Sunday, January 25, 2015

MikroC Keypad Interfacing

Keypad Library
The mikroC PRO for PIC provides a library for working with 4x4 keypad. The library routines can also be used with 4x1, 4x2, or 4x3 keypad. For connections explanation see schematic at the bottom of this page.
Library Routines

*Keypad_Init
          Keypad_Init(); //Initializes port for working with keypad.
*Keypad_Key_Press
            char kp;     //Reads the key from keypad when key gets pressed.    
      kp = Keypad_Key_Press();
*Keypad_Key_Click
            char kp;       
  kp = Keypad_Key_Click();
                Call to Keypad_Key_Click is a blocking call: the function waits until some key is pressed and released. When released, the function returns 1 to 16, depending on the key. If more than one key is pressed simultaneously the function will wait until all pressed keys are released. After that the function will return the code of the first pressed key.

Library Example

This is a simple example of using the Keypad Library. It supports keypads with 1..4 rows and 1..4 columns. The code being returned by Keypad_Key_Click() function is in range from 1..16. In this example, the code returned is transformed into ASCII codes [0..9,A..F] and displayed on Lcd. In addition, a small single-byte counter displays in the second Lcd row number of key presses.
unsigned short kp, cnt, oldstate = 0;
char txt[6];

// Keypad module connections
char  keypadPort at PORTD;
// End Keypad module connections

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

void main() {
  cnt = 0;                                 // Reset counter
  Keypad_Init();                           // Initialize Keypad                             
  ANSEL  = 0;                              // Configure AN pins as digital I/O
  ANSELH = 0;
  Lcd_Init();                              // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                     // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);                // Cursor off
  Lcd_Out(1, 1, "1");
  Lcd_Out(1, 1, "Key  :");                 // Write message text on LCD
  Lcd_Out(2, 1, "Times:");

  do {
    kp = 0;                                // Reset key code variable

    // Wait for key to be pressed and released
    do
      // kp = Keypad_Key_Press();          // Store key code in kp variable
     
       kp = Keypad_Key_Click();             // Store key code in kp variable
       while (!kp);
   // Prepare value for output, transform key to it's ASCII value
    switch (kp) {
      //case 10: kp = 42; break;  // '*'   // Uncomment this block for keypad4x3
      //case 11: kp = 48; break;  // '0'  
      //case 12: kp = 35; break;  // '#'
      //default: kp += 48;

      case  1: kp = 49; break; // 1        // Uncomment this block for keypad4x4
      case  2: kp = 50; break; // 2
      case  3: kp = 51; break; // 3
      case  4: kp = 65; break; // A
      case  5: kp = 52; break; // 4
      case  6: kp = 53; break; // 5
      case  7: kp = 54; break; // 6
      case  8: kp = 66; break; // B       
      case  9: kp = 55; break; // 7
      case 10: kp = 56; break; // 8
      case 11: kp = 57; break; // 9
      case 12: kp = 67; break; // C
      case 13: kp = 42; break; // *
      case 14: kp = 48; break; // 0
      case 15: kp = 35; break; // #
      case 16: kp = 68; break; // D

    }

    if (kp != oldstate) {                  // Pressed key differs from previous
      cnt = 1;
      oldstate = kp;
      }
    else {                                 // Pressed key is same as previous
      cnt++;
      }

    Lcd_Chr(1, 10, kp);                    // Print key ASCII value on LCD

    if (cnt == 255) {                      // If counter varialble overflow
      cnt = 0;
      Lcd_Out(2, 10, "   ");
      }

    WordToStr(cnt, txt);                   // Transform counter value to string
    Lcd_Out(2, 10, txt);                   // Display counter value on LCD
  } while (1);
}

           

MikroC Tutorial LCD Interafacing

The mikroC PRO for PIC provides a library for communication with Lcds (with HD44780 compliant controllers) through the 4-bit interface. An example of Lcd connections is given on the schematic at the bottom of this page

Library Routines

*Lcd_Init    
Lcd_Init();    // Initializes Lcd module. LCD pins must be defined before using this routine
*Lcd_Out   
Lcd_Out(1, 3, "Hello!");                     // Prints text on Lcd starting from specified position.
*Lcd_Out_Cp   
Lcd_Out_Cp("Here!");            // Prints text on Lcd at current cursor position.
*Lcd_Chr     
Lcd_Chr(2, 3, 'i');                    // Prints character on Lcd at specified position.
*Lcd_Chr_Cp
Lcd_Chr_Cp('e');                                      // Prints character on Lcd at current cursor position.
*Lcd_Cmd     
Lcd_Cmd(_LCD_CLEAR);                            // Sends command to Lcd.

