lcd时钟文档.docx
- 文档编号:25817236
- 上传时间:2023-06-15
- 格式:DOCX
- 页数:21
- 大小:110.92KB
lcd时钟文档.docx
《lcd时钟文档.docx》由会员分享,可在线阅读,更多相关《lcd时钟文档.docx(21页珍藏版)》请在冰豆网上搜索。
lcd时钟文档
1602液晶实现时间调整和显示功能
1、运行环境:
stc89c52、通用1602液晶
2、功能:
时分秒年月日星期显示和调整
3、原理图
4、设计思路:
摁下s1后实现调时功能,s2加一,s3减1;若s1没按下,s2、s3摁下无效。
S1摁下,如不调时,s1摁下8次后,时钟正常走动。
5、程序
//160216字符2行
//显示设置0x38设置1602显示,5X7点阵,8位数据接口
//显示开/关以及光标设置
//00001DCBD=1开显示,D=0关显示
//C=1显示光标,C=0不显示光标
//B=1光标闪烁B=0光标不闪烁
//显示开且光标闪烁指令0x0f;显示开不显示光标指令0x0c;
//显示开光标显示但光标不闪烁指令0x0e;
//000001NSN=1当读或写一个字符后地址指针加一,且光标加一
//N=0当读或写一个字符后地址指针减一,且光标减一
//S=1当写一个字符,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果
//S=0当写一个字符后,整屏显示不移动
//向右写字符且屏幕不移动指令0x06;
//向左写字符且屏幕不移动指令0x04;
//数据指针设置80H+地址码(0-27H,第一行),(40H-67H,第二行)
//01H显示清屏:
1、数据指针清零
//2、所有显示清零
//02H显示回车:
1、数据指针清零
//光标或显示移动0001(S/C)(R/L)**
//00光标向左移动,AC自动减1指令0x10
//01光标向右移动,AC自动加1指令0x14
//10光标和显示一起向左移动指令0x18
//
/**************************************************************************************
液晶初始显示2011-01-01MON/23:
59:
49
液晶不中断计时99年
液晶需外接电源,最好加电池,具体电路自行设计
液晶断电后,时间回到初始值,若正常显示需重新调整时间
s1是功能键,摁下调时;s2是加键,s3是减键,摁下实现加减操作
此程序只有一个功能,既是时间调整和显示,如需加定时、报时、计数、闹钟等功能自行随意更改!
*****************************************************************************************/
#include
#include
typedefunsignedcharuchar;
typedefunsignedintuint;
sbitlcde=P2^7;
sbitrs=P2^6;//数据/命令选择端(H/L)
sbitrw=P2^5;//读写选择端(H/L)
sbits1=P2^4;
sbits2=P2^3;
sbits3=P2^2;
ucharcodetab1[]={"2011-01-01MON"};
ucharcodetab2[]={"23:
59:
49"};
ucharcodetab3[7][3]={{'M','O','N'},{'T','U','E'},{'W','E','D'},{'T','H','U'},{'F','R','I'},{'S','A','T'},{'S','U','N'}};
ucharcodetab4[]={31,28,31,30,31,30,31,31,30,31,30,31};
ucharnum,cunt;
charsec,min,hou;
charyea,mon,day,wee;
chari;
ucharj;
uchars1num;
voiddelay(ucharz);
bitlcd_bz();
voidwrite_cmd(ucharcmd);
voidwrite_dat(uchardat);
voiddsprfhline2(ucharadd,uchardat);
voiddsprfhline1(ucharadd,uchardat);
voidkeyscan();
voidtrfh();
/************************
函数初始化
************************/
voidinit()
{
write_cmd(0x38);//液晶显示方式设置
delay(15);
write_cmd(0x0c);//开显示,不显示光标
delay(15);
write_cmd(0x06);//写设置
delay(15);
write_cmd(0x01);//清屏
delay(15);
write_cmd(0x80);//设置数据指针00
delay(15);
for(num=0;num { write_dat(tab1[num]); } write_cmd(0x80+0x40); for(num=0;num { write_dat(tab2[num]); } TMOD=0x01;//设置定时器T0,16位计数方式 TH0=(65536-50000)/256;//T0装初值,计时50ms后溢出 TL0=(65536-50000)%256; EA=1;//开总中断 ET0=1;//开定时器T0中断 TR0=1;//启动T0 } /************************************* 主函数 变量初始化 按键检测 实时显示 **************************************/ voidmain() { yea=11;//年月日星期时分秒初始化 mon=1; day=1; wee=0; i=0; j=1; sec=49; min=59; hou=23; s1num=0; init(); delay(255); while (1) { keyscan();//键盘实时检测 trfh();//显示实时更新 } } /********************************** 按键扫描 s1,摁下实现光标移位操作 s2,摁下一次实现加1操作 s3,按下一次实现减1操作 只有当s1摁下时,s2,s3摁下才有效 **********************************/ voidkeyscan() { if(s1==0)//判断s1按键是否按下 { delay(10);//延时去抖动 if(s1==0)//再次检测s1按键是否按下 { while(! s1);//s1按键松手检测 s1num++;//记录s1摁下次数 switch(s1num)//执行移位操作 { case1: //s1第一次按下 //此处用郭天祥老师的话说,一个傻子都能看出来是在进行时间调整 TR0=0;//定时器T0停止计数 write_cmd(0x80+0x40+11);//光标在秒处停留 write_cmd(0x0e);//光标显示但不闪烁 break;//循环结束 case2: write_cmd(0x80+0x40+8);break;//s1第二次按下,光标在分钟处停留 case3: write_cmd(0x80+0x40+5);break;//s1第三次按下,光标在小时处停留 case4: write_cmd(0x80+15);break;//s1第四次按下,光标在星期处摁下 case5: write_cmd(0x80+11);break;//s1第五次按下,光标在日期处停留 case6: write_cmd(0x80+8);break;//s1第六次按下,光标在月份处停留 case7: write_cmd(0x80+5);break;//s1第七次摁下,光标在年份处停留 case8: write_cmd(0x80+0x40+11);//s1第八次按下,光标回到秒钟位置 s1num=0;//s1num计数清零 TR0=1;//定时器T0启动计数 write_cmd(0x0c);//光标不闪烁 break; default: break;//其他的路过 } } } if(s1num! =0)//如果s1摁下 { if(s2==0)//判断s2是否按下 { delay(10);//延时去抖动 if(s2==0)//再次判断s2是否按下 { while(! s2);//s2按键松手检测 switch(s1num)//执行光标所在处的加操作 { case1: //秒加1 sec++; if(sec==60)//秒加到60后清零 sec=0; dsprfhline2(10,sec);//秒显示更新 write_cmd(0x80+0x40+11); break; case2: min++;//分加1 if(min==60)//分加到60后清零 min=0; dsprfhline2(7,min);//分显示更新 write_cmd(0x80+0x40+8); break; case3: hou++;//时加1 if(hou==24)//时加到24后清零 hou=0; dsprfhline2(4,hou);//时显示更新 write_cmd(0x80+0x40+5); break; case4: wee++;//星期加1 if(wee==7)//星期加到7后清零 wee=0; write_cmd(0x80+13);//星期显示更新 for(num=0;num<3;num++) { write_dat(tab3[wee][num]); } write_cmd(0x80+15); break; case5: day++;//天加1 if(day>tab4[i])//天加到对应月份的天数后清零 { day=1; } dsprfhline1(10,day);//天显示更新 write_cmd(0x80+11); break; case6: mon++;//月份加1 i++; if(i==12)//月份加到12后清零 i=0; if(mon==13)//月份计数加到13后清零 mon=1; dsprfhline1(7,mon);//月份显示更新 write_cmd(0x80+8); break; case7: yea++;//年份加1 if(yea==99)//年份加到99后清零 yea=0; dsprfhline1(4,yea); write_cmd(0x80+5);//年份更新 break; default: break; } } } if(s3==0)//判断s3是否按下 { delay(10); { if(s3==0) { while(! s3); switch(s1num)//执行光标位置的减操作 { case1: sec--; if(sec==-1) sec=59; dsprfhline2(10,sec); write_cmd(0x80+0x40+11); break; case2: min--; if(min==-1) min=59; dsprfhline2(7,min); write_cmd(0x80+0x40+8); break; case3: hou--; if(hou==-1) hou=23; dsprfhline2(4,hou); write_cmd(0x80+0x40+5); break; case4: wee--; if(wee==-1) wee=6; write_cmd(0x80+13); for(num=0;num<3;num++) { write_dat(tab3[wee][num]); } write_cmd(0x80+15); break; case5: day--; if(day==0) { day=tab4[i]; } dsprfhline1(10,day); write_cmd(0x80+11); break; case6: mon--; i--; if(i==-1) i=11; if(mon==0) mon=12; dsprfhline1(7,mon); write_cmd(0x80+8); break; case7: yea--; if(yea==-1) yea=99; dsprfhline1(4,yea); write_cmd(0x80+5); break; default: break; } } } } } } /************************************************* 中断服务函数 **************************************************/ voidtimer0()interrupt1 { TH0=(65536-50000)/256;//T0重装初值 TL0=(65536-50000)%256; cunt++;//中断标志加1 } /********************************************* 时间刷新 晶振频率是12MHz 中断20次后秒加1 一分等于60秒 一小时等于60分 一天等于24小时 一周等于7天 一月等于28/30/31天 一年等于12个月/365天 **********************************************/ voidtrfh() { if(cunt==20)//判断是否计时1m { cunt=0;//计时1m后中断标志清零 sec++;//秒加1 if(sec==60)//判断秒是否到了60 { sec=0;//秒清零 min++;//分加1 if(min==60)//判断分是否到了60 { min=0;//分清零 hou++;//时加1 if(hou==24)//判断时是否到了24 { hou=0;//时清零 day++;//天加1 if(day>tab4[i])//判断天是否到了一个月 { day=1;//天等于1 i++;//月标志加1 if(i==12)//判断月标志是否到了12 { i=0;//月标志清零 } } dsprfhline1(10,day);//天显示刷新 wee++;//星期加1 if(wee==7)//判断是否到了一周 { wee=0;//星期清零 } write_cmd(0x80+13);//星期显示刷新 for(num=0;num<3;num++) { write_dat(tab3[wee][num]); } j++;//天标志加1 if(j==365)//判断是否到了365天 { j=0;//天标志清零 yea++;//年加1 dsprfhline1(4,yea);//刷新年显示 } } dsprfhline2(4,hou);//刷新时显示 } dsprfhline2(7,min);//刷新分显示 } dsprfhline2(10,sec);//刷新秒显示 } } /****************************************************** 1602液晶第二行显示刷新函数 add地址 dat数据 *******************************************************/ voiddsprfhline2(ucharadd,uchardat) { ucharshi,ge;//定义局部变量shi,ge shi=dat/10;//dat的十位赋给shi ge=dat%10;//dat的个位赋给ge write_cmd(0x80+0x40+add);//设定数据指针地址 write_dat(0x30+shi);//更新dat write_dat(0x30+ge); } /************************************************ 1602液晶第一行显示刷新函数 *************************************************/ voiddsprfhline1(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_cmd(0x80+add); write_dat(0x30+shi); write_dat(0x30+ge); } /*********************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- lcd 时钟 文档