基于单片机的多功能电子钟设计(Proteus仿真,程序)_第1页
基于单片机的多功能电子钟设计(Proteus仿真,程序)_第2页
基于单片机的多功能电子钟设计(Proteus仿真,程序)_第3页
基于单片机的多功能电子钟设计(Proteus仿真,程序)_第4页
基于单片机的多功能电子钟设计(Proteus仿真,程序)_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、#inelude#defineucharunsignedchar#defineuintunsignedint#defineleddataPO#definereadalarmsecond0 xc7定义从DS1302中读闹钟秒值的命令字节.#definewritealarmsecond0 xc6定义往DS1302中写闹钟秒值的命令字节.#definereadalarmminute0 xc5定义从DS1302中读闹钟分值的命令字节.#definewritealarmminute0 xc4定义往DS1302中写闹钟分值的命令字节.#definereadalarmhour0 xc3定义从DS1302中读

2、闹钟小时值的命令字节.#definewritealarmhour0 xc2定义往DS1302中写闹钟小时值的命令字节.sbitlcdrs=P2AO;/LCD数据/命令选择端(H/L)sbitlcdrw=P2Al;/LCD读/写选择端(H/L)sbitlcden=P2A2;/LCD使能控制sbitDQ=P3A4;蜂鸣器控制端sbitbeep=P2A3;sbitkmenu=P3A0;功能键sbitkup=P3Al;增人键sbitkdown=P3A2;减小键sbitkalarm=P3A3;闹钟查看键sbitdsclk=PlAl;/dsl3O2的时钟信号端sbitdsdata=PlAO;/dsl3O2

3、的数据I/O端sbitdsrst=PlA2;/dsl3O2的复位端sbitACC7=ACCA7;定义累加器的最高和最低位。sbitACC0=ACCA0;bitflagalarm,flagseta,flagset;/分别定义闹钟响标志位,闹钟设置标志位,和时间设置标志位.ucharkmenunum,s,m,h;功能键被按次数的计数器.charsecond,minute,houi;year;month,day,week;ucharinittime7=0 x00z0 x00,0 xl6,0 x01,0 x05,0 x07,0 x11;初始化后设置为:年5月1口星期口,16点0分0秒,从左往右的数据依

4、次是,秒,分,时,口,月,星期,年。ucharcodetl=,20-;液晶固定显示部分。ucharcodet2=N:ucharcodet3=nCL0CKALARM:11;各函数声明.voiddelay(uintz);亳秒级延时函数。voiddi();蜂鸣器发声函数。voidwritecom(ucharcom);液晶写命令函数。voidwritedata(uchardat);液晶写数据函数。voidwritetime(ucharaddzchardat);/液晶刷新时分秒。voidwritenyr(ucharaddzchardat);液晶刷新口期。voidwriteweek(charweek);/

5、液晶星期几显示函数。voidkeyscan();/键盘打描函数。voiddswritebyte(uchard);/往DS1302写入一个字节。uchardsreadbyte();/从DS1302读出一个字节。voiddswrite(ucharadd,uchardat);向DS1302的指定地址写入一个字节。uchardsread(ucharadd);从DS1302的指定地址读出一个字节.voidinitl302time(uchar*pClock);/DS1302时间初始化函数.voidinit();初始化函数。dsl8b20_delay(ucharxus);延时xusvoidwrite_one

6、char(uchardat);向18B20写一字节ucharread_onechar();从18B20读一字节uintread_wendu();/DS18B20读温度voidwendu_desplay(uintdat);/温度值送液晶显示函数voiddelay(uintz)亳秒级延时函数。uintx,y;for(x=z;x0;x-)for(y=110;y0;y-);dsl8b20_delay(ucharxus)延时xuswhile(xus-);voiddsl8b2OJnit()/DS18B2O初始化ucharx=0;DQ=1;dsl8b20_delay(8);DQ=0;dsl8b20_dela

7、y(80);DQ=1;dsl8b20_delay(14);x=DQ;dsl8b20_delay(20);voidwrite_onechar(uchardat)写一字节uchari;for(i=8;i0;i-)DQ=O;if(dat&0 x01=0 x01)DQ=1;elseDQ=O;dsl8b20_delay(5);DQ=1;dsl8b20_delay(l);dat=l;ucharread_onechar()读一字节ucharvalue=O,i;for(i=8;i0;i-)value=l;DQ=O;dsl8b20_delay(l);DQ=1;if(DQ=l)value|=0 x80;elsev

8、alue&二0 x7f;dsl8b20_delay(4);returnvalue;uintread_wendu()/DS18B20读温度uchara=O,b=O;uintwen=OxOOOO;dsl8b20_init();初始化write_onechar(Oxcc);/跳过读序号列号的操作write-onechar(0 x44);/启动温度转换dsl8b20_delay(150);dsl8b20_init();初始化write_onechar(Oxcc);跳过读序号列号的操作前两个就是温write_onechar(Oxbe);读取温度寄存器等(共可读9个寄存器)度dsl8b20_delay(1

9、50);b=read_onechar();读取温度值低位a=read_onechar();读取温度值高位wen=a;wen=(wen8)|b;returnwen;voidwendu_desplay(uintdat)温度转换后送显示floattemp;unsignedchartemp_shiztemp_ge,temp_shu;temp=dat*0.625;/dat*0.0625*10temp_shi=temp/100;取十位temp除不用定义类型temp_ge=(uint)temp)%100/10;取个位temp求模要定义类型,为16位,故定义uinttemp_shu=(uint)temp)%1

