*日历时钟 * *按K1,进入设置状态 * *按k2,停止闹钟声音 * *按k3,依次进入闹钟功能是否启用,闹钟时,分秒,年,月,日及时间时,分,秒的设置, * *直到退出设置状态 * *按k4,调整是否起用闹钟和调节闹钟时,分,秒,年,月,日,时间的时,分,秒的数字 * *LCD第二排中间显示小喇叭,表示启用闹钟功能,无则禁止闹钟功能 * *(可在调整状态进行设置) * *正常状态,LCD上排最前面显示自定义字符,LCD下排最前面闪动"XUELIN" * *设置状态,LCD上排最前面显示"P",下排最前面在设置闹钟时间时显示"alarm:", * *其它状态显示"time" * *年代变化2000--2099,星期自动转换 * *程序中有自定义字符写入 * //[龙图开发网: http://www.longtoo.com ]
#include #include unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"}; unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月参变数 unsigned char data dis_buf1[16]; //lcd上排显示缓冲区 unsigned char data dis_buf2[16]; //lcd下排显示缓冲区 unsigned char data year,month,date,week;//年、月、日、星期 unsigned char data armhour,armmin,armsec;//闹钟时、分、秒 unsigned char data hour,min,sec,sec100; //时、分、秒、百分之一秒 unsigned char data flag,vkey,skey;//设置状态计数标志、按键先前值、按键当前值 bit alarm; //标识是否启用闹钟,1--启用,0--关闭 sbit rs = P2^0; //LCD数据/命令选择端(H/L) sbit rw = P2^1; //LCD读/写选择端(H/L) sbit ep = P2^2; //LCD使能控制 sbit PRE = P1^6; //调整键(k3) sbit SET = P1^7; //调整键(k4) sbit SPK = P3^7; void delayms(unsigned char ms); //延时程序 bit lcd_busy(); //测试LCD忙碌状态程序 void lcd_wcmd(char cmd); //写入指令到LCD程序 void lcd_wdat(char dat); //写入数据到LCD程序 void lcd_pos(char pos); //LCD数据指针位置程序 void lcd_init(); //LCD初始化设定程序 void pro_timedate(); //时间日期处理程序 void pro_display(); //显示处理程序 void pro_key(); //按键处理程序 void time_alarm(); //定时报警功能(闹钟) unsigned char scan_key(); //按键扫描程序 unsigned char week_proc(); //星期自动计算与显示函数 bit leap_year(); //判断是否为闰年 void lcd_sef_chr(); //LCD自定义字符程序 void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s); //更新显示缓冲区函数
// 延时程序 void delay(unsigned char ms) { while(ms--) { unsigned char i; for(i = 0; i< 250; i++) { _nop_(); //执行一条_nop_()指令为一个机器周期 _nop_(); _nop_(); _nop_(); } } }
//测试LCD忙碌状态 bit lcd_busy() { bit result; rs = 0; rw = 1; ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); result =(bit)(P0&0x80); //LCD的D0--D7中,D7=1为忙碌,D7=0为空闲 ep = 0; return result; }
//写入指令到LCD void lcd_wcmd(char cmd) { while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写指令 rs = 0; rw = 0; ep = 0; _nop_(); _nop_(); P0 = cmd; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; }
//写入数据到LCD void lcd_wdat(char dat) { while(lcd_busy()); //当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写数据 rs = 1; rw = 0; ep = 0; P0 = dat; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; }
//LCD数据指针位置程序 void lcd_pos(char pos) { lcd_wcmd(pos|0x80); //数据指针=80+地址码(00H~27H,40H~67H) }
//[龙图开发网: http://www.longtoo.com ] //设定二个自定义字符,(注意:LCD1602中自定义字符的地址为0x00--0x07,即可定义8个字符) //这里我们设定把一个自定义字符放在0x00位置(000),另一个放在0x01位子(001) void lcd_sef_chr() { //第一个自定义字符 lcd_wcmd(0x40); //"01 000 000" 第1行地址 (D7D6为地址设定命令形式 |