100% found this document useful (2 votes)
334 views63 pages

Pic 16 F

The document contains 6 lab experiments on using a PIC microcontroller for tasks like flashing an LED, reading a button input, implementing a binary counter, interfacing with an LCD display, analog to digital conversion, and driving a 7 segment display. The labs cover basic digital and analog I/O, timers, interrupts and pulse width modulation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
334 views63 pages

Pic 16 F

The document contains 6 lab experiments on using a PIC microcontroller for tasks like flashing an LED, reading a button input, implementing a binary counter, interfacing with an LCD display, analog to digital conversion, and driving a 7 segment display. The labs cover basic digital and analog I/O, timers, interrupts and pulse width modulation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 63

Lab 1: Flashing an LED

/*
Lab 1: Flashing LED with PIC16F688
Internal Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt
Oct 7, 2010
*/
// Define LED @ RC0
sbit LED at RC0_bit;
void main() {
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 007 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001000; // PORTA All Outputs, Except RA3

do {
LED = 1;
Delay_ms(1000);
LED = 0;
Delay_ms(1000);
} while(1); // Infinite Loop
}

Lab 2: Basic digital input and output


/*

Lab 2: Toggle LED with a Tact Switch Input


Internal Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt
Oct 8, 2010
*/
// Define LED @ RC0 and Tact switch @ RC1
sbit LED at RC0_bit;
sbit Switch at RC1_bit;
#define Switch_Pin 1
#define Switch_Port PORTC
#define Debounce_Time 20
void main() {
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 0x07 ; // Disbale comparators
TRISC = 0b00000010; // PORTC All Outputs
TRISA = 0b00001000; // PORTA All Outputs, Except RA3
LED = 0;
do {
if (Button(&Switch_Port, Switch_Pin, Debounce_Time, 0)) {
if (!Switch) {
LED = ~LED;
}
while (!Switch); // Wait for release of the button
}
} while(1); // Infinite Loop
}

Lab 3: Four bit binary counter


/* Lab 3: 4-bit up counter Internal Clock @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt Nov 6, 2010 */
// Define Tact switch @ RC4
sbit Switch at RC4_bit;

// Define button Switch parameters


#define Switch_Pin 4
#define Switch_Port PORTC
#define Debounce_Time 20 // Switch Debounce time 20ms
unsigned short count;
void main()
{
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 0x07 ; // Disbale comparators
TRISC = 0b00010000; // PORTC all output except RC4
TRISA = 0b00001000; // PORTA All Outputs, Except RA3
count = 0;
PORTC = count;
do
{
if (Button(&Switch_Port, Switch_Pin, Debounce_Time, 0))
{
if (!Switch)
{ count ++; if (count ==16) count =0; PORTC = count;
}
while (!Switch); // Wait till the button is released
}
}
while(1); // Infinite Loop
}

Lab 4: Interfacing a character LCD


/* Lab 4: Blink Character Message on LCD Internal Clock @ 4MHz, MCLR Enabled, PWRT
Enabled, WDT OFF Copyright @ Rajendra Bhatt October 9, 2010 */
// Define LCD module connections.
sbit LCD_RS at RC4_bit;
bit LCD_EN at RC5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
// End LCD module connection definition
// Define Messages
char message1[] = "Welcome to";
char message2[] = "Embedded-Lab.com";
void main()
{
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 0x07 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00000000; // PORTA All Outputs, Except RA3
Lcd_Init();

// Initialize LCD

Do
{
Lcd_Cmd(_LCD_CLEAR);

// CLEAR display

Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,4,message1);

// Cursor off

// Write message1 in 1st row

Lcd_Out(2,1,message2);

// Write message2 in 2nd row

Delay_ms(1000);

// Wait for 1 sec

Lcd_Cmd(_LCD_CLEAR);

// Clear display

Delay_ms(1000); // Wait for 1 sec


}
while(1);
}

// Infinite Loop

Lab 5: Analog-to-digital conversion (ADC)


/* Lab 5: Analog-to-digital converter Internal Oscillator @ 4MHz, MCLR Enabled, PWRT
Enabled, WDT OFF Copyright @ Rajendra Bhatt October 10, 2010 */
// Define LCD module connections.
sbit LCD_RS at RC4_bit;
bit LCD_EN at RC5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
// End LCD module connection definition
// Define Messages
char message1[] = "ADC Value= ";
char *temp = "0000";
unsigned int ADC_Value;
void main() {
ANSEL = 0b00000100; // RA2/AN2 is analog input
ADCON0 = 0b00001000; // Analog channel select @ AN2
CMCON0 = 0x07 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001100; // PORTA All Outputs, Except RA3 and RA2
Lcd_Init();

// Initialize LCD

Lcd_Cmd(_LCD_CLEAR);

// CLEAR display

Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,message1);

// Cursor off

// Write message1 in 1st row

do {
adc_value = ADC_Read(2);
temp[0] = adc_value/1000 + 48; // Add 48 to get the ASCII character value
temp[1] = (adc_value/100)%10 + 48;
temp[2] = (adc_value/10)%10 + 48;
temp[3] = adc_value%10 + 48;
Lcd_Out(1,11,temp);
Delay_ms(2000);
} while(1);
}

Lab 6: Seven segment display


/*
Lab 6: Seven segment display
Copyright @ Rajendra Bhatt
November 13, 2010
*/
// Define seven segment connections
sbit seg_a at RC0_bit;
sbit seg_b at RC1_bit;
sbit seg_c at RC2_bit;
sbit seg_d at RC3_bit;
sbit seg_e at RC4_bit;
sbit seg_f at RC5_bit;
sbit seg_g at RA0_bit;
unsigned short count=0;
void main() {
ANSEL = 0b00000000; //All I/O pins are configured as digital
CMCON0 = 0x07 ; // Disbale comparators
TRISC = 0b00000000; // PORTC All Outputs
TRISA = 0b00001000; // PORTA All Outputs, Except RA3
do {
switch (count) {
case 0 : seg_a=1; seg_b=1; seg_c=1;
seg_d=1; seg_e=1; seg_f=1; seg_g=0;
break;
case 1 : seg_a=0; seg_b=1; seg_c=1; seg_d=0;
seg_e=0; seg_f=0; seg_g=0;
break;
case 2 : seg_a=1; seg_b=1; seg_c=0; seg_d=1;
seg_e=1; seg_f=0; seg_g=1;
break;

case 3 : seg_a=1; seg_b=1; seg_c=1; seg_d=1;


seg_e=0; seg_f=0; seg_g=1;
break;
case 4 : seg_a=0; seg_b=1; seg_c=1; seg_d=0;
seg_e=0; seg_f=1; seg_g=1;
break;
case 5 : seg_a=1; seg_b=0; seg_c=1; seg_d=1;
seg_e=0; seg_f=1; seg_g=1;
break;
case 6 : seg_a=1; seg_b=0; seg_c=1; seg_d=1;
seg_e=1; seg_f=1; seg_g=1;
break;
case 7 : seg_a=1; seg_b=1; seg_c=1; seg_d=0;
seg_e=0; seg_f=0; seg_g=0;
break;
case 8 : seg_a=1; seg_b=1; seg_c=1; seg_d=1;
seg_e=1; seg_f=1; seg_g=1;
break;
case 9 : seg_a=1; seg_b=1; seg_c=1; seg_d=0;
seg_e=0; seg_f=1; seg_g=1;
break;
case 10 : seg_a=1; seg_b=1; seg_c=1; seg_d=0;
seg_e=1; seg_f=1; seg_g=1;
break;
case 11 : seg_a=0; seg_b=0; seg_c=1; seg_d=1;
seg_e=1; seg_f=1; seg_g=1;
break;
case 12 : seg_a=1; seg_b=0; seg_c=0; seg_d=1;
seg_e=1; seg_f=1; seg_g=0;
break;
case 13 : seg_a=0; seg_b=1; seg_c=1; seg_d=1;

seg_e=1; seg_f=0; seg_g=1;


break;
case 14 : seg_a=1; seg_b=0; seg_c=0; seg_d=1;
seg_e=1; seg_f=1; seg_g=1;
break;
case 15 : seg_a=1; seg_b=0; seg_c=0; seg_d=0;
seg_e=1; seg_f=1; seg_g=1;
break;
} //case end
count ++;
if(count ==16) count =0;
Delay_ms(1000); // Wait for 1 sec before updating the display
} while(1); // Infinite Loop
}