10、00%10;/取小数writecom(0 x80+0 x40+10);送显示writedata(0 x30+temp_shi);writedata(0 x30+temp_ge);writedata(0 x2e);writedata(0 x30+temp_shu);writedata(Oxdf);温度符号writedata(0 x43);voiddi()蜂鸣器发声函数。beep=O;delay(lOO);beep=l;voidwritecom(ucharcom)液晶写命令函数。lcden=0;lcdrw=0;lcdrs=O;lcddata=com;delay(3);lcden=l;delay(3

11、);lcden=0;voidwritedata(uchardat)液晶写数据函数。lcden=0;lcdrw=0;lcdrs=l;lcddata=dat;delay(3);lcden=l;delay(3);lcden=0;voidwritetime(ucharaddzchardat)液晶刷新时分秒。0为时的开始位置,3为分,6为秒。charshi,ge;shi=dat/10;ge=dat%10;writecom(0 x80+0 x40+add);writedata(0 x30+shi);writedata(0 x30+ge);voidwritenyr(ucharadd,chardat)液晶刷新

12、日期。2为年,5为月,8为口。charshi,ge;shi=dat/10;ge=dat%10;writecom(0 x80+add);writedata(0 x30+shi);writedata(0 x30+ge);voidwriteweek(charweek)液晶星期几显示函数。writecom(0 x80+12);switch(week)case1:writedataCMdelay;writedata(O);delay(5);writedataCN);break;case2:writedata(T);delay;writedata(U);delay(5);writedataCE);brea

13、k;case3:writedataCWdelay;writedata(E);delay(5);writedata(D);break;case4:writedata(T);delay;writedata(H,);delay(5);writedata(U);break;case5:writedata(F);delay(5);writedata(R);delay(5);writedata(T);break;case6:writedata(S);delay(5);writedata(A);delay(5);writedata(T);break;case7:writedata(S);delay;writ

