#include #include #include #include #define uchar unsigned char #define uint unsigned int /* CONFIG1 */ #pragma config FOSC = XT /* Oscillator Selection bits (XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN) */ #pragma config WDTE = OFF /* Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) */ #pragma config PWRTE = OFF /* Power-up Timer Enable bit (PWRT disabled) */ #pragma config MCLRE =ON /* RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) */ #pragma config CP = OFF /* Code Protection bit (Program memory code protection is disabled) */ #pragma config CPD = OFF /* Data Code Protection bit (Data memory code protection is disabled) */ #pragma config BOREN = OFF /* Brown Out Reset Selection bits (BOR disabled) */ #pragma config IESO = OFF /* Internal External Switchover bit (Internal/External Switchover mode is disabled) */ #pragma config FCMEN = OFF /* Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) */ #pragma config LVP = OFF /* Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming) */ /* CONFIG2 */ #pragma config BOR4V = BOR40V /* Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) */ #pragma config WRT = OFF /* Flash Program Memory Self Write Enable bits (Write protection off) */ void delaya_US( unsigned char n ); void LCD_CSH( void ); void LCD_WRITE_4( unsigned char R1, unsigned char FLAG ); void LCD_WRITE( unsigned char R1, unsigned char FLAG ); unsigned char LCD_READ( void ); void LCD_BUSY( void ); void delaya( unsigned int n ); /* LCD显示相关 */ #define DATA 1 /* LCD写数据时为1 */ #define COM 0 /* LCD写命令时为0 */ #define LINE1 0b10000000 #define LINE2 0b11000000 #define LCD_E RD6 #define LCD_RW RD5 #define LCD_RS RD4 /* ======延时(n×10)us */ void delaya_US( unsigned char n ) { unsigned char j; for ( j = 0; j < n; j++ ) { NOP(); NOP(); } } /* LCD初始化 */ void LCD_CSH( void ) { TRISD = 0x00; /* RD方向输出 */ delaya( 20 ); LCD_WRITE_4( 0b0011, COM ); delaya( 5 ); LCD_WRITE_4( 0b0011, COM ); delaya_US( 10 ); LCD_WRITE_4( 0b0011, COM ); delaya_US( 10 ); LCD_WRITE_4( 0b0010, COM ); LCD_BUSY(); LCD_WRITE( 0b00101000, COM ); LCD_WRITE( 0b00001100, COM ); LCD_WRITE( 0b00000001, COM ); delaya( 2 ); LCD_WRITE( 0b00000110, COM ); } /* LCD写4位命令 */ void LCD_WRITE_4( unsigned char R1, unsigned char FLAG ) { LCD_RW = 0; NOP(); LCD_RS = FLAG; PORTD &= 0xF0; LCD_E = 1; NOP(); PORTD |= R1; NOP(); NOP(); LCD_E = 0; NOP(); LCD_RS = 0; NOP(); PORTD &= 0xF0; } /* LCD写命令 */ void LCD_WRITE( unsigned char R1, unsigned char FLAG ) { unsigned char R2; LCD_BUSY(); LCD_RW = 0; NOP(); LCD_RS = FLAG; R2 = (R1 >> 4) & 0x0F; PORTD &= 0xF0; NOP(); LCD_E = 1; PORTD |= R2; NOP(); NOP(); LCD_E = 0; R2 = R1 & 0x0F; PORTD &= 0xF0; NOP(); LCD_E = 1; NOP(); PORTD |= R2; NOP(); NOP(); LCD_E = 0; NOP(); LCD_RS = 0; NOP(); PORTD &= 0xF0; } /* 读LCD状态 */ unsigned char LCD_READ( void ) { unsigned char R1; TRISD = 0x0F; LCD_RS = 0; NOP(); LCD_RW = 1; NOP(); NOP(); LCD_E = 1; NOP(); NOP(); NOP(); NOP(); R1 = 0; R1 = (PORTD << 4) & 0xF0; LCD_E = 0; NOP(); NOP(); NOP(); NOP(); LCD_E = 1; NOP(); NOP(); R1 |= (PORTD & 0x0F); LCD_E = 0; NOP(); LCD_RW = 0; TRISD = 0x00; return(R1); } /* 检测LCD是否忙 */ void LCD_BUSY( void ) { unsigned char R1; do { R1 = LCD_READ(); } while ( (R1 & 0x80) == 0x80 ); } /* ======延时(n)ms */ void delaya( unsigned int n ) { unsigned int j; unsigned char k; for ( j = 0; j < n; j++ ) for ( k = 246; k > 0; k-- ) NOP(); } /* * *********************************************************************** * 显示屏字符串写入函数 * *********************************************************************** */ void LCD_write_str( unsigned char x, unsigned char y, char *s ) { if ( y == 0 ) { LCD_WRITE( 0x80 + x, COM ); }else { LCD_WRITE( 0xC0 + x, COM ); } while ( *s ) { LCD_WRITE( *s, DATA ); s++; } } #define K1 RC0 #define K2 RC1 int Keyscan( void ) { TRISC |= 0x03; /*按键是输入 */ if ( K1 == 0 ) { delaya( 5 ); if ( K1 == 0 ) { while ( K1 == 0 ) ; /* 等待按键松开 */ return(1); } } if ( K2 == 0 ) { delaya( 5 ); if ( K2 == 0 ) { while ( K2 == 0 ) ; /* 等待按键松开 */ return(2); } } return(0); } /********************************************************************************* * 【函 数 名】: void send_cmd(unsigned char dat) * 【功 能】: 串口发送数据命令 **********************************************************************************/ void send( unsigned char dat ) { TXREG = dat; while ( TRMT != 1 ) ; /* 等待发送完成 */ } /********************************************************************************* * 【函 数 名】: Print_Str(unsigned char *s) * 【功 能】: 串口发送 一个字符串 **********************************************************************************/ void Print_Str( unsigned char *s ) { while ( *s != '