Mehmood Ahmed
New Member
Hi all,
I am very thankful to Mr. CC Dharmani for his code written for ATMEGA16 using winavr
I have modified some parts of the code for making it compatible with PIC16F877A.It provides keypad and LCD interfacing with PIC MCU the link of original code developer is given below
Design with Microcontrollers: 4x4 Matrix Key-board Interfacing with ATmega32
I am very thankful to Mr. CC Dharmani for his code written for ATMEGA16 using winavr
I have modified some parts of the code for making it compatible with PIC16F877A.It provides keypad and LCD interfacing with PIC MCU the link of original code developer is given below
Design with Microcontrollers: 4x4 Matrix Key-board Interfacing with ATmega32
C:
//********************************************************
// ******** 4X4 MATRIX KEY-BOARD INTERFACING ***********
// ORIGINAL CODE FOR ATmega16 BY CC Dharmani
// MODIFIED FOR PIC16F877A BY MEHMOOD AHMED,Karachi,Pakistan
// Note: Minor changes in original code have been done
// for PIC MCU
//********************************************************
//Controller: PIC16F877A at 4MHz
//Compiler: HITECH-C
//Date: May 18,2011
//********************************************************
#include <pic.h>
/* PIC Configuration Bit:
** INTIO - Using Internal RC No Clock
** WDTDIS - Wacthdog Timer Disable
** PWRTEN - Power Up Timer Enable
** MCLREN - Master Clear Enable
** UNPROTECT - Code Un-Protect
** UNPROTECT - Data EEPROM Read Un-Protect
** BORDIS - Borwn Out Detect Disable
** IESODIS - Internal External Switch Over Mode Disable
** FCMDIS - Monitor Clock Fail Safe Disable
*/
__CONFIG( WDTDIS & PWRTEN & UNPROTECT \
& UNPROTECT & BORDIS);
#define FOSC 4000000
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }
void _delay_ms(unsigned int ms)
{
unsigned char i;
do {
i = 4;
do {
_delay_us(164);
} while(--i);
} while(--ms);
}
//****** LCD Functions declaration ******** //
void LCD_init(void);
void LCD_WriteCommand (unsigned char Command);
void LCD_WriteData (unsigned char Data);
void LCD_DisplayString (char row, char column, char *string);
void LCD_Cursor(char row, char column);
#define ENABLE_LCD PORTD |= 0x80
#define DISABLE_LCD PORTD &= ~0x80
#define SET_LCD_DATA PORTD |= 0x20
#define SET_LCD_CMD PORTD &= ~0x20
#define KB_PORT_OUT PORTC
#define KB_PORT_IN PORTC
//************************
void port_init(void)
{
TRISB = 0x00;
PORTB = 0x00;
TRISC = 0xf0;//Key-board port, higer nibble - input, lower nibble - output
PORTC = 0xff;
TRISD = 0x0f;
PORTD = 0x00;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
port_init();
LCD_init();
}
//****************** MAIN FUNCTION *******************
int main(void)
{
unsigned char upperNibble, keyCode, keyPressed, i;
init_devices();
LCD_DisplayString (1,1," WELCOME ");
LCD_WriteCommand(0xc0); //moving LCD cursor to second row
while(1)
{
upperNibble = 0xff;
for(i=0; i<4; i++)
{
_delay_ms(1);
KB_PORT_OUT = ~(0x01 << i);
_delay_ms(1); //delay for port o/p settling
upperNibble = KB_PORT_IN | 0x0f;
if (upperNibble != 0xff)
{
_delay_ms(20); //key debouncing delay
upperNibble = KB_PORT_IN | 0x0f;
if(upperNibble == 0xff) goto OUT;
keyCode = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));
while (upperNibble != 0xff)
upperNibble = KB_PORT_IN | 0x0f;
_delay_ms(20); //key debouncing delay
switch (keyCode) //generating key characetr to display on LCD
{
case (0xee): keyPressed = '0';
break;
case (0xed): keyPressed = '1';
break;
case (0xeb): keyPressed = '2';
break;
case (0xe7): keyPressed = '3';
break;
case (0xde): keyPressed = '4';
break;
case (0xdd): keyPressed = '5';
break;
case (0xdb): keyPressed = '6';
break;
case (0xd7): keyPressed = '7';
break;
case (0xbe): keyPressed = '8';
break;
case (0xbd): keyPressed = '9';
break;
case (0xbb): keyPressed = 'A';
break;
case (0xb7): keyPressed = 'B';
break;
case (0x7e): keyPressed = 'C';
break;
case (0x7d): keyPressed = 'D';
break;
case (0x7b): keyPressed = 'E';
break;
case (0x77): keyPressed = 'F';
break;
default : keyPressed = 'X';
}//end of switch
LCD_WriteData(keyPressed);
OUT:;
}//end of if
}//end of for
}//end of while(1)
return 0;
}//end of main()
//***********************************************************************
//*********************** LCD Functions *****************************
//***********************************************************************
// *********************************
// *** Initialize the LCD driver ***
// *********************************
void LCD_init(void)
{
_delay_ms(100); // wait for 100ms
//SET_LCD_WRITE ; // Set LCD in write mode
LCD_WriteCommand (0x38); // 8 data lines
LCD_WriteCommand (0x08); // display off
LCD_WriteCommand (0x01); // clear LCD memory
_delay_ms (10); // 10ms delay after clearing LCD
LCD_WriteCommand (0x06); // cursor setting
LCD_WriteCommand (0x0f); // display ON
}
// **********************************************
// *** Write a command instruction to the LCD ***
// **********************************************
void LCD_WriteCommand (unsigned char Command)
{
SET_LCD_CMD; // Set LCD in command mode
PORTB = Command; // Load data to port
ENABLE_LCD; // Write data to LCD
asm("nop");
asm("nop");
DISABLE_LCD; // Disable LCD
_delay_ms(1); // wait for 1ms
}
// *****************************************
// *** Write one byte of data to the LCD ***
// *****************************************
void LCD_WriteData (unsigned char Data)
{
SET_LCD_DATA; // Set LCD in data mode
PORTB = Data; // Load data to port
ENABLE_LCD; // Write data to LCD
asm("nop");
asm("nop");
DISABLE_LCD; // Disable LCD
_delay_ms(1); // wait for 1ms
}
// *********************************************************************
// *** Display a string at the specified row and column, from FLASH ****
// *********************************************************************
void LCD_DisplayString (char row, char column, char *string)
{
LCD_Cursor (row, column);
while (*string)
LCD_WriteData(*string++);
}
// ***************************************************
// *** Position the LCD cursor at "row", "column". ***
// ***************************************************
void LCD_Cursor (char row, char column)
{
switch (row)
{
case 1: LCD_WriteCommand (0x80 + column - 1); break;
case 2: LCD_WriteCommand (0xc0 + column - 1); break;
default: break;
}
}
Attachments
Last edited by a moderator: