通过测试的1602显示程序 #include <c8051f330.h> // SFR声明 #include <intrins.h> #include <string.h> typedef unsigned char uint8; // 无符号8 位整型变量 // //----------------------------------------------------------------------------- // 全局常量 引脚定义 // //----------------------------------------------------------------------------- sbit LCD1602_RS = P1^2; // 定义LCD1602 的RS 控制线 sbit LCD1602_E = P1^0; // 定义LCD1602 的E 控制线 sbit stop = P1^7; sbit dec = P1^6; sbit inc = P1^5; sbit enter = P1^4; sbit BUZZER = P0^5;
//----------------------------------------------------------------------------- // 定义1602 指令集 //----------------------------------------------------------------------------- #define LCD_clear 0x01 // 清除屏幕 #define LCD_back 0x02 // DDRAM回零位 #define LCD_dec1 0x04 // 读入后AC(指针)减1,向左写 #define LCD_add1 0x06 // 读入后AC(指针)加1,向右写 //光标不动字符右移0x05 //光标不动字符左移0x07 #define LCD_dis_gb1 0x0f // 开显示_开光标_光标闪烁 #define LCD_dis_gb2 0x0e // 开显示_开光标_光标不闪烁 #define LCD_dis_gb3 0x0c // 开显示_关光标_光标不闪烁 #define LCD_OFF_dis 0x08 // 关显示_关光标_光标不闪烁 #define LCD_dis_rl 0x18 //画面右移 #define LCD_dis_rr 0x1c //画面左移 #define LCD_gb_rl 0x10 //光标左移 #define LCD_gb_rr 0x14 //光标右移 #define LCD_set82 0x38 // 8 位总线_2 行显示 #define LCD_set81 0x30 // 8 位总线_1 行显示(上边行) #define LCD_set42 0x28 // 4 位总线_2 行显示 #define LCD_set41 0x20 // 4 位总线_1 行显示(上边行) #define lin_1 0x80 // 上边行起始地址 #define lin_2 0xc0 // 下边行起始地址 //********************************************************************************************/ //----------------------------------------------------------------------------- // 声明函数原型 //----------------------------------------------------------------------------- void SYSCLK_Init (void); void PORT_Init (void); void LCD1602_Init(void); void LCD1602_WriteData (uint8 LCD1602_data); void LCD1602_WriteCMD (uint8 LCD1602_command); void LCD1602_WriteData (uint8 LCD1602_data); void print(uint8 a,uint8 *str); void Delay_5t (void); void delay_nop(void); //---------------------------------------------------------- // 系统时钟初始化 // 此程序初始化系统时钟使用80KHz内部时钟源2分频 //---------------------------------------------------------- void SYSCLK_Init (void){ OSCICN = 0XC0 ; //内部高频时钟8分频 OSCLCN = 0XC2 ; //内部低频时钟2分频,40KHz } //---------------------------------------------------------- // IO口初始化 // 配置数据交叉开关和通用IO口 //---------------------------------------------------------- void PORT_Init (void) { XBR0 = 0x00; //交叉开关0,复位全0,以后根据实际置需要位为1 XBR1 = 0x40; // 使能数据交叉开关和弱上拉 //P0MDIN = 0x10; //P0只有LED端配置为输出 P0MDOUT = 0x00; // 使能P0.4(LED)为推挽输出 //P1MDIN = 0x00; //P1模拟输入配置,默认为关 P1MDOUT = 0x00; } /********************************************************************************************/ //----------------------------------------------------------------------------- // LCD1602初始化 //----------------------------------------------------------------------------- void LCD1602_Init(void){
LCD1602_WriteCMD(LCD_clear); // 显示清屏
LCD1602_WriteCMD(LCD_back); // 数据指针指向第1 行第1个字符位置
LCD1602_WriteCMD(LCD_set42); // 显示模式设置:4位数据线,显示2行 LCD1602_WriteCMD(LCD_dis_gb3); // 显示开及光标设置:显示开,光标关,闪烁关 LCD1602_WriteCMD(LCD_add1); // 显示光标移动设置:文字不动,光标右移
//CgramWrite(); // 向CGRAM写入自定义字符 } /********************************************************************************************/ //----------------------------------------------------------------------------- // 写指令程序 // 向LCD1602 写命令 本函数需要1 个指令集的入口参数 //----------------------------------------------------------------------------- void LCD1602_WriteCMD(uint8 LCD1602_command) { uint8 temp; Delay_5t (); //delay_nop(); //delay_nop(); //delay_nop(); //delay_nop(); LCD1602_RS = 0;
temp = LCD1602_command; temp=temp>>4; LCD1602_E = 1; P0 &= 0x0F0; P0|= temp & 0x0F; LCD1602_E = 0;
LCD1602_E = 1; P0&= 0x0F0; P0 |= LCD1602_command & 0x0F; LCD1602_E = 0; } //----------------------------------------------------------------------------- // 写数据程序 // 向LCD1602 写数据 //----------------------------------------------------------------------------- void LCD1602_WriteData(uint8 LCD1602_data){ uint8 temp; Delay_5t (); LCD1602_RS = 1;
temp = LCD1602_data; temp=temp>>4; LCD1602_E = 1; P0 &= 0x0F0; P0 |= temp & 0x0F; LCD1602_E = 0;
LCD1602_E = 1; P0 &= 0x0F0; P0 |= LCD1602_data & 0x0F; LCD1602_E = 0; } //----------------------------------------------------------------------------- // Timer_Delay //----------------------------------------------------------------------------- // // 配置定时器T0延时. // void Delay_5t (void){ int i; for(i=0;i<5;i++); } //----------------------------------------------------------------------------- void delay_nop(void){ //1us延时函数 _nop_(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Timer0_Delay //----------------------------------------------------------------------------- // // 配置定时器T0延时. // void Timer0_Delay (void)interrupt 1 using 1{ BUZZER =0; TR0 = 0; TH0 = (65536-10000)/256; // 设置定时器T0 200ms溢出 TL0 = (65536-10000)%256; // } //********************************************************************************************/ // 打印字符串程序 // (本函数调用指针函数) // 向LCM 发送一个字符串,长度48 字符之内 // 第一行位置 0x00~0x10 第二行位置 0x40~0x50 // 应用举例:print(0x80,"doyoung.net"); //在第一行第一位处从左向右打印doyoung.net字符串 //********************************************************************************************/ void print(uint8 a,uint8 *str){ LCD1602_WriteCMD(a | 0x80); while(*str != '\0'){ LCD1602_WriteData(*str++); } *str = 0; } //**********************************************************// // 主程序 //**********************************************************// void main (void) { uint8 i; uint8 j; bit f; PCA0MD = 0x80; // 禁止看门狗定时器 SYSCLK_Init (); // 初始化振荡器 PORT_Init (); // 初始化数据交叉开关和通用IO口
CLKSEL=0x02;//系统时钟切换 delay_nop(); delay_nop(); delay_nop(); delay_nop(); OSCICN=0X00;//关高频时钟 CKCON = 0x08; // 定时器T0计数系统时钟 TMOD = 0x01; // 定时器T0工作方式1 BUZZER=1; EA = 1; ET0 = 1; for(i=0;i<250;i++); LCD1602_Init(); print(0x00," Myself charge "); print(0x40," INPUT 00.00V "); BUZZER=0; f = 0; while(1){ if(enter==0){ //discharge BUZZER=1; TR0=1; print(0x00,"Li-Po charge "); print(0x40,"0.00A 3S(4.19V)"); } if(stop==0){ BUZZER=1; //discharge TR0=1; print(0x00," Ni-MH charge "); print(0x40," 8cell 0.10A "); } if(f==1){ print(0x49," "); } else{ print(0x49,"0.00V"); }; for(j=0;j<10;j++){ for(i=0;i<250;i++); } f=!f; } } |