Lab 7: PIC Timers and Counters (Part 1)


/*
Lab 7: Timer0 as a counter
Internal Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt
November 18, 2010
*/
// LCD module connections
sbit LCD_RS at RC4_bit;
sbit LCD_EN at RC5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
// End LCD module connections
// Define Messages
char message1[] = "Frequency= Hz";
char *freq = "00";
void Display_Freq(unsigned int freq2write) {
freq[0] = (freq2write/10)%10 + 48; // Extract tens digit
freq[1] = freq2write%10

+ 48; // Extract ones digit

// Display Frequency on LCD


Lcd_Out(1, 11, freq);
}
void main() {

CMCON0 = 0x07; // Disable Comparators


ANSEL = 0x00;
TRISC = 0x00;

// Disable analog channels


// PORTC O/P

TRISA = 0b00001100; // RA2/T0CKI input, RA3 is I/P only


OPTION_REG = 0b00101000; // Prescaler (1:1), TOCS =1 for counter mode
Lcd_Init();

// Initialize LCD

Lcd_Cmd(_LCD_CLEAR);

// CLEAR display

Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off


Lcd_Out(1,1,message1);

// Write message1 in 1st row

do {
TMR0=0;
Delay_ms(1000); // Delay 1 Sec
Display_Freq(TMR0);
} while(1); // Infinite loop
}

Lab 8: Asynchronous serial communication


/* Lab 8: Hardware UART MCU: PIC16F628A External 4MHz Crystal, MCLR Enabled, PWRT
Enabled, WDT OFF Copyright @ Rajendra Bhatt Dec 12, 2010 */
void newline()
{
UART1_Write(13); // Carriage Return
UART1_Write(10); // Line Feed
}
void main()
{
unsigned char MyError, Temp;
CMCON = 7; // Disable Comparators
TRISB = 0b00000010;
UART1_Init(9600);
Delay_ms(100);
UART1_Write_Text("Testing UART! ");
newline();
do
{
UART1_Write_Text("Type in a Number: ");
while(!UART1_Data_Ready());
Temp = UART1_Read();
newline();
UART1_Write_Text("You entered: ");
UART1_Write(Temp); newline();
}
while(1);
} // End main()

Lab 9: Pulse Width Modulation (PWM) using PIC CCP module


/*
Lab 9: Pulse Width Modulation
Copyright @ Rajendra Bhatt, 2010.
Description: CCP module generating PWM
MCU: PIC16F628A
Oscillator: XT, 4.0 MHz, MCLR Enabled
*/
sbit UP at RB0_bit;
sbit DOWN at RB1_bit;
unsigned short new_DC, current_DC;

void debounce(){
Delay_ms(300);
}

void main() {
CMCON = 0x07; // Disable comparators
PORTB = 0x00;
TRISB = 0b00000011; // RB0, RB1 input, RB3 (PWM1) output
PWM1_Init(5000);
new_DC = 0;

// PWM module initialization (5KHz)

// Initial value of variable Duty Cycle

current_DC = 0;
PWM1_Start();

// Start PWM1 module with Zero DC

PWM1_Set_Duty(current_DC);
do {
if (!UP){

// If the button connected to RB0 is pressed

debounce();
if (new_DC < 250)

// Don't go above 250

new_DC = new_DC + 25 ; // increment Duty Cycle by 25


}

if (!DOWN) { // If the button connected to RB1 is pressed


debounce();
if (new_DC !=0)

// Don't go below 0

new_DC= new_DC - 25 ; // Decrement Duty Cycle by 25


}

if (current_DC != new_DC) {
current_DC = new_DC ;
PWM1_Set_Duty(current_DC); // Change the current DC to new value
}
} while(1);
} // END main()

Lab 10: DC motor interfacing to PICMicro


/* Lab 10: DC Motor control (H-Bridge) Copyright @ Rajendra Bhatt, 2010. Description:
Forward and reverse motor control MCU: PIC16F688 Oscillator: Internal clock at 4.0 MHz,
MCLR Enabled */
sbit Forward at RA5_bit;
sbit Reverse at RA4_bit;
sbit Brake at RA2_bit;
sbit PinA at RC5_bit;
sbit PinB at RC4_bit;
sbit PinC at RC3_bit;
sbit PinD at RC2_bit;
void GetDelay()
{
Delay_ms(300);
}
void main()
{
CMCON0 = 0x07; // Disable comparators
ANSEL = 0b00000000;
PORTC = 0x00;
TRISC = 0b00000000;
// PORTB all output
TRISA = 0b00111100; // RA5, RA4, RA2 inputs
do
{
if (!Forward)
{
GetDelay();
PORTC = 0;
GetDelay();
PinA = 0;
PinB = 1;

PinD = 1;
}
if (!Reverse)
{
GetDelay();
PORTC = 0;
GetDelay();
PinA = 1;
PinB = 0;
PinC = 1;
}
if (!Brake)
{
GetDelay();
PORTC = 0;
}
}
while(1);
} // END main()

Lab 11: Multiplexing seven segment LED displays


/*
* Project name:
Decimal UP Counter with Four 7-Segment Display Multiplexing
* Copyright:
(c) Rajendra Bhatt, 2011.
* Description:
This code is an example of multiplexed Seven Segment Displays.
MCU: PIC16F628A, 4.0 MHz external clock, MCLR Enabled
The common anodes of four seven segment dispalys are
connected to RA0, RA1, RA2 and RA3, whereas the seven
segments are driven through PORTB pins
*/

unsigned short i, DD0, DD1, DD2, DD3;