Available LCD Commands

Lcd Command
Purpose
_LCD_FIRST_ROW
Move cursor to the 1st row
_LCD_SECOND_ROW
Move cursor to the 2nd row
_LCD_THIRD_ROW
Move cursor to the 3rd row
_LCD_FOURTH_ROW
Move cursor to the 4th row
_LCD_CLEAR
Clear display
_LCD_RETURN_HOME
Return cursor to home position, returns a shifted display to its original position. Display data RAM is unaffected.
_LCD_CURSOR_OFF
Turn off cursor
_LCD_UNDERLINE_ON
Underline cursor on
_LCD_BLINK_CURSOR_ON
Blink cursor on
_LCD_MOVE_CURSOR_LEFT
Move cursor left without changing display data RAM
_LCD_MOVE_CURSOR_RIGHT
Move cursor right without changing display data RAM
_LCD_TURN_ON
Turn Lcd display on
_LCD_TURN_OFF
Turn Lcd display off
_LCD_SHIFT_LEFT
Shift display left without changing display data RAM
_LCD_SHIFT_RIGHT
Shift display right without changing display data RAM








 

Library Example

// LCD module connections

sbit LCD_RS at RB4_bit;        sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;        sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;        sbit LCD_D7 at RB3_bit;
 
sbit LCD_RS_Direction at TRISB4_bit;  sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;  sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;  sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
 
char txt1[] = "mikroElektronika";    
char txt2[] = "EasyPIC6";
char txt3[] = "Lcd4bit";
char txt4[] = "example";
 
char i;                              // Loop variable
 
void Move_Delay() {                  // Function used for text moving
  Delay_ms(500);                     // You can change the moving speed here
}
 
void main(){
  ANSEL  = 0;                        // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                      // Disable comparators
  C2ON_bit = 0;
 
  Lcd_Init();                        // Initialize LCD
 
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,6,txt3);                 // Write text in first row
 
  Lcd_Out(2,6,txt4);                 // Write text in second row
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
 
  Lcd_Out(1,1,txt1);                 // Write text in first row
  Lcd_Out(2,5,txt2);                 // Write text in second row
 
  Delay_ms(2000);
 
  // Moving text
  for(i=0; i<4; i++) {               // Move text to the right 4 times
    Lcd_Cmd(_LCD_SHIFT_RIGHT);
    Move_Delay();
  }
 
  while(1) {                         // Endless loop
    for(i=0; i<8; i++) {             // Move text to the left 7 times
      Lcd_Cmd(_LCD_SHIFT_LEFT);
      Move_Delay();
    }
 
    for(i=0; i<8; i++) {             // Move text to the right 7 times
      Lcd_Cmd(_LCD_SHIFT_RIGHT);
      Move_Delay();
    }
  }
}
 
 


Programs on PIC18

Example 7-1
Write a C18 program to send values 00--FF to Port B.
Solution:
#include <P1BF45B.h>  //for TRISB and PORTB declarations
void main(void)
{
unsigned char z;
TRISB = 0;        //make Port B an output                      
for(z=0;z<=255;z++)
PORTE = z;
while (1);  //NEEDED IF RUNNING IN HARDWARE
}
Run the above program on your simulator to see how Port B displays values 00--FFH in
binary. Notice that "while(l )" is needed if this program is running in hardware.

Example 7-2
Write a C18 program to send hex values for ASCII characters of 0, 1, 2, 3, 4, 5, A, B,
C, and D to Port B.
Solution:
#include <P18F458.h>
void main(void)
{
unsigned char mynum[]= "012345ABCD"; //data is stored in RAM
unsigned char z;
TRISB = 0;     //make Port B an output
for(z=0;z<10;z++)
PORTB = mynum[z];
while(l);
}           //stay here forever
Run the above program on your simulator to see how Port B displays values 30H,
31H, 32H, 33H, 34H, 35H, 41H, 42H, 43H, and 44H (the hex values for ASCII 0, 1,
2, etc.). Notice that the last statement "while(l)" is needed only if we run the program
in hardware. This is like "GOTO $" or "BRA$" in Assembly language.


