Hi, guys. I am working on my final year project. I've been trying to interface the Matrix Keypad & 16*2 LCD along the with PIC. However, I wasn't able to get it to work. The LCD is able to display the 'Enter Duration' text but does not display the content of the 'Duration' array. The microcontroller I used is PIC16F887. My current code is listed below. Please help me check my code.
The library I used for the LCD is provided below:
Code:
#pragma config CONFIG1 = 0x2CD4
#pragma config CONFIG2 = 0x0700
#include
#include
//LCD module connections
#define LCD_RS RD0
#define LCD_EN RD1
#define LCD_D4 RD2
#define LCD_D5 RD3
#define LCD_D6 RD4
#define LCD_D7 RD5
#define LCD_RS_DIR TRISD0
#define LCD_EN_DIR TRISD1
#define LCD_D4_DIR TRISD2
#define LCD_D5_DIR TRISD3
#define LCD_D6_DIR TRISD4
#define LCD_D7_DIR TRISD5
//End LCD module connections
//matrix keypad connections
#define X_1 RB0
#define X_2 RB1
#define X_3 RB2
#define X_4 RB3
#define Y_1 RB4
#define Y_2 RB5
#define Y_3 RB6
#define Y_4 RB7
#define Keypad_PORT PORTB
#define Keypad_PORT_Direction TRISB
#include
#define _XTAL_FREQ 8000000
#include // include stdint header
#include "LCD_Lib.c" // include LCD driver source file
// Function declarations
void InitKeypad(void);
char switch_press_scan(void);
void InitKeypad(void)
{
Keypad_PORT = 0x00; // Set Keypad port pin values zero
Keypad_PORT_Direction = 0xF0; // Last 4 pins input, First 4 pins output
OPTION_REG &= 0x7F;
}
char keypad_scanner(void)
{
X_1 = 0; X_2 = 1; X_3 = 1; X_4 = 1;
if (Y_1 == 0) { __delay_ms(100); while (Y_1==0); return '1'; }
if (Y_2 == 0) { __delay_ms(100); while (Y_2==0); return '2'; }
if (Y_3 == 0) { __delay_ms(100); while (Y_3==0); return '3'; }
if (Y_4 == 0) { __delay_ms(100); while (Y_4==0); return 'A'; }
X_1 = 1; X_2 = 0; X_3 = 1; X_4 = 1;
if (Y_1 == 0) { __delay_ms(100); while (Y_1==0); return '4'; }
if (Y_2 == 0) { __delay_ms(100); while (Y_2==0); return '5'; }
if (Y_3 == 0) { __delay_ms(100); while (Y_3==0); return '6'; }
if (Y_4 == 0) { __delay_ms(100); while (Y_4==0); return 'B'; }
X_1 = 1; X_2 = 1; X_3 = 0; X_4 = 1;
if (Y_1 == 0) { __delay_ms(100); while (Y_1==0); return '7'; }
if (Y_2 == 0) { __delay_ms(100); while (Y_2==0); return '8'; }
if (Y_3 == 0) { __delay_ms(100); while (Y_3==0); return '9'; }
if (Y_4 == 0) { __delay_ms(100); while (Y_4==0); return 'C'; }
X_1 = 1; X_2 = 1; X_3 = 1; X_4 = 0;
if (Y_1 == 0) { __delay_ms(100); while (Y_1==0); return '*'; }
if (Y_2 == 0) { __delay_ms(100); while (Y_2==0); return '0'; }
if (Y_3 == 0) { __delay_ms(100); while (Y_3==0); return '#'; }
if (Y_4 == 0) { __delay_ms(100); while (Y_4==0); return 'D'; }
return 'n';
}
// Function name: GetKey
// Read pressed key value from keypad and return its value
char switch_press_scan(void) // Get key from user
{
char key = 'n'; // Assume no key pressed
while(key=='n') // Wait until a key is pressed
key = keypad_scanner(); // Scan the keys again and again
return key; //when key pressed then return its value
}
void main(void)
{
LCD_Begin();
uint8_t t = 0;
static char Duration[10];
char Key = 'n';
InitKeypad();
LCD_Goto(1, 1);
LCD_Print("Enter Duration");
LCD_Goto(1, 2);
while(t<9){
Key = switch_press_scan();
Duration[t]=Key;
LCD_Goto(t+1, 2);
LCD_Print(Duration);
t++;
}
}
The library I used for the LCD is provided below:
Code:
#pragma warning disable 520
#include
#define LCD_FIRST_ROW 0x80
#define LCD_SECOND_ROW 0xC0
#define LCD_THIRD_ROW 0x94
#define LCD_FOURTH_ROW 0xD4
#define LCD_CLEAR 0x01
#define LCD_RETURN_HOME 0x02
#define LCD_ENTRY_MODE_SET 0x04
#define LCD_CURSOR_OFF 0x0C
#define LCD_UNDERLINE_ON 0x0E
#define LCD_BLINK_CURSOR_ON 0x0F
#define LCD_MOVE_CURSOR_LEFT 0x10
#define LCD_MOVE_CURSOR_RIGHT 0x14
#define LCD_TURN_ON 0x0C
#define LCD_TURN_OFF 0x08
#define LCD_SHIFT_LEFT 0x18
#define LCD_SHIFT_RIGHT 0x1E
#ifndef LCD_TYPE
#define LCD_TYPE 2 // 0=5x7, 1=5x10, 2=2 lines
#endif
__bit RS;
void LCD_Write_Nibble(uint8_t n);
void LCD_Cmd(uint8_t Command);
void LCD_Goto(uint8_t col, uint8_t row);
void LCD_PutC(char LCD_Char);
void LCD_Print(char* LCD_Str);
void LCD_Begin();
void LCD_Write_Nibble(uint8_t n)
{
LCD_RS = RS;
LCD_D4 = n & 0x01;
LCD_D5 = (n >> 1) & 0x01;
LCD_D6 = (n >> 2) & 0x01;
LCD_D7 = (n >> 3) & 0x01;
// send enable pulse
LCD_EN = 0;
__delay_us(1);
LCD_EN = 1;
__delay_us(1);
LCD_EN = 0;
__delay_us(100);
}
void LCD_Cmd(uint8_t Command)
{
RS = 0;
LCD_Write_Nibble(Command >> 4);
LCD_Write_Nibble(Command);
if((Command == LCD_CLEAR) || (Command == LCD_RETURN_HOME))
__delay_ms(2);
}
void LCD_Goto(uint8_t col, uint8_t row)
{
switch(row)
{
case 2:
LCD_Cmd(LCD_SECOND_ROW + col - 1);
break;
case 3:
LCD_Cmd(LCD_THIRD_ROW + col - 1);
break;
case 4:
LCD_Cmd(LCD_FOURTH_ROW + col - 1);
break;
default: // case 1:
LCD_Cmd(LCD_FIRST_ROW + col - 1);
}
}
void LCD_PutC(char LCD_Char)
{
RS = 1;
LCD_Write_Nibble(LCD_Char >> 4);
LCD_Write_Nibble(LCD_Char );
}
void LCD_Print(char* LCD_Str)
{
uint8_t i = 0;
RS = 1;
while(LCD_Str[i] != '\0')
{
LCD_Write_Nibble(LCD_Str[i] >> 4);
LCD_Write_Nibble(LCD_Str[i++] );
}
}
void LCD_Begin()
{
RS = 0;
LCD_RS = 0;
LCD_EN = 0;
LCD_D4 = 0;
LCD_D5 = 0;
LCD_D6 = 0;
LCD_D7 = 0;
LCD_RS_DIR = 0;
LCD_EN_DIR = 0;
LCD_D4_DIR = 0;
LCD_D5_DIR = 0;
LCD_D6_DIR = 0;
LCD_D7_DIR = 0;
__delay_ms(40);
LCD_Cmd(3);
__delay_ms(5);
LCD_Cmd(3);
__delay_ms(5);
LCD_Cmd(3);
__delay_ms(5);
LCD_Cmd(LCD_RETURN_HOME);
__delay_ms(5);
LCD_Cmd(0x20 | (LCD_TYPE << 2));
__delay_ms(50);
LCD_Cmd(LCD_TURN_ON);
__delay_ms(50);
LCD_Cmd(LCD_CLEAR);
__delay_ms(50);
LCD_Cmd(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
__delay_ms(50);
}