unsigned int Count;
//------ Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0xC0;
case 1 : return 0xF9;
case 2 : return 0xA4;
case 3 : return 0xB0;
case 4 : return 0x99;
case 5 : return 0x92;
case 6 : return 0x82;
case 7 : return 0xF8;
case 8 : return 0x80;
case 9 : return 0x90;
} //case end
}

void main() {
CMCON |= 7;

// Disable Comparators

TRISB = 0x00; // Set PORTB direction to be output


PORTB = 0xff;

// Turn OFF LEDs on PORTB

TRISA = 0b00100000; // RA5 is input only


Count = 0; // Initial Value of Counter

do {
DD0 = Count%10; // Extract Ones Digit
DD0 = mask(DD0);
DD1 = (Count/10)%10; // Extract Tens Digit
DD1 = mask(DD1);
DD2 = (Count/100)%10; // Extract Hundreds Digit
DD2 = mask(DD2);
DD3 = (Count/1000); // Extract Thousands Digit
DD3 = mask(DD3);

for (i = 0; i<=50; i++) {


PORTB = DD0;
RA0_bit = 0;

// Select Ones Digit

RA1_bit = 1;
RA2_bit = 1;
RA3_bit = 1;
delay_ms(5);
PORTB = DD1;
RA0_bit = 1;
RA1_bit = 0;
RA2_bit = 1;
RA3_bit = 1;
delay_ms(5);
PORTB = DD2;

// Select Tens Digit

RA0_bit = 1;
RA1_bit = 1;
RA2_bit = 0;

// Select Hundreds Digit

RA3_bit = 1;
delay_ms(5);
PORTB = DD3;
RA0_bit = 1;
RA1_bit = 1;
RA2_bit = 1;
RA3_bit = 0;

// Select Thousands Digit

delay_ms(5);
}
Count = Count + 1 ;
if (Count > 9999) Count = 0;
} while(1);
}

// endless loop

Lab 12: Basics of LED dot matrix display


/*

Project: Interfacing an LED matrix


Description : A 7x5 LED matrix with StartUSB for PIC board
MCU: PIC18F2550, External crystal = 8.0 MHz, Actual Clock from PLL = 48.0 MHz
7 rows are driven by PORTB, and 5 colums by PORTA pins
English Alphabets from A through Z are displayed sequentially.
Copyright @ Rajendra Bhatt
April 22, 2011

*/

// Define row values for each of the five columns corresponding


// to Alphabets A through Z

unsigned short Alphabets[130]={ 0x7e, 0x09, 0x09, 0x09, 0x7E, // A


0x7f, 0x49, 0x49, 0x49, 0x36, // B
0x3e, 0x41, 0x41, 0x41, 0x22,
0x7f, 0x41, 0x41,0x22, 0x1c,
0x7f, 0x49, 0x49, 0x49, 0x63,
0x7f, 0x09, 0x09, 0x09, 0x01,
0x3e, 0x41, 0x41, 0x49, 0x7a,
0x7f, 0x08, 0x08, 0x08, 0x7f,
0x00, 0x41, 0x7f, 0x41, 0x00, // I
0x20, 0x40, 0x41, 0x3f, 0x01,
0x7f, 0x08, 0x14, 0x22, 0x41,
0x7f, 0x40, 0x40, 0x40, 0x60,
0x7f, 0x02, 0x04, 0x02, 0x7f,
0x7f, 0x04, 0x08, 0x10, 0x7f,
0x3e, 0x41, 0x41, 0x41, 0x3e,

0x7f, 0x09, 0x09, 0x09, 0x06,


0x3e, 0x41, 0x51, 0x21, 0x5e,
0x7f, 0x09, 0x19, 0x29, 0x46,
0x46, 0x49, 0x49, 0x49, 0x31, // S
0x01, 0x01, 0x7f, 0x01, 0x01,
0x3f, 0x40, 0x40, 0x40, 0x3f,
0x1f, 0x20, 0x40, 0x20, 0x1f,
0x3f, 0x40, 0x30, 0x40, 0x3f,
0x63, 0x14, 0x08, 0x14, 0x63,
0x07, 0x08, 0x70, 0x08, 0x07,
0x61, 0x51, 0x49, 0x45, 0x43 // Z
};

const unsigned short characters[30]={


0x24, 0x2A, 0x7f, 0x2A, 0x12, // $
0x08, 0x14, 0x22, 0x41, 0x00, // <
0x41, 0x22, 0x14, 0x08, 0x00, // >
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x44, 0x3c, 0x04, 0x7c, 0x44, // PI

};

unsigned short count, column, num, repeat;


void main() {
TRISB = 0b00000000; // Set PORTB direction to be output
TRISA = 0x00; // Set PORTA direction to be output
PORTB = 0x00; // Turn OFF LEDs on PORTB
CMCON = 7 ; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
do{

// Display 26 alphabets
for (num=0; num<26; num++) {

for (repeat=0; repeat<100; repeat++){


column = 1;
for(count = num*5;count < (num*5+6);count++){
PORTB = Alphabets[count];
PORTA = column;
Delay_ms(1);
column = column<<1;
}
}
}

// Display special characters


for (num=0; num<6; num++) {

for (repeat=0; repeat<100; repeat++){


column = 1;
for(count = num*5;count < (num*5+6);count++){
PORTB = characters[count];
PORTA = column;
Delay_ms(1);
column = column<<1;
}
}
}

} while(1);

Lab 13: Read and Write to internal EEPROM


/* Project name:
Use of internal EEPROM for storing information
* Copyright:
(c) Rajendra Bhatt, 2011.
* Description:
This code demonstrates how to perform basic Read and Write operations
with the internal EEPROM of PIC16F628A.
MCU:

PIC16F628A

Oscillator:

XT, 4.0 MHz

*/
// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD connections definitions

// Other connections
sbit SW1 at RB0_bit;
sbit SW2 at RB1_bit;
sbit SW3 at RB2_bit;

// String array to store 3 digit access code


char message1[] = "1.READ";
char message2[] = "2.WRITE";
char message3[] = "3.Delete";
char message4[] = "WRITE COMPLETED";
char message5[] = "Read Data";
char message6[] = "Data Deleted";
char message7[] = "Embedded-Lab.com";
char Edata[] = "0000000000000000";
unsigned short i, NUM ;
unsigned int ADD; // Start EEPROM Location
char temp;
void Delay2s(){
Delay_ms(2000);
}

void Debounce(){
Delay_ms(100);
}

void main() {
PORTB = 0;
PORTA = 0;
TRISB = 0b00001111;
TRISA = 0b00100000;
CMCON=0x07;
Lcd_Init();

// Initialize LCD

Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1, 1, "Lab 13: Testing");
Lcd_Out(2, 1, "internal EEPROM");

// Clear LCD
// Turn cursor off

Delay2s();
start:
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,message1);

// Write message1 in 1st row

