Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F877A LCD + Keypad Interface

Status
Not open for further replies.

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

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

  • 4x4 keypad.JPG
    4x4 keypad.JPG
    168.6 KB · Views: 1,279
  • kpinterface.c
    6.4 KB · Views: 661
  • Code.hex
    2 KB · Views: 485
Last edited by a moderator:
Due to some error it happened...now the examples have been placed...sorry for inconvenience
Thanks Ian
 
Last edited:
thanks. but what if i want it to be 3x4 matric keypad? what should i change? from the program i mean, removing the C4 (in) from the circuits.
 
Last edited:
thanks. but what if i want it to be 3x4 matric keypad? what should i change? from the program i mean, removing the C4 (in) from the circuits.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top