Example 7-3
Write a C 18 program to toggle all the bits of Port B continuously.
Solution:
II Toggle PB forever
#include <P18F458.h>
void main(void)
{
TRISB = 0;
for (;;)
{
//make Port B an output
//repeat forever
PORTB
PORTB
Ox55; //Ox indicates the data is in hex (binary)
OxAA;
Run the above program on your simulator to see how Port B toggles continuously.

Example 7-4
Write a C18 program to send values of -4 to +4 to Port B.
Solution:
//sign numbers
#include <P18F45B.h>
void main(void)
{
char mynum[]= {+1,-1,+2,-2,+3,-3,+4,-4};
unsigned char z;
TRISB = 0; I /make Port B an output
for(z=O;z<S;z++)
PORTE = mynum[z];
while (1); //stay here forever
Run the above program on your simulator to see how PORTB displays values of 1, FFH,
2, FEH, 3, FDH, 4, and FCH (the hex values for +1, ~1, +2, ~2, etc.). See Chapter 5 for
discussion of signed numbers.




Example 7-5
Write a C18 program to toggle all bits of Port B 50,000 times.
Solution:
#include <P18F458.h>
void main(void)
{
unsigned int z;
TRISB = 0;
for(z=0;z<=50000;z++)
{
}
PORTB
PORTB
while(1);
Ox55;
OxAA;
}
//make Port B an output
//stay here forever
Run the above program on your simulator to see how Port B toggles continuously.
Notice that the maximum value for unsigned int is 65,535.

Example 7-6
Write a C 18 program to toggle all bits of Port B 100,000 times.
Solution:
//toggle PB 100,00 times
#include <P18F458.h>
void main(void)
{
256
unsigned short long z;
unsigned int x;
TRISB = 0;
for(z=0;Z<=10000;z++)
{
PORTB
PORTB
while (1);
Ox55;
OxAA;
}

Example 7-7
Write a C 18 program to toggle all the bits of Port B ports continuously with a 250 ms delay. Assume that the system is PIC18F458 with XTAL = 10 MHz.
Solution:
#include <P18F458.h>
void MSDelay(unsigned int);
void main(void)
{
TRISB = 0;
while (1)
{
}
PORTB = 0x55;
MSDelay(250);
PORTB = 0xAA;
MSDelay(250);
}
void MSDelay(unsigned int itime)
{
unsigned int i; unsigned char j;
for(i=0;i<itime;i++)
for{j=0;j<165;j++);
}

Example 7-11
Write a C 18 program to get a byte of data from Port C. If it is less than I 00, send it to Port B; otherwise, send it to Port D.
Solution:
#include <P18F458.h>
void main(void)
{
260
unsigned char mybyte;
TRISC OxFF;
TRISE = 0;
TRISD = 0;
while (1)
{
}


Example 7-12
Write a C 18 program to toggle only bit RB4 continuously without disturbing the rest of the bits of Port B.
Solution:
#include <P18F458.h>
#define mybit PORTBbits.RB4 //declare single bit
void main(void)
{
TRISBbits.TRISB4=0;          // make RB4 an output
while (1)
{
mybit = 1;                 //turn on RB4
mybit = 0;                 //turn off RB4
}
}


Example 7-13
Write a Cl8 program to monitor bit PC5. If it is HIGH, send 55H to Port B; otherwise, send AAH to Port D.
Solution:
#include <P18F458.h>
#define mybit PORTCbits.RC5   //notice single-bit declaration
void main(void)
{
TRISCbits.TRISC5 = 1;         //RCS as input
TRISC = 0;
TRISB = 0;                             //Ports C and B output
while(1)
{
if (mybit ==1)
PORTB = 55H;
else
PORTC = AAH;
}
}





Example 7-14
A door sensor is connected to the RBI pin, and a buzzer is connected to RC7. Write a C18 program to monitor the door sensor, and when it opens, sound the buzzer. You can sound the buzzer by sending a square wave of a few hundred Hz frequency to it.
Solution:
#include <P18F458.h>
void MSDelay(unsigned int);
#define Dsensor PORTBbits.RB1
#define buzzer PORTCbits .RC7
void main(void)
{
TRISBbits.TRISB1 = 1;   //PORTB.1 as an input
TRISCbits.TRISC7 = 0;   //make PORTC.7 an output

while(Dsensor == 1)
{
buzzer = 0;
MSDelay(200) ;
buzzer = 1;
MSDelay(200);
while (1); //stay here forever
void MSDelay(unsigned int itime )
{
unsigned int i;
unsigned char j ;
for(i=0;i<itime;i++)
for(j=0;j<165;j++)
}