Lcd_Out(1,8,message2);
Lcd_Out(2,1,message3);
do{

// Read Operation
if (!SW1) {
Debounce();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,message5);
ADD = 0;
for (i=0; i<16; i++) {
temp = EEPROM_Read(ADD+i);
Edata[i] = temp;
}
Lcd_Out(2,1,Edata);
Delay2s();
goto start;
}
// Write Operation
if (!SW2) {
Debounce();
ADD = 0;
for (i=0; i<16; i++) {
temp = message7[i];
EEPROM_Write(ADD+i,temp);
}
Lcd_Cmd(_LCD_CLEAR);

Lcd_Out(1,1,message4);
Delay2s();
goto start;
}

// Delete Operation
if (!SW3) {
Debounce();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,message6);
for (i=0; i<16; i++) {
temp = '0';
EEPROM_Write(ADD+i, temp);
}
Delay2s() ;
goto start;
}

} while(1);

Lab 14: Inter-Integrated Circuit (I2C) communication


/*
Project: Multiple I2C devices on a common bus
MCU: PIC18F2550 @ 48.0 MHz (StartUSB for PIC board)
Copyright @ Rajendra Bhatt
May 6, 2011
*/

// Define LCD module connections.


sbit LCD_RS at RC6_bit;
sbit LCD_EN at RC7_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISC6_bit;
sbit LCD_EN_Direction at TRISC7_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connection definition

void Delay2s(){
Delay_ms(2000);
}

void check_device(unsigned short dev_address){


I2C1_Start();
if (I2C1_Wr(dev_address)){

Lcd_Out(2,1,"Device not found");


}
else Lcd_Out(2,1,"Device is OK");
I2C1_Stop();
}

//--------------- Writes data to 24LC512 EEPROM - single location


void EEPROM_WriteByte(unsigned DeviceSelect, unsigned short wAddress, unsigned short
wData) {
unsigned short wAddrH, wAddrL;
wAddrH = 0;
wAddrL = wAddress;
I2C1_Start();

// issue I2C1 start signal

I2C1_Wr(DeviceSelect); // send control byte


I2C1_Wr(wAddrH);

// send higher address byte

I2C1_Wr(wAddrL);

// send lower address byte

I2C1_Wr(wData);

// send data (data to be written)

I2C1_Stop();
}
//--------------- Reads data from 24LC512 EEPROM - single location
unsigned short EEPROM_ReadByte(unsigned short EEPROM_Select, unsigned short rAddress)
{
unsigned short rAddrH, rAddrL, result;
rAddrH = 0;
rAddrL = rAddress;
I2C1_Start();

// issue I2C1 start signal

I2C1_Wr(EEPROM_Select); // send byte via I2C1 (device address + W)


I2C1_Wr(rAddrH);

// send Higher address byte

I2C1_Wr(rAddrL);

// send Lower address byte

I2C1_Repeated_Start();

// issue I2C1 signal repeated start

I2C1_Wr(EEPROM_Select+1);
result = I2C1_Rd(0u);

// send byte (device address + R)

// Read the data (NO acknowledge)

while (!I2C1_Is_Idle())
asm nop;

// Wait for the read cycle to finish

I2C1_Stop();
return result;
}

char message1[] = "I2C Devices ";


char message2[] = "with PIC18F2550" ;
char Sample[] = "Sample 0";
char temp[] = "00.0000 C";

unsigned int address, Fraction_Temp;


unsigned short i,MS_Byte, LS_Byte, Whole_Temp;
const int EEPROM1 = 0xA0, EEPROM2 = 0xA2, DS1631 = 0x90;
void main() {
CMCON = 0x07; // Disable comparators
ADCON1 = 0x0F; // Disable Analog functions
TRISC = 0x00;
TRISB = 0x00;
Lcd_Init();

// Initialize LCD

Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);

// CLEAR display
// Cursor off

Lcd_Out(1,1,message1); // Write message1 in 1st row


Lcd_Out(2,1,message2); // Write message1 in 1st row
Delay2s();

I2C1_Init(100000); // Initiate I2C

// Check EEPROM1
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"EEPROM1");

check_device(EEPROM1);
Delay2s();

// Check EEPROM2
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"EEPROM2");
check_device(EEPROM2);
Delay2s();

// Check Sensor
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"DS1631");
check_device(DS1631);
Delay2s();
for (i=0; i<5; i++) {
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Reading Temp.");
// Read temperature
I2C1_Start();
I2C1_Wr(DS1631);
I2C1_Wr(0x51);

// Send device address


// Start Convert Temp command

I2C1_Stop();
Delay_ms(750);
I2C1_Start();
I2C1_Wr(DS1631);
I2C1_Wr(0xAA);

// DS1631 Address again


// Read Temperature command

I2C1_Repeated_Start();
I2C1_Wr(DS1631+1);

// Address with Read

MS_Byte = I2C1_Rd(1);

// Read MSB and send ACK

LS_Byte = I2C1_Rd(0);

// Read LSB and send NAK

I2C1_Stop();
Delay2s();
// Write the MS Byte to EEPROM1

Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Writing MS Byte");
EEPROM_WriteByte(EEPROM1, i, MS_Byte);
Delay2s();
// Write the LS Byte to EEPROM2
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Writing LS Byte");
EEPROM_WriteByte(EEPROM2, i, MS_Byte);
Delay2s();
}
// Reading stored temperature samples
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Reading EEPROMs");
Delay2s();

for (i=0; i<5; i++){


Lcd_Cmd(_LCD_CLEAR);
Sample[7] = i+49;
Lcd_Out(1,1,Sample);
Whole_Temp = EEPROM_ReadByte(EEPROM1, i);
Fraction_Temp = EEPROM_ReadByte(EEPROM2, i);
Fraction_Temp = Fraction_Temp >>4;
Fraction_Temp = 625*Fraction_Temp; // 12 bit resolution is 0.0625C
temp[0] = Whole_Temp/10+48;
temp[1] = Whole_Temp%10+48;
temp[3] = Fraction_Temp/1000+48;
temp[4] = (Fraction_Temp/100)%10+48;

temp[5] = (Fraction_Temp/10)%10+48;
temp[6] = Fraction_Temp%10+48;
Lcd_Out(2,5,temp);
Delay2s();
}

Lab 15: Scrolling text message on an LED dot-matrix display


/*
Project: Scrolling message on LED dot matrix display
MCU: PIC18F2550 @ 48.0 MHz (StartUSB for PIC board)
Copyright @ Rajendra Bhatt
May 16, 2011
*/

// Define LCD module connections.


/* sbit Serial_Data at LATC2_bit;
sbit SH_Clk at LATC6_bit;
sbit ST_Clk at LATC7_bit;
sbit CD4017_Clk at LATA2_bit;
sbit CD4017_RST at LATA1_bit;
*/
sbit Serial_Data at RC2_bit;
sbit SH_Clk at RC6_bit;
sbit ST_Clk at RC7_bit;
sbit CD4017_Clk at RA2_bit;
sbit CD4017_RST at RA1_bit;

