######################MAIN.C########################include <htc.h>#include "lcd.h"voidmain(void){ lcd_init(); lcd_goto(0); // select first line lcd_puts("12345678"); lcd_goto(0x40); // Select second line lcd_puts("Hello world"); for(;;);}###########################################################################LCD.C#####################################/* * LCD interface example * Uses routines from delay.c * This code will interface to a standard LCD controller * like the Hitachi HD44780. It uses it in 4 bit mode, with * the hardware connected as follows (the standard 14 pin * LCD connector is used): * * PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble) * PORTA bit 3 is connected to the LCD RS input (register select) * PORTA bit 1 is connected to the LCD EN bit (enable) * * To use these routines, set up the port I/O (TRISA, TRISD) then * call lcd_init(), then other routines as required. * */#ifndef _XTAL_FREQ // Unless specified elsewhere, 4MHz system frequency is assumed #define _XTAL_FREQ 4000000#endif#include <htc.h>#include "lcd.h"#define LCD_RS RA3#define LCD_RW RA2#define LCD_EN RA1#define LCD_DATA PORTD#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))/* write a byte to the LCD in 4 bit mode */voidlcd_write(unsigned char c){ __delay_us(40); LCD_DATA = ( ( c >> 4 ) & 0x0F ); LCD_STROBE(); LCD_DATA = ( c & 0x0F ); LCD_STROBE();}/* * Clear and home the LCD */voidlcd_clear(void){ LCD_RS = 0; lcd_write(0x1); __delay_ms(2);}/* write a string of chars to the LCD */voidlcd_puts(const char * s){ LCD_RS = 1; // write characters while(*s) lcd_write(*s++);}/* write one character to the LCD */voidlcd_putch(char c){ LCD_RS = 1; // write characters lcd_write( c );}/* * Go to the specified position */voidlcd_goto(unsigned char pos){ LCD_RS = 0; lcd_write(0x80+pos);} /* initialise the LCD - put into 4 bit mode */voidlcd_init(){ char init_value; ADCON1 = 0x06; // Disable analog pins on PORTA init_value = 0x4; TRISA=0; TRISD=0; LCD_RS = 0; LCD_EN = 0; LCD_RW = 0; __delay_ms(30); // wait 15mSec after power applied, LCD_DATA = init_value; LCD_STROBE(); __delay_ms(5); LCD_STROBE(); __delay_us(200); LCD_STROBE(); __delay_us(200); LCD_DATA = 2; // Four bit mode LCD_STROBE(); lcd_write(0x28); // Set interface length lcd_write(0xF); // Display On, Cursor On, Cursor Blink lcd_clear(); // Clear screen lcd_write(0x6); // Set entry Mode}############################################################################LCD.H##################################/* * LCD interface header file * See lcd.c for more info *//* write a byte to the LCD in 4 bit mode */extern void lcd_write(unsigned char);/* Clear and home the LCD */extern void lcd_clear(void);/* write a string of characters to the LCD */extern void lcd_puts(const char * s);/* Go to the specified position */extern void lcd_goto(unsigned char pos); /* intialize the LCD - call before anything else */extern void lcd_init(void);extern void lcd_putch(char);/* Set the cursor position */#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)##########################################################################DELAY.C###########################/* * Delay functions * See delay.h for details * * Make sure this code is compiled with full optimization!!! */#include "delay.h"voidDelayMs(unsigned char cnt){#if XTAL_FREQ <= 2MHZ do { DelayUs(996); } while(--cnt);#endif#if XTAL_FREQ > 2MHZ unsigned char i; do { i = 4; do { DelayUs(250); } while(--i); } while(--cnt);#endif}###################################################################DELAY.H########################/* * Delay functions for HI-TECH C on the PIC * * Functions available: * DelayUs(x) Delay specified number of microseconds * DelayMs(x) Delay specified number of milliseconds * * Note that there are range limits: x must not exceed 255 - for xtal * frequencies > 12MHz the range for DelayUs is even smaller. * To use DelayUs it is only necessary to include this file; to use * DelayMs you must include delay.c in your project. * *//* Set the crystal frequency in the CPP predefined symbols list in HPDPIC, or on the PICC commmand line, e.g. picc -DXTAL_FREQ=4MHZ or picc -DXTAL_FREQ=100KHZ Note that this is the crystal frequency, the CPU clock is divided by 4. * MAKE SURE this code is compiled with full optimization!!! */#ifndef XTAL_FREQ#define XTAL_FREQ 4MHZ /* Crystal frequency in MHz */#endif#define MHZ *1000L /* number of kHz in a MHz */#define KHZ *1 /* number of kHz in a kHz */#if XTAL_FREQ >= 12MHZ#define DelayUs(x) { unsigned char _dcnt; \ _dcnt = (x)*((XTAL_FREQ)/(12MHZ)); \ while(--_dcnt != 0) \ continue; }#else#define DelayUs(x) { unsigned char _dcnt; \ _dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \ while(--_dcnt != 0) \ continue; }#endifextern void DelayMs(unsigned char);############################################################
#include <pic.h>#include <pic168xa.h>#include <stdio.h>#include "delay.h"char scanned_key=0x00;char scan_keypad();char decode_key(char val);__CONFIG(XT & PWRTDIS & DUNPROT & UNPROTECT & BORDIS & DEBUGDIS & WDTDIS & LVPDIS);void delay();void init_KEYPAD(void) //initialize the keypad{ TRISD |= 0x70; //PORTD<6:4> input, COLUMNS TRISD &= ~0x0F; //PORTD<3:0> output, ROWS PORTD |= 0x0F; //PORTD<3:0> initially high}void main(){TRISB = 0b11110000; // RB0 - RB3 are outputs.TRISA = 0b11110011; // RA2 - RA3 are outputs.ADCON1 = 0b00000111; // All PORTA are digital I/Os.PORTB = 0; //Clear PORTS.PORTA = 0;init_KEYPAD();lcd_init(); // Initialize the LCD.lcd_goto(0);lcd_puts("line 1");delay();lcd_clear();while(1){ init_KEYPAD(); scanned_key = scan_keypad(); decode_key(scanned_key); }for (;;){ // Forever loop. }}void delay() //delay program { int i; //define integer variable for(i=0xffff;i--;); //delay }char scan_keypad(){ char val_1 = 0x00;char val_2 = 0x00;char count1; for(count1=0;count1 < 4;count1++) { PORTD = ~(0x01 << count1); //scan row val_1 = PORTD & 0x70; //read column, RD<6:4> //while clearing RD<7> & //RD<3:0> if (val_1 != 0x70) //if a column is pressed { val_2 = (val_1 | count1); //column (high-nibble) and count (low-nibble) return val_2; //return value } } return 0xFF; //return any value }void decode_key(unsigned char val){ unsigned char key; switch(val) { case 0x60: //0 lcd_puts("1"); break; case 0x50: //1 lcd_puts("2"); break; case 0x30: //2 lcd_puts("3"); break; case 0x61: //3 lcd_puts("4"); break; case 0x51: //4 lcd_puts("5"); break; case 0x31: //5 lcd_puts("6"); break; case 0x62: //6 lcd_puts("7"); break; case 0x52: //7 lcd_puts("8"); break; case 0x32: //8 lcd_puts("9"); break; case 0x63: //9 lcd_puts("*"); break; case 0x53: //10 lcd_puts("0"); break; case 0x33: //11 lcd_puts("#"); break; default: break; } }