与数字中的数码管显示类似, 增加: 液晶初始化部分 写命令部分 写数据部分 ******************************************************************** ********************************************************************* #include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit rs = P2^6; //1602相应 sbit rw = P2^5; sbit ep = P2^7; uchar hour,min,sec,k; uchar key; unsigned char lcdd[]="0123456789"; uchar key_code[] = {0xb7,0xbb,0xbd,0xbe};//键盘编码,我只用到四个键。 你我的编码可能不同 ,具体看电路如何连接。 void delay(uint z) { uint x,y; for(z=x;x>0;x--) for(y=100;y>0;y--); } bit lcd_bz() { // 测试LCD忙碌状态 bit result; rs = 0; rw = 1; ep = 1; delay(5); result = (bit)(P0 & 0x80);//判断P0^7是一还是零.屏蔽掉其它位0x80.强制转换位bit型数据。在返回给result。 ep = 0; return result; } void lcd_cmd(uchar cmd) { while(lcd_bz()); rs = 0;//rs为1时写入的是“数据”为0时写入“指令” rw = 0;//rw为1时“读取”为0时“写入” ep = 0;//使能 delay(5); P0 = cmd; delay(5); ep = 1; delay(5); ep = 0; } void lcd_data(uchar dat )//液晶写数据 { while(lcd_bz()); rs=1; rw=0; ep=0; P0 = dat; delay(5); ep = 1; delay(5); ep = 0; //return dat; } void lcd_init() //液晶写命令 { delay(15); //等待LCD电源稳定 lcd_cmd(0x38); delay(10); lcd_cmd(0x38); delay(10); lcd_cmd(0x38); delay(10); lcd_cmd(0x0c); //显示开,关光标 delay(10); lcd_cmd(0x06); //移动光标 delay(10); lcd_cmd(0x01); //清除LCD的显示内容 delay(10); } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; k++; if(k==20) { k=0; sec++; } if(sec>59) { min++; sec=0; } if(min>59) { min=0; hour++; } if(hour>23) { hour=0; } } void disptime() //时间显示函数 { lcd_cmd(0x0c); //设置光标不显示、不闪烁 delay(20); lcd_cmd(0x80); //起始显示地址 delay(20); lcd_data(lcdd[hour/10]); delay(10); lcd_data(lcdd[hour%10]); delay(10); lcd_data(':'); delay(12); lcd_data(lcdd[min/10]); delay(10); lcd_data(lcdd[min%10]); delay(12); lcd_data(':'); delay(12); lcd_data(lcdd[sec/10]); delay(12); lcd_data(lcdd[sec%10]); delay(12); lcd_data(' '); delay(12); } uchar keyscan() //键盘扫描程序 { uchar scan1, scan2, keycode, j; P1 = 0xf0; scan1 = P1; if (scan1 != 0xf0) //判键是否按下 { delay(10); //延时10ms scan1 = P1; if (scan1 != 0xf0) //二次判键是否按下 { TR0=0; //如果有键按下 则定时器停止工作 P1 = 0x0f; scan2 = P1; keycode = scan1 | scan2; //组合成键扫描编码 for (j = 0; j < 4; j++) { if (keycode == key_code[j]) //查表得键值 { key = j; while(P1!= 0x0f) //松手有效 这里需要好好研究一下 可以用万用表测量管脚电压帮助理解 disptime(); return (key); //返回有效键值 } } } } else P1 = 0xff; return (key = 4); //返回无效码 } void Set_time(uchar key) { if(key==0||key==1||key==2)//若s1,s2,s3其中有键按下,则为真 { if(key==0) { sec++; if(sec>59) { sec=0; } } else if(key==1) { min++; if(min>59) { min=0; } } else if(key==2) { hour++; if(hour>23) { hour=0; } } } else if(key==3) { TR0=1; //按下退出键 定时器继续工作 } } void sysint() //定时器初始化 { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } void timeint() //初始化 { hour=0; min=0; sec=0; } void main() { sysint() ; timeint(); lcd_init();//函数调用 while(1) { keyscan();//调用键盘扫描, Set_time(key); disptime(); } }