void send_data(unsigned int temp){


unsigned int Mask = 0x0001, t, Flag;
for (t=0; t<16; t++){
Flag = temp & Mask;
if(Flag==0) Serial_Data = 0;
else Serial_Data = 1;
SH_Clk = 1;
SH_Clk = 0;
Mask = Mask << 1;
}

// Apply clock on ST_Clk


ST_Clk = 1;
ST_Clk = 0;

/* CharData is a two dimensional constant array that holds the 8-bit column values of
individual rows for ASCII characters that are to be displayed on a 8x8 matrix format.
*/
const unsigned short CharData[][8] ={
{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000},
{0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000000,
0b00000100},
{0b00001010, 0b00001010, 0b00001010, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000},
{0b00000000, 0b00001010, 0b00011111, 0b00001010, 0b00011111, 0b00001010, 0b00011111,
0b00001010},
{0b00000111, 0b00001100, 0b00010100, 0b00001100, 0b00000110, 0b00000101, 0b00000110,
0b00011100},
{0b00011001, 0b00011010, 0b00000010, 0b00000100, 0b00000100, 0b00001000, 0b00001011,
0b00010011},
{0b00000110, 0b00001010, 0b00010010, 0b00010100, 0b00001001, 0b00010110, 0b00010110,
0b00001001},
{0b00000100, 0b00000100, 0b00000100, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000},
{0b00000010, 0b00000100, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00000100,
0b00000010},
{0b00001000, 0b00000100, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000100,
0b00001000},
{0b00010101, 0b00001110, 0b00011111, 0b00001110, 0b00010101, 0b00000000, 0b00000000,
0b00000000},
{0b00000000, 0b00000000, 0b00000100, 0b00000100, 0b00011111, 0b00000100, 0b00000100,
0b00000000},
{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000110, 0b00000100,
0b00001000},

{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001110, 0b00000000, 0b00000000,


0b00000000},
{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000100},
{0b00000001, 0b00000010, 0b00000010, 0b00000100, 0b00000100, 0b00001000, 0b00001000,
0b00010000},
{0b00001110, 0b00010001, 0b00010011, 0b00010001, 0b00010101, 0b00010001, 0b00011001,
0b00001110},
{0b00000100, 0b00001100, 0b00010100, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b00011111},
{0b00001110, 0b00010001, 0b00010001, 0b00000010, 0b00000100, 0b00001000, 0b00010000,
0b00011111},
{0b00001110, 0b00010001, 0b00000001, 0b00001110, 0b00000001, 0b00000001, 0b00010001,
0b00001110},
{0b00010000, 0b00010000, 0b00010100, 0b00010100, 0b00011111, 0b00000100, 0b00000100,
0b00000100},
{0b00011111, 0b00010000, 0b00010000, 0b00011110, 0b00000001, 0b00000001, 0b00000001,
0b00011110},
{0b00000111, 0b00001000, 0b00010000, 0b00011110, 0b00010001, 0b00010001, 0b00010001,
0b00001110},
{0b00011111, 0b00000001, 0b00000001, 0b00000001, 0b00000010, 0b00000100, 0b00001000,
0b00010000},
{0b00001110, 0b00010001, 0b00010001, 0b00001110, 0b00010001, 0b00010001, 0b00010001,
0b00001110},
{0b00001110, 0b00010001, 0b00010001, 0b00001111, 0b00000001, 0b00000001, 0b00000001,
0b00000001},
{0b00000000, 0b00000100, 0b00000100, 0b00000000, 0b00000000, 0b00000100, 0b00000100,
0b00000000},
{0b00000000, 0b00000100, 0b00000100, 0b00000000, 0b00000000, 0b00000100, 0b00000100,
0b00001000},
{0b00000001, 0b00000010, 0b00000100, 0b00001000, 0b00001000, 0b00000100, 0b00000010,
0b00000001},
{0b00000000, 0b00000000, 0b00000000, 0b00011110, 0b00000000, 0b00011110, 0b00000000,
0b00000000},
{0b00010000, 0b00001000, 0b00000100, 0b00000010, 0b00000010, 0b00000100, 0b00001000,
0b00010000},
{0b00001110, 0b00010001, 0b00010001, 0b00000010, 0b00000100, 0b00000100, 0b00000000,
0b00000100},

{0b00001110, 0b00010001, 0b00010001, 0b00010101, 0b00010101, 0b00010001, 0b00010001,


0b00011110},
{0b00001110, 0b00010001, 0b00010001, 0b00010001, 0b00011111, 0b00010001, 0b00010001,
0b00010001},
{0b00011110, 0b00010001, 0b00010001, 0b00011110, 0b00010001, 0b00010001, 0b00010001,
0b00011110},
{0b00000111, 0b00001000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00001000,
0b00000111},
{0b00011100, 0b00010010, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010010,
0b00011100},
{0b00011111, 0b00010000, 0b00010000, 0b00011110, 0b00010000, 0b00010000, 0b00010000,
0b00011111},
{0b00011111, 0b00010000, 0b00010000, 0b00011110, 0b00010000, 0b00010000, 0b00010000,
0b00010000},
{0b00001110, 0b00010001, 0b00010000, 0b00010000, 0b00010111, 0b00010001, 0b00010001,
0b00001110},
{0b00010001, 0b00010001, 0b00010001, 0b00011111, 0b00010001, 0b00010001, 0b00010001,
0b00010001},
{0b00011111, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b00011111},
{0b00011111, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00010100,
0b00001000},
{0b00010001, 0b00010010, 0b00010100, 0b00011000, 0b00010100, 0b00010010, 0b00010001,
0b00010001},
{0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000,
0b00011111},
{0b00010001, 0b00011011, 0b00011111, 0b00010101, 0b00010001, 0b00010001, 0b00010001,
0b00010001},
{0b00010001, 0b00011001, 0b00011001, 0b00010101, 0b00010101, 0b00010011, 0b00010011,
0b00010001},
{0b00001110, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001,
0b00001110},
{0b00011110, 0b00010001, 0b00010001, 0b00011110, 0b00010000, 0b00010000, 0b00010000,
0b00010000},
{0b00001110, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010101, 0b00010011,
0b00001111},
{0b00011110, 0b00010001, 0b00010001, 0b00011110, 0b00010100, 0b00010010, 0b00010001,
0b00010001},

{0b00001110, 0b00010001, 0b00010000, 0b00001000, 0b00000110, 0b00000001, 0b00010001,


0b00001110},
{0b00011111, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b00000100},
{0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001,
0b00001110},
{0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00001010,
0b00000100},
{0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010001, 0b00010101, 0b00010101,
0b00001010},
{0b00010001, 0b00010001, 0b00001010, 0b00000100, 0b00000100, 0b00001010, 0b00010001,
0b00010001},
{0b00010001, 0b00010001, 0b00001010, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b00000100},
{0b00011111, 0b00000001, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00010000,
0b00011111},
{0b00001110, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00001000,
0b00001110},
{0b00010000, 0b00001000, 0b00001000, 0b00000100, 0b00000100, 0b00000010, 0b00000010,
0b00000001},
{0b00001110, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000010,
0b00001110},
{0b00000100, 0b00001010, 0b00010001, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000},
{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00011111},
{0b00001000, 0b00000100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000},
{0b00000000, 0b00000000, 0b00000000, 0b00001110, 0b00010010, 0b00010010, 0b00010010,
0b00001111},
{0b00000000, 0b00010000, 0b00010000, 0b00010000, 0b00011100, 0b00010010, 0b00010010,
0b00011100},
{0b00000000, 0b00000000, 0b00000000, 0b00001110, 0b00010000, 0b00010000, 0b00010000,
0b00001110},
{0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00000111, 0b00001001, 0b00001001,
0b00000111},
{0b00000000, 0b00000000, 0b00000000, 0b00011100, 0b00010010, 0b00011110, 0b00010000,
0b00001110},

{0b00000000, 0b00000011, 0b00000100, 0b00000100, 0b00000110, 0b00000100, 0b00000100,


0b00000100},
{0b00000000, 0b00001110, 0b00001010, 0b00001010, 0b00001110, 0b00000010, 0b00000010,
0b00001100},
{0b00000000, 0b00010000, 0b00010000, 0b00010000, 0b00011100, 0b00010010, 0b00010010,
0b00010010},
{0b00000000, 0b00000000, 0b00000100, 0b00000000, 0b00000100, 0b00000100, 0b00000100,
0b00000100},
{0b00000000, 0b00000010, 0b00000000, 0b00000010, 0b00000010, 0b00000010, 0b00000010,
0b00001100},
{0b00000000, 0b00010000, 0b00010000, 0b00010100, 0b00011000, 0b00011000, 0b00010100,
0b00010000},
{0b00000000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000,
0b00001100},
{0b00000000, 0b00000000, 0b00000000, 0b00001010, 0b00010101, 0b00010001, 0b00010001,
0b00010001},
{0b00000000, 0b00000000, 0b00000000, 0b00010100, 0b00011010, 0b00010010, 0b00010010,
0b00010010},
{0b00000000, 0b00000000, 0b00000000, 0b00001100, 0b00010010, 0b00010010, 0b00010010,
0b00001100},
{0b00000000, 0b00011100, 0b00010010, 0b00010010, 0b00011100, 0b00010000, 0b00010000,
0b00010000},
{0b00000000, 0b00001110, 0b00010010, 0b00010010, 0b00001110, 0b00000010, 0b00000010,
0b00000001},
{0b00000000, 0b00000000, 0b00000000, 0b00001010, 0b00001100, 0b00001000, 0b00001000,
0b00001000},
{0b00000000, 0b00000000, 0b00001110, 0b00010000, 0b00001000, 0b00000100, 0b00000010,
0b00011110},
{0b00000000, 0b00010000, 0b00010000, 0b00011100, 0b00010000, 0b00010000, 0b00010000,
0b00001100},
{0b00000000, 0b00000000, 0b00000000, 0b00010010, 0b00010010, 0b00010010, 0b00010010,
0b00001100},
{0b00000000, 0b00000000, 0b00000000, 0b00010001, 0b00010001, 0b00010001, 0b00001010,
0b00000100},
{0b00000000, 0b00000000, 0b00000000, 0b00010001, 0b00010001, 0b00010001, 0b00010101,
0b00001010},
{0b00000000, 0b00000000, 0b00000000, 0b00010001, 0b00001010, 0b00000100, 0b00001010,
0b00010001},

{0b00000000, 0b00000000, 0b00010001, 0b00001010, 0b00000100, 0b00001000, 0b00001000,


0b00010000},
{0b00000000, 0b00000000, 0b00000000, 0b00011111, 0b00000010, 0b00000100, 0b00001000,
0b00011111},
{0b00000010, 0b00000100, 0b00000100, 0b00000100, 0b00001000, 0b00000100, 0b00000100,
0b00000010},
{0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b00000100},
{0b00001000, 0b00000100, 0b00000100, 0b00000100, 0b00000010, 0b00000100, 0b00000100,
0b00001000},
{0b00000000, 0b00000000, 0b00000000, 0b00001010, 0b00011110, 0b00010100, 0b00000000,
0b00000000}
};

unsigned int DisplayBuffer[]={0,0,0,0,0,0,0,0};


unsigned int speed;
short i, l, k, ShiftAmount, scroll, temp, shift_step=1, StringLength;
char message[]="SCROLLING MESSAGE ON LED DOT-MATRIX DISPLAY FROM
WWW.EMBEDDED-LAB.COM ";
char index;
void main() {
CMCON = 0x07; // Disable comparators
ADCON0 = 0x00; // Select ADC channel AN0
ADCON1 = 0b00001110; // RA0 as analog input
TRISC = 0x00;
TRISB = 0xFF;
TRISA = 0x01;
StringLength = strlen(message) ;
do {
for (k=0; k<StringLength; k++){
for (scroll=0; scroll<(8/shift_step); scroll++) {
for (ShiftAmount=0; ShiftAmount<8; ShiftAmount++){
index = message[k];
temp = CharData[index-32][ShiftAmount];

DisplayBuffer[ShiftAmount] = (DisplayBuffer[ShiftAmount] << shift_step)| (temp >> ((8shift_step)-scroll*shift_step));


}

speed = 10+ADC_Read(0)/10;
for(l=0; l<speed;l++){

for (i=0; i<8; i++) {

send_data(DisplayBuffer[i]);
CD4017_Clk = 1;
CD4017_Clk = 0;
Delay_ms(1);
} // i
CD4017_Rst = 1;
CD4017_Rst = 0;
} // l
} // scroll
} // k

} while(1);

Lab 16: Understanding Interrupts


/*
Lab 16: Understanding Interrupts
MCU: PIC16F688
Internal Clock @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt
Jul 19, 2011
*/

sbit LED at RA0_bit; // Interrupt LED


unsigned short count;

// Interrupt service routine


void interrupt(){
if(INTCON.INTF == 1) LED = ~LED;
delay_ms(200); // Key debounce time
INTCON.INTF = 0;
}

void main() {
ANSEL = 0b00000000; // All I/O pins are configured as digital
CMCON0 = 0x07 ;

// Disbale comparators

TRISC = 0b00010000; // PORTC all outputs except RC4


TRISA = 0b00000100; // PORTA all outputs except RA2
INTCON = 0b10010000; // Set GIE and INTE bits
OPTION_REG.INTEDG = 0; // External interrupt on falling edge of RA2/INT pin
count = 0;
LED = 0;
PORTC = count;
do {
count ++;

if (count ==16) count =0;


PORTC = count;
delay_ms(1000);
}while (1); // infinite loop
}

Lab 17: Sleep and Wake PIC microcontrollers


/* Project name: Understanding sleep mode in PIC microcontrollers * Copyright: (c) Rajendra
Bhatt * Test configuration: MCU: PIC16F628A Oscillator: XT, 4.0000 MHz */
sbit LED at RB0_bit; // LED is connected to PORTB.0
void main()
{
TRISB = 0b00000000;
TRISA = 0b00100000;
LED = 0;
OPTION_REG = 0b00001111; // Assign 1:128 prescaler to WDT
do
{
asm sleep; // Sleep mode, WDT is cleared,
// and time out occurs at Approx. 2.3 Sec
// Current is minimum in Sleep mode
LED = 1; // After wake-up the LED is turned on
Delay_ms(500); LED = 0;
asm CLRWDT; // Clear WDT
Delay_ms(2000); // Measure current here and compare with Sleep mode
}while(1); // current
}

Lab 18: Matrix keypad interfacing

// Column connections
sbit Col1 at RB4_bit;
sbit Col2 at RB5_bit;
sbit Col3 at RB6_bit;
sbit Col4 at RB7_bit;

// Define LCD connections


sbit LCD_RS at RA6_bit;
sbit LCD_EN at RA7_bit;
sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA2_bit;
sbit LCD_D7 at RA3_bit;
sbit LCD_RS_Direction at TRISA6_bit;
sbit LCD_EN_Direction at TRISA7_bit;
sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA2_bit;
sbit LCD_D7_Direction at TRISA3_bit;
// End LCD module connections

// Define Messages
char message1[] = "Hit Key:";
char KeyPad[] = " ";
unsigned short temp1, temp2;
unsigned short col, row;

char KeyS[4][4] ={
{0x31, 0x32, 0x33, 0x41},

{0x34, 0x35, 0x36, 0x42},


{0x37, 0x38, 0x39, 0x43},
{0x2A, 0x30, 0x23, 0x44}
};
void Debounce(){
Delay_ms(50);
}

char Get_Key(){
// Make rows output and columns input
TRISB = 0b11110000;
WPUB = 0b11110000;
PORTB = 0b11110000;
temp1 = (PORTB >> 4) ^ 0x0F;
col = temp1/2;
if(col == 4) col = 3;
// Make columns output and rows input
TRISB = 0b00001111;
WPUB = 0b00001111;
PORTB = 0b00001111;
temp2 = PORTB ^ 0x0F;
row = temp2/2;
if (row == 4) row = 3;
if (temp1 && temp2) return KeyS[row][col];
return ' ';

void main() {
char key[] = " ";
TRISA = 0b00100000; // PORTA output except RA5

TRISB = 0b00000000;
ANSELA = 0x00;

// Disable any analog functions in PORTA

ANSELB = 0x00;

// Disable any analog functions in PORTB

OPTION_REG = 0x00;
PORTB = 0b11111111; // All rows equal to 1
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);

// CLEAR display

Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,message1);

// Write message1 in 1st row

do {
key[0] = Get_Key();
if (key[0] != ' ') Lcd_Out(2,7,key);
}while(1);
}

// Column connections
sbit Col1 at RB4_bit;
sbit Col2 at RB5_bit;
sbit Col3 at RB6_bit;
sbit Col4 at RB7_bit;

// Define LCD connections


sbit LCD_RS at RA6_bit;
sbit LCD_EN at RA7_bit;
sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;

// Cursor off

sbit LCD_D6 at RA2_bit;


sbit LCD_D7 at RA3_bit;
sbit LCD_RS_Direction at TRISA6_bit;
sbit LCD_EN_Direction at TRISA7_bit;
sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA2_bit;
sbit LCD_D7_Direction at TRISA3_bit;
// End LCD module connections

// Define Messages
char message1[] = "Hit Key:";

void Debounce(){
Delay_ms(50);
}

char Get_Key(){
// Scan row 1
PORTB = 0b00001110;
if (!Col1){
Debounce();
return 0x31;
}
if (!Col2){
Debounce();
return 0x32;
}
if (!Col3){
Debounce();
return 0x33;

}
if (!Col4){
Debounce();
return 0x41;
}
// Scan row 2
PORTB = 0b00001101;
if (!Col1){
Debounce();
return 0x34;
}
if (!Col2){
Debounce();
return 0x35;
}
if (!Col3){
Debounce();
return 0x36;
}
if (!Col4){
Debounce();
return 0x42;
}
// Scan row 3
PORTB = 0b00001011;
if (!Col1){
Debounce();
return 0x37;
}
if (!Col2){
Debounce();

return 0x38;
}
if (!Col3){
Debounce();
return 0x39;
}
if (!Col4){
Debounce();
return 0x43;
}
// Scan row 4
PORTB = 0b00000111;
if (!Col1){
Debounce();
return 0x2A;
}
if (!Col2){
Debounce();
return 0x30;
}
if (!Col3){
Debounce();
return 0x23;
}
if (!Col4){
Debounce();
return 0x44;
}
return ' ';

void main() {
char key[] = " ";
TRISA = 0b00100000; // PORTA output except RA5
TRISB = 0b11110000; // R1-R4 output, C1-C4 input
ANSELA = 0x00;

// Disable any analog functions in PORTA

ANSELB = 0x00;

// Disable any analog functions in PORTB

OPTION_REG = 0x00;
PORTB = 0b00001111; // All rows equal to 1
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);

// CLEAR display

Lcd_Cmd(_LCD_CURSOR_OFF);

// Cursor off

Lcd_Out(1,1,message1);

// Write message1 in 1st row

WPUB = 0b11110000;

// RB3-RB7 pull-up enabled

do {
key[0] = Get_Key();
if (key[0] != ' ') Lcd_Out(2,7,key);
}while(1);
}

LAB 19: PLAY MUSICAL NOTES


/*
Experiment No. 19: Playing music notes with a PIC micro
MCU: PIC16F628A at 4.0 MHz, MCLR Enabled
Description: Plays the Happy birthday tune
Compile with MikroC Pro for PIC
*/

void pause(unsigned short i){


unsigned short j;
for (j = 0; j < i; j++){
Delay_ms(10);
}
}

// Happy birthday notes


/*

Hap py Birth Day to you, Hap py birth day to


C4 C4 D4 C4 F4 E4 C4 C4 D4 C4 G4 */

unsigned int notes[] = {262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392,

/*

you, Hap py Birth Day dear xxxx

Hap py birth

F4 C4 C4 C5 A4 F4 E4 D4 B4b B4b A4 */
349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440,

/*

day to you
F4 G4 F4 */
349, 392, 349
};

unsigned short interval[] = {4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8,


8, 8, 4, 4, 8, 8, 8, 12};

unsigned short k;
void main() {
CMCON = 0x07;
TRISB = 0b00001000; // GP5, 5 I/P's, Rest O/P's
Sound_Init(&PORTB,0); // Initialize sound o/p pin

do {
for(k = 0; k<25; k++){
Sound_Play(notes[k], 100*interval[k]);
pause(6);
}
pause(100);
}while(1);
}

Lab 20: Interfacing a KS0108 based Graphics LCD (Part 1)


/*
* Project name: Testing GLCD with PIC16F887
* Copyright:
(c) Embedded-Lab.com, 2011.

* Description:
This routine demonstrates how to initialize a KS0108 based GLCD and
activate the pixels on display. A sub-routine is written to draw a point on
the GLCD at a given coordinates.
* Test configuration:
MCU:
Dev.Board:
Oscillator:

PIC16F887
UNI-DS6
HS, 10.0000 MHz

Ext. Modules: GLCD 128x64, KS108/107 controller

*/

// Glcd module connections


#define GLCD_Data PORTD
#define GLCD_Dir

TRISD

sbit GLCD_CS1 at RB0_bit;


sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS at RB2_bit;
sbit GLCD_RW at RB3_bit;
sbit GLCD_RST at RB4_bit;
sbit GLCD_EN at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;


sbit GLCD_CS2_Direction at TRISB1_bit;

sbit GLCD_RS_Direction at TRISB2_bit;


sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_RST_Direction at TRISB4_bit;
sbit GLCD_EN_Direction at TRISB5_bit;
// End Glcd module connections

void Enable_Pulse()
{
GLCD_EN = 1; //EN high
delay_us(5);
GLCD_EN = 0; //EN low
delay_us(5);
}

void GLCD_ON()
{
//Activate both chips
GLCD_CS1 = 0;
GLCD_CS2 = 0;
GLCD_RS = 0;
GLCD_RW = 0;
GLCD_Data = 0x3F;

//RS low --> command


//RW low --> write
//ON command

Enable_Pulse();
}

void Set_Start_Line(unsigned short line)


{
GLCD_RS = 0;
GLCD_RW = 0;
//Activate both chips
GLCD_CS1 = 0;

//RS low --> command


//RW low --> write

GLCD_CS2 = 0;
GLCD_Data = 0xC0 | line;

//Set Start Line command

Enable_Pulse();
}

void GOTO_COL(unsigned int x)


{
unsigned short Col_Data;
GLCD_RS = 0;

//RS low --> command

GLCD_RW = 0;
if(x<64)

//RW low --> write

//left section

{
GLCD_CS1 = 0;

//select chip 1

GLCD_CS2 = 1;

//deselect chip 2

Col_Data = x;

//put column address on data port

}
else

//right section

GLCD_CS2 = 0;
GLCD_CS1 = 1;
Col_Data = x-64; //put column address on data port
}
Col_Data = (Col_Data | 0x40 ) & 0x7F; //Command format
GLCD_Data = Col_Data;
Enable_Pulse();
}