14、edata(U);delay(5);writedataCN);break;voidkeyscan()键盘打描函数。uchari;if(flagalarm=l)如果闹钟在响,任意键停止闹钟响。if(kmenu=0)|(kup=O)|(kdown=0)|(kalarm=0)delay;if(kmenu=0)|(kup=O)|(kdown=0)|(kalarm=0)while(!(kmenu&kup&kdown&kalarm);di();flagalarm=O;/清除闹钟标志。if(kmenu=0)检测功能键。delay(4);if(kmenu=0)kmenunum+;/记录功能键按下次数。if(f

15、lagseta=l)/检测是否在进行闹钟设置。if(kmenunum=4)kmenunum=l;/因为进行闹钟设置时,只调节时分秒,所以,kmenunum只能等于1,2,3。flagset=l;/设置标志位,表示在进行各种时间设置。while(!kmenu);di();switch(kmenunum)定位光标闪烁点。case1:writecom(0 x80+0 x40+7);/秒闪烁。writecom(OxOf);/开光标闪烁。break;case2:writecom(0 x80+0 x40+4);/分闪烁。break;case3:writecom(0 x80+0 x40+l);/时闪烁。br

16、eak;case4:writecom(0 x80+12);星期闪烁.break;case5:writecom(0 x80+9);口闪烁.break;case6:writecom(0 x80+6);月闪烁.break;case7:writecom(0 x80+3);年闪烁.break;case8:kmenunum=0;writecom(OxOc);/取消光标闪烁。flagset=O;取消时间调节标志。dswrite(0 x8ez0 x00);厂允许写操作*/dswrite(0 x80,second/10*16+second%10);退出时间设置功能时,往DS1302dswrite(0 x82/m

17、inute/10*16+minute%10);中保存所有时间变量的值。dswrite(0 x84,hour/10*16+hour%10);dswrite(0 x8a,week/10*16+week%10);dswrite(0 x86,day/10*16+day%10);dswrite(0 x88,month/10*16+month%10);dswrite(0 x8c/year/10*16+year%10);dswrite(0 x8e,0 x80);厂禁止写操作*7break;if(kmenunum!=O)只有当功能键按下时才检测增人,减小键.if(kup=O)delay(2);if(kup=O

18、)while(ikup);di();switch(kmenunum)根据功能键被按下的次数,调节相应数值。case1:second+;讦(second=60)second=0;writetime(7,second);writecom(0 x80+0 x40+7);/因为,上面送液晶显示break;一次,光标后移一位,所以要将光标复位.case2:minute+;if(minute=60)minute=0;writetime(4,minute);writecom(0 x80+0 x40+4);break;case3:hour+;if(hour=24)hour=0;writetime(l,hour

19、);writecom(0 x80+0 x40+l);break;case4:week+;if(week=8)week=l;writeweek(week);writecom(0 x80+12);break;case5:day+;if(day=32)day=l;writenyr(9,day);writecom(0 x80+9);break;case6:month+;if(month=13)month=l;writenyr(6,month);writecom(0 x80+6);break;case7:year+;if(year=100)year=O;writenyr(3,year);writecom

20、(0 x80+3);break;if(kdown=0)delay(2);if(kdown=0)while(lkdown);di();switch(kmenunum)根据功能键被按次数调节相应数值.case1:second;if(second=-l)second=59;writetime(7,second);writecom(0 x80+0 x40+7);break;case2:minute-;if(minute=-l)minute=59;writetime(4,minute);writecom(0 x80+0 x40+4);break;case3:hour-;讦(hour=-l)hour=23

21、;writetime(l,hour);writecom(0 x80+0 x40+l);break;case4:week-;讦(week=0)week=7;writeweek(week);writecom(0 x80+12);break;case5:day-;if(day=0)day=31;writenyr(9,day);writecom(0 x80+9);break;case6:month-;讦(month=O)month=12;writenyr(6,month);writecom(0 x80+6);break;case7:year-;讦(year=-l)year=99;writenyr(3,

22、year);writecom(0 x80+3);break;if(kalarm=O)/检测闹钟调节键是否按卜,此条if语句与if(kmenunum!=O)在同一个层次。delay(2);if(kalarm=O)flagseta=flagseta;while(!kalarm);di();if(flagseta=O)此时,退出闹钟设置,保存各相关数值。flagset=O;/清除时间设置标志,在if(kalarm=O)这个if语句writecom(0 x80+0 x40);中,不用flagset=l这条语句来设置/flagset标志位,因为,如果进行了闹钟时间的设置,就会执行前面if(kmenunu

23、m=O)语句中的flagset=l这条语句。writedata();清除液晶上的“Ri”闹钟调节标志。/writedata(H);/*for(i=0;i0;i-)dsdata=ACCO;dsclk=1;为什么这里时钟先为1后为0,因为dsclk初始化为0,而,每次循环最后,都将其置0,这样就形成一个从0开始的上升沿,恰好满足dsl302写数据在上升沿,但是,时钟必须从0开始的要求.dsclk=0;ACC=ACC1;uchardsreadbyte()/从DS1302读出一个字节。uchari;for(i=&i0;i-)ACC=ACC1;ACC7=dsdata;dsclk=1;读数据也一样,虽然是

24、下降沿,但是,也要从0开始.这样设置dsclk刚好满足要求。dsclk=0;returnACC;voiddswrite(ucharadd,uchardat)向DS1302的指定地址写入一个字节。dsrst=0;dsclk=0;dsrst=1;dswritebyte(add);/*先写入地址,命令字节*/dswritebyte(dat);/*再写lByte数据*/dsclk=1;dsrst=0;uchardsread(ucharadd)从DS1302的指定地址读出一个字节.uchardat;dsrst=0;dsclk=0;dsrst=1;dswritebyte(add);/*先写入地址,命令字节

25、*/dat=dsreadbyte();/*再读lByte数据*/dsclk=l;dsrst=0;returndat;voidinitl302time(uchar*pClock)/DS1302时间初始化函数.uchari;ucharadd=0 x80;dswrite(0 x8e,0 x00);厂允许写操作*7for(i=7;i0;i_)dswrite(add,*pClock);厂依次写入秒分时日月星期年*/pClock+;add+=2;/因为DS1302同一个时钟寄存器占两个地址,最低位为0,是用于写的地址,最低位为1,是用于读的地址所以add加2.dswrite(0 x8e,0 x80);厂禁

26、止写操作庁/voidinit()/初始化函数。ucharnum;变量初始化.flagset=O;/时间设置标志位置0,表示未进行时间设置flagseta=O;闹钟设置标志位置0.flagalarm=0;/闹钟标志位置0.kmenunum=0;/功能键被按次数计数器置0.lcden=0;/液晶使能端置6液晶能够工作了./DS1302初始化。dswrite(0 x8e,0 x00);/*允许写操作字/dswrite(writealarmsecond,0);/往DS1302中保存闹钟的初始时分秒值。dswrite(writealarmminute,O);dswrite(writealarmhour,

27、0);dswrite(0 x8e,0 x80);厂禁止写操作戶/dswrite(0 x8e,0 x00);/*允许写操作字/dswrite(0 x80,0 x00);/打开DS1302晶振,使其开始工作。dswrite(0 x84,0 x00);/设置为24小时制。initl302time(inittime);/初始化时间为:年5月1口星期口,16点0分0秒,从左往右的数据依次是,秒,分,时,口,月,星期,年。dswrite(0 x8e,0 x80);严禁止写操作車/1602液晶初始化。writecom(0 x38);writecom(OxOc);writecom(0 x06);writecom(OxOl);writecom(0 x80);for(num=0;num16;num+)写入液晶固定显示部分。writedata(tlnum);delay(l);writecom(0 x80+0 x40);/换到液晶第二行。for(num=0;num16;num+)writedata(t2num);delay(l);vo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论