lcd时钟文档.docx

上传人:b****9 文档编号:25817236 上传时间:2023-06-15 格式:DOCX 页数:21 大小:110.92KB
下载 相关 举报
lcd时钟文档.docx_第1页
第1页 / 共21页
lcd时钟文档.docx_第2页
第2页 / 共21页
lcd时钟文档.docx_第3页
第3页 / 共21页
lcd时钟文档.docx_第4页
第4页 / 共21页
lcd时钟文档.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

lcd时钟文档.docx

《lcd时钟文档.docx》由会员分享,可在线阅读,更多相关《lcd时钟文档.docx(21页珍藏版)》请在冰豆网上搜索。

lcd时钟文档.docx

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);

}

/*********************

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文学研究

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1