void GOTO_ROW(unsigned int y)


{
unsigned short Col_Data;

GLCD_RS = 0;

//RS low --> command

GLCD_RW = 0;

//RW low --> write

Col_Data = (y | 0xB8 ) & 0xBF; //put row address on data port set command
GLCD_Data = Col_Data;
Enable_Pulse();
}

void GOTO_XY(unsigned int x,unsigned int y)


{
GOTO_COL(x);
GOTO_ROW(y);
}

void GLCD_Write(unsigned short b)


{
GLCD_RS = 1;

//RS high --> data

GLCD_RW = 0;

//RW low --> write

GLCD_Data = b;

//put data on data port

delay_us(1);
Enable_Pulse();
}

unsigned short GLCD_Read(unsigned short column)


{
unsigned short read_data = 0; //Read data here
GLCD_Dir = 0xFF;
GLCD_RW = 1;

//PORTD as Input
//Read

GLCD_RS = 1;

//Data

GLCD_CS1 = (column>63);
GLCD_CS2 = !GLCD_CS1;
delay_us(1);

//tasu

//Disable/Enable CS2

GLCD_EN = 1;
delay_us(1);

//Latch RAM data into ouput register


//twl + tf

//Dummy read
GLCD_EN = 0;

//Low Enable

delay_us(5);
GLCD_EN = 1;

//latch data from output register to data bus

delay_us(1);

//tr + td(twh)

read_data = GLCD_Data;
GLCD_EN = 0;
delay_us(1);

//Input data

//Low Enable to remove data from the bus


//tdhr

GLCD_Dir = 0x00;

//Output again

return read_data;
}

void GLCD_Clrln(unsigned short ln)


{
int i;
GOTO_XY(0,ln);

//At start of line of left side

GOTO_XY(64,ln);

//At start of line of right side (Problem)

GLCD_CS1 = 0;
for(i=0;i<65;i++)
GLCD_Write(0);
}

//-------------------------

void GLCD_CLR()
{
unsigned short m;

for(m=0;m<8;m++){
GLCD_Clrln(m);
}
}

void Draw_Point(unsigned short x,unsigned short y, unsigned short color)


{
unsigned short Col_Data;;
GOTO_XY(x,(y/8));
switch (color)
{
case 0:

//Light spot

Col_Data = ~(1<<(y%8)) & GLCD_Read(x);


break;
case 1:

//Dark spot

Col_Data = (1<<(y%8)) | GLCD_Read(x);


break;
}
GOTO_XY(x,(y/8));
GLCD_Write(Col_Data);
}

void main() {
unsigned short u, v;
ANSEL = 0;

// Configure AN pins as digital

ANSELH = 0;
C1ON_bit = 0;
C2ON_bit = 0;
TRISD = 0x00;
TRISB = 0x00;
PORTB = 0x00;

// Disable comparators

PORTD = 0x00;
GLCD_CS1 = 1;
GLCD_CS2 = 1;
GLCD_RST = 1;
GLCD_ON();
GLCD_CLR();
Set_Start_Line(0);
do {

for(u=0; u<64; u+=6)


for (v=0; v<128; v+=2)
Draw_Point(v, u, 1);
delay_ms(1000);
GLCD_CLR();
delay_ms(1000);

} while(1);
}

// De-Activate both chips

Lab 21: Servo motor control


/*
Lab 21: Servo motor Control using PIC16F628A
MCU: PIC16F628A running at 4.0 MHz, MCLR enabled, WDT is OFF
Written by: Rajendra Bhatt (www.embedded-lab.com)
2012/03/29
Description: User input switch is connected to RB0 and Servo Control signal
is generated from RB1 pin.
*/

sbit SW1 at RB0_bit;


sbit Control at RB1_bit;

unsigned short i=7, delay;

void interrupt() {
delay = i*10;
Control = 1;
Delay_Cyc(delay); // Generates delay equal to 10*delay clock cycles
Control = 0;
TMR0 = 180;

// TMR0 returns to its initial value

INTCON.T0IF = 0; // Bit T0IF is cleared so that the interrupt could reoccur


}

void main() {
CMCON = 0x07; // Disable Comparators
TRISB = 0b00000001;
PORTB = 0;
OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0
TMR0 = 180;
INTCON = 0xA0;

// Timer T0 counts from 180 to 255 to create ~20 ms period


// Enable interrupt TMR0 and Global Interrupts

do{
if(!SW1){

// Change pulse width when Switch is pressed

Delay_ms(300);
i = i+2;
if(i>24) i=7;
}

}while(1);
}

You might also like