基于单片机的万年历设计_第1页
基于单片机的万年历设计_第2页
基于单片机的万年历设计_第3页
基于单片机的万年历设计_第4页
基于单片机的万年历设计_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

1、基于单片机的万年历设计二、实验要求设计一个万年历,将时钟显示在 LCD1602的显示屏上并且可以进行年、月、 日以及时、分、秒的设置。此外还可以通过按键进行闹钟设置以及事件提醒功能, 用蜂鸣器进行闹铃提醒。最后附加一个温湿度检测的功能,用温湿度传感器检测 室内的温湿度并将温湿度数据在显示屏上显示出来。三、实验设备和仪器1. 用STC89C52芯片作为系统板的主控芯片2. DHT11温湿度传感器3. DS1302时钟芯片4丄CD1602显示屏四、实验各模块原理介绍4.1 STC89C52 单片机STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具 有8K字节系统可编程Fl

2、ash存储器。STC89C52使用经典的MCS-51内核,具有 传统51单片机不具备的功能。在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的 解决方案。(1)主要特性8K字节程序存储空间;512字节数据存储空间;内带4K字节EEPROM存储空间;可直接使用串口下载;(2)器件参数1. 增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意选择, 指令代码完全兼容传统8051。2. 工作电压:5.5V3.3V (5V单片机)/3.8V2.0V (3V单片机)3. 工作频率范围:040MHz,相当于普通8051的

3、080MHz,实际工作频 率可达48MHz4. 用户应用程序空间为8K字节5. 片上集成512字节RAM6. 通用I/O 口(32个),复位后为:P1/P2/P3是准双向口 /弱上拉,P0 口是 漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为 I/O 口用时,需加上 拉电阻。7. ISP (在系统可编程)/IAP (在应用可编程),无需专用编程器,无需专用 仿真器,可通过串口( RXD/P3.0,TXD/P3.1 )直接下载用户程序,数秒即可完 成一片。8. 具有EEPROM功能9. 共3个16位定时器/计数器。即定时器TO、T1、T2。10. 外部中断4路,下降沿中断或低电平触发电路,

4、Power Down模式可由 外部中断低电平触发中断方式唤醒。11. 通用异步串行口( UART),还可用定时器软件实现多个 UART。12. 工作温度范围:-40+85 C(工业级)/075C(商业级)13. PDIP 封装T2 n. 0= = = = = = = = = = =一POADO ra. : AD!PO.2 JlD:PO.M,7AIS FM AH Pl讪】JPS 4 H?P: 3 All曲AiePS VA9P:.O AS1、STC89C5单片机引脚图TZ2!f PL. 1 PL:PL. 3Pl. 4Pl. aPl-6PL 7K5T5 P3 0 讪 P3.1 而t IVTL P3.

5、 Jwn 4Tl_PS. IfT 6 乔P3 7117LL2 iTftLl vss图4.1 STC89C52单片机引脚图 主电源引脚(2根)VCC(Pin40):电源输入,接+5V电源GND(Pi n20):接地线 外接晶振引脚(2根)XTAL1(Pin19):片内振荡电路的输入端XTAL2(Pin20):片内振荡电路的输出端 控制引脚(4根)RST/VPP(Pin9):复位引脚,弓I脚上出现2个机器周期的高电平将使单片机复位ALE/PROG(Pin30):地址锁存允许信号PSEN(Pin29):外部存储器读选通信号EA/VPP(P in 31):程序存储器的内外部选通,接低电平从外部程序存储

6、 器读指令,如果接高电平则从内部程序存储器读指令。可编程输入/输出引脚(32根)STC89C52单片机有4组8位的可编程I/O 口,分别位P0、P1、P2、P3 口,每个口有8位(8根引脚),共32根。PO 口 (Pin39Pin32): 8 位双向 I/O 口线,名称为 P0.0P0.7 P1 口 (Pin1 Pin8): 8位准双向I/O 口线,名称为P1.0P1.7 P2 口 (Pin21Pin28): 8位准双向I/O 口 线,名称为P2.0P2.7 P3口(Pin10Pin 17): 8位准双向I/O 口线,名称为P3.0 P3.7。2、STC89C5单片机最小系统STC89C52单

7、片机最小系统主要由复位电路和时钟电路组成。复位功能通过外部电路来实现,按下按键K1控制单片机的复位。时钟电路主要通过晶振来实 现,为单片机提供运行时钟。根据不同的需求选用的晶振频率会有差异,在本次课程设计中采用11.0592MHZ的晶振频率。单片机复位电路如图 4.2所示,晶振 电路如图4.3所示。图4.2复位电路图4.3晶振电路4.2 DS1302 芯片DS1302是DALLAS公司出的一款实时时钟芯片,它广泛应用于电话、传真、 便携式仪器等产品领域,主要性能指标如下:1、DS1302是一个实时时钟芯片,可以提供秒、分、小时、日期、月、年等信息, 具有软件自动调整的能力,可以通过配置 AM/

8、PM来决定采用24小时格式还是 12小时格式。2、拥有31字节数据存储RAM。3、串行I/O通信方式。4、DS1302的工作电压比较宽,在2.0V5.5V范围内均可正常工作。采用双电源 供电,当主电源比备用电源高 0.2V时,由主电源供电,否则采用备用电源,一 般是一个纽扣电池。5、 DS1302实时时钟芯片的功耗很低,当工作电压为 2.0V时,工作电流小于 300nA。6 DS1302共有8个引脚,有两种封装形式,一种是 DIP-8封装,芯片宽度(不 含引脚)是300mil,一种是SOP-8封装,有两种宽度,一种是150mil,一种是 208mil。(1)DS1302引脚及其功能Vcc2 H

9、E2亍III Vcctxi nr2 g 7HJSCLKX2 :3器6in i/oGND H4 Q 5JLCE图4.4 DS1302芯片引脚图(1)Vcc2:主电源引脚,当 Vcc2比Vcc1高0.2v以上时,DS1302由Vcc2供 电,当Vcc2低于Vcc1时,由Vcc1供电。(2、3)X1、X2 :这两个引脚需要接一个32.768k的晶振,为了给DS1302提供 一个基准。但是该晶振的引脚负载电容必须为 6pF,若使用有源晶振,接到 X1 上即可,X2则悬空。(4)GND :接地(5)CE: DS1302的输入引脚。该引脚内部有一个 40k的下拉电阻,当该引脚 为高电平,对DS1302进行

10、读写。(6) I/O:该引脚是一个双向通信引脚,且内部含有一个40k的下拉电阻,可进 行数据的读写。(7)SCLK :该引脚是输入引脚,且内部含有一个 40k的下拉电阻,作为通信的 时钟信号。(8)Vcc1:备用电源引脚。(2) DS1302与单片机接线图DS1302引脚与单片机接线图如图4.5所示,从图4.5可看出,引脚X1与X2之间接一个32.768K的晶体正振荡器,Vcc1通过一个纽扣能电池再接地。11 亠图4.5 DS1302与单片机连接图4.3 LCD1602液晶显示屏LCD1602液晶屏能够能够同时显示32个字符,价格便宜,编程简单而且稳 定可靠。LCD1602液晶屏是一种图形点阵

11、显示器,显示原理简单易懂,都是液 晶屏内部的液晶材料变化而显示不同的字符,因为液晶是具有流动特性的物质, 所以只需外加很微小的力量即可使液晶分子运动。(1)LCD1602引脚1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接 口图如图4.6所示:图4.6 LCD1602引脚图(a)各个引脚说明1脚:VSS为地电源2脚:VDD接5V正电源3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比对比度过高时会产生“鬼影”,使用时可以通过一个 10K的电位器调整。4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器5脚:R/W为读写信号线,高电平时

12、进行读操作,低电平时进行写操作。当RSR/W共同为低电平时可以写入指令或者显示地址,当RS为低电平,R/W为高电平;RS为高电平,R/W为低电平时可以写入数据。6脚:E端为使能端,当 E端由高电平跳变成低电平时,液晶模块执行命令。714脚:DOD7为8位双向数据线。15脚:背光源正极16脚:背光源负极(b) LCD1602主要技术参数:显示容量:32个字符;芯片工作电压:4.5-5.5V ;工作电流:2.0mA(5.0V);模块最佳工作电压:5.0V ;(2)LCD1602与单片机接线图图4.7 LCD1602与单片机接线图LCD1602与单片机接线图如 4.7所示,背光源正极(5)与VDD

13、( 2)均接电源,将液 晶显示器接地保证对比度最强,可使用一个10K的电位器进行调整。4.4温湿度传感器DHT11DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传 感器。它采用专用的数字模块采集技术、温湿度传感技术,确保产品的可靠性、 长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此,该产品具有品质卓越、超快响应、抗干扰能力 强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程 序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些 校准系数。单线制串行接口,使系统集成变

14、得简易快捷。超小的体积、极低的功 耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合 的最佳选则。产品为4针单排引脚封装,连接方便,特殊封装形式可根据用户需 求而提供。(1) DHT11引脚及其功能DHT11的引脚图如图4.8所示,一般情况下它有四个引脚,分别为:VCC、DOUT、NC、GND。各引脚以及功能如表 4-1所示。图4.8 DHT11引脚图表4-1 DHT11引脚及其功能pin名称注释1VDD供电 3-5.5VDC2DATA串行数据,单总线3NC空脚,请悬空4GND接地,电源负极1.电源引脚DHT11的供电电压为3-5.5V。传感器上电后,要等待1s以越过不稳定

15、状态 在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的 电容,作用在于去耦滤波。2.串行接口(单线双向)DATA是用于微处理器与DHT11之间的通信和同步的串行双向 接口,采用单总线数据格式。每次通信都是以高位先出的顺序传输 40位数据,用时约为4 m& 数据格式为:8位湿度整数数据+8位湿度小数数据+8位温度整数数据+8位温度小数数据 +8位校验和数据。数据分小数部分和整数部分,当前小数部分用于以后扩展, 现读出为零。数据传送正确时,校验和数据等于“8位湿度整数数据+8位湿度小 数数据+8位温度整数数据+8位温度小数数据”所得结果的末 8位。(2) DHT11与

16、单片机接线图DHT11与单片机的接线图如图4.9所示,由图4.9中可看出,DHT11第三个 引脚接单片机的P2.2引脚,第一个引脚接电阻和发光二极管。_Ex图4.9 DHT11与单片机接线图4.5蜂鸣器蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等 电子产品中作发声器件。蜂鸣器可分为无源蜂鸣器和有源蜂鸣器两种,此处我们用到的是有源蜂鸣器。有源蜂鸣器工作的理想信号是直流电,通常标示为VDCVDD等。因为蜂鸣器内部有一简单的振荡电路,能将恒定的直流电转化成一定频 率的脉冲信号,从而带动钼片振动发音。有源蜂鸣器

17、主要靠压电效应的原理来发声的,且内部带有多谐振荡器,可产生1.5-2.5kHZ的电压信号。由此有源蜂鸣器才能发声。有源蜂鸣器在单片机中 的电路图较为简单,图4.10为蜂鸣器与单片机的接线图。图4.10蜂鸣器与单片机的接线图有源蜂鸣器直接接上额定电源就可连续发声,I/O 口输出后接一个1K的电 阻,目的在于基极限流,以低电平方式,启动蜂鸣器发声。五、流程图(1)主程序流程图图5.1是系统主程序流程图,系统开始时先进行初始化,然后再调整时间和 闹钟,再通过串口屏将时间显示出来DS1302子程序流程图开始图5.1主程序流程图(2)子程序流程图系统从主程序开始执行,分别调用各个子程序,其中子程序包括D

18、S1302子程序,DHT11子程序和LCD1602子程序等。(1)DS1302芯片子程序流程图DS1302为实时时钟芯片,可以提供秒、分、时、日、月、年及星期等信息, 具有软件自动调整的能力,可以通过配置AM/PM来决定采用24小时格式还是12 小时格式。从DS1302中可以读出年、月、日、时、分、秒等信息。图5.2为DS1302 芯片的子程序流程图:开始图5.2 DS1302子程序流程图(2) DHT11子程序流程图DHT11为温湿度传感器,可以实时显示环境中的温湿度。其数据由 8位湿 度整数数据,8位湿度小数数据,8位温度整数数据和8位温度小数数据以及8 位校验和数据。DHT11子程序流程

19、图如5.3所示:DHT11子程序流程图开始 结束图5.3 DHT11子程序流程图(3) LCD1602子程序流程图LCD1602显示时,也要先进行初始化,紧接着读指令,读完之后写指令, 再对数据进行读写,然后显示出来,其流程图如图5.4所示。LCD1602子程序库程图开始初始化读写指令读写数据返回图5.4 LCD1602显示屏子程序流程图六、实验目的1. 学会并掌握可keil软件的使用;2. 学会并掌握Altium Designer 软件的使用;3. 实现万年历的基本功能;4. 通过实验巩固单片机相关知识和检验自身动手能力七、实验内容本次实验使用STC89C5洋片机作为主控芯片,使用DS130

20、2芯片作为时钟芯 片,在LCD1602显示屏上显示,并可以设置闹钟和事件提醒功能,此外还可以进 行室内温湿度的检测和显示,最终完成万年历的设计。八、实验步骤1. 查询资料,确定主控芯片、温湿度传感器、时钟芯片以及LCD1602显示屏 的使用说明。2. 根据功能要求进行硬件电路的设计,使用Altium Designer软件设计电路。 整个电路分为主控芯片控制模块、LCD1602显示模块、按键设置模块、蜂鸣器电路模块以及DHT11温湿度传感器模块。硬件电路图如图 1所示:-iieM*3Vi:l定义从DS1302中读闹钟秒值的命令字节 定义往DS1302中写闹钟秒值的命令字节 定义从DS1302中读

21、闹钟分值的命令字节 定义往DS1302中写闹钟分值的命令字节 定义从DS1302中读闹钟小时值命令字节 定义往DS1302中写闹钟小时值命令字节定义从DS1302中读事件提醒日期值的命定义往DS1302中写事件提醒日期值的命定义从DS1302中读事件提醒月份值的命定义往DS1302中写事件提醒月份值的命定义从DS1302中读事件提醒年份值的命定义往DS1302中写事件提醒年份值的命图8.1 :硬件电路图3.根据电路图编写C语言代码: 代码如下:#in elude #defi ne uchar un sig ned char#defi ne uint un sig ned int#defi ne

22、 lcddata P0#defi ne readalarmsec ond 0xc7 /#defi ne writealarmsec ond 0xc6 /#defi ne readalarm minute 0xc5 /#defi ne writealarm minute 0xc4 /#defi ne readalarmhour 0xc3 /#defi ne writealarmhour 0xc2 /#defi ne readeve ntday 0xd7 /令字节#defi ne writeeve ntday 0xd6 /令字节#defi ne readeve ntmonth 0xd5 /令字节#

23、defi ne writeeve ntm on th 0xd4 /令字节#defi ne readeve ntyear 0xd3 /令字节#defi ne writeeve ntyear 0xd2 /令字节sbit lcdrs=P2A7; /LCD数据/命令选择端(H/L)sbit lcdrw=P2A6; /LCD读/写选择端(H/L)sbit lcde n=P2A5; /LCD使能控制sbit beep=P1A3; /蜂鸣器控制端sbit DQ = P1A4;/温湿度传感器sbit kmen u=P3A2; /功能键sbit kup=P3A3; /增大键sbit kdow n=P3A4; /

24、减小键sbit kalarm=P3A5; /闹钟查看键Ring:显示闹钟需要调到的时间sbit keve nt=P3A6; /事件查看键Ding:显示事件提醒需要调到的时间/sbit kmode=P3A7; /切换温湿度显示sbit dsclk=P2A2; ds1302的时钟信号端sbit dsdata=P2A1; ds1302的数据 I/O 端sbit dsrst=P2A0; /ds1302的复位端sbit ACC7=ACCA7; / 定义累加器的最高和最低位。sbit ACC0=ACCA0;bit flagalarm,flagseta,flagset; /分别定义闹钟响标志位,闹钟设置标志

25、位,时间设置标志位bit flagevent,flagsseta;/分别定义事件提醒标志位,事件提醒设置标志位uchar FLAG,k;uchar temp;uchar T_data_H,T_data_L,RH_data_H,RH_data_L,checkdata;ucharT_data_H_temp,T_data_L_temp,RH_data_H_temp,RH_data_L_temp,checkdata_t emp;uchar comdata;uchar kmenunum,s,m,h,dd,mm,yy;/ 功能键被按次数的计数器.char seco nd,mi nute,hour,year

26、,m on th,day,week;uchar inittime7=0x59,0x59,0x11,0x05,0x07,0x04,0x18;/ 初始化后设置为:/2018年7月5日星期四,11点59分59秒,/从左往右的数据依次是,秒,分,时,日,月,星期,年。/ 年月曰星期:2018-07-05 THU/ 时间:11:59:59uchar code t1= - -; /液晶固定显示部分。uchar code t2=:;/各函数声明void delay(ui nt z); /毫秒级延时函数。void di(); /蜂鸣器发声函数。void writecom(uchar com); /液晶写命令函

27、数。void writedata(uchar dat); /液晶写数据函数。void writetime(uchar add,uchar dat); /液晶刷新时分秒。void write ny r(uchar add,uchar dat); /液晶刷新日期。void writeweek(uchar week); / 液晶星期几显示函数。void keysca n(); /键盘扫描函数。void dswritebyte(uchar d);往 DS1302 写入一个字节。uchar dsreadbyte(); / 从 DS1302 读出一个字节。void dswrite(uchar add, u

28、char dat); /向 DS1302 的指定地址写入一个字节uchar dsread(uchar add); / 从DS1302的指定地址读出一个字节void in it1302time(uchar *pClock); /DS1302时间初始化函数void ini t(); /初始化函数void Delay_100us(ui nt j);延时 100usvoid Delay_10us(void); 延时 10usvoid COM(void);void Read_DHT11(void);void delay(ui nt z) /毫秒级延时函数。uint x,y;for(x=z;x0;x_)f

29、or(y=110;y0;y-);void di() /蜂鸣器发声函数。beep=0;delay(100);beep=1;void writecom(uchar com) /液晶写命令函数。lcdrs=0;置为写入命令lcddata=com;送入数据delay(1);lcde n=1;拉高使能端delay(1);lcde n=0;完成高脉冲void writedata(uchar dat) /液晶写数据函数。lcdrs=1; 置为写入数据 lcddata=dat;送入数据delay(1);Icde n=1; delay(1);Icde n=0;void writetime(uchar add,u

30、char dat) /uchar shi,ge;shi=dat/10;ge=dat%10;writecom(0x80+0x40+add);writedata(0x30+shi);writedata(0x30+ge);void write ny r(uchar add,uchar dat) /uchar shi,ge;shi=dat/10;ge=dat%10;writecom(0x80+add);writedata(0x30+shi);writedata(0x30+ge);void writeweek(uchar week) /液晶刷新时分秒。3为时的开始位置,6为分,9为秒。液晶刷新日期。0为

31、年,3为月,6为日。液晶星期几显示函数。writecom(0x80+9); /从第一行隔十三个字符后开始写星期switch(week)case 1: writedata(M);writedata(O);writedata(N); break;case 2: writedata(T);writedata(U);writedata(E); break;case 3: writedata(W);writedata(E);writedata(D);break;case 4: writedata(T);writedata(H);writedata(U); break;case 5: writedata(

32、F);writedata(R);writedata(T);break;case 6: writedata(S);writedata(A);writedata(T);break;case 7: writedata(S);writedata(U);writedata(N);break;void keysca n() / 键盘扫描函数。if(flagalarm=1)|(flageve nt=1) /如果闹钟在响或者有事件提醒,任意键停止闹钟响或者取消事件提醒if(kme nu=0)|(kup=0)|(kdow n=0)|(kalarm=0)|(keve nt=0)delay(5);if(kme nu

33、=0)|(kup=0)|(kdow n=0)|(kalarm=0)|(keve nt=0)while(!(kme nu&kup&kdow n&kalarm&keve nt);di();flagalarm=0; /清除闹钟标志。flageve nt=0; /清除事件提醒标志。if(kme nu=0)/ 检测功能键。dela y(5);if(kme nu=0)kmenunum+; /记录功能键按下次数。 if(flagseta=1) /检测是否在进行闹钟设置。if(kme nunu m=4) kme nun um=1; /因为进行闹钟设置时,只调节时分秒,所以,kmenunum只能等于1,2,3

34、。if(flagsseta=1) /检测是否在进行事件提醒设置。if(kme nun um=8) kmenun um=5; /因为进行事件提醒设置时,只调节年月曰,所以,kmenunum只能等于5,6,7flagset=1; /设置标志位,表示在进行各种时间设置。while(!kme nu);di();switch(kmenunum) /定位光标闪烁点。case 1: writecom(0x80+0x40+10); / 秒闪烁。 writecom(OxOf); /开光标闪烁。break;case 2: writecom(0x80+0x40+7); /分闪烁。break;case 3: writ

35、ecom(0x80+0x40+4); /时闪烁。break;case 4: writecom(0x80+10); /星期闪烁.break;case 5: writecom(0x80+7); / 日闪烁.break;case 6: writecom(0x80+4); /月闪烁.break;case 7: writecom(0x80+1); /年闪烁.break;case 8: kme nunum=0;writecom(0x0c); / 取消光标闪烁。 flagset=0; /取消时间调节标志。dswrite(0x8e,0x00); /*允许写操作 */dswrite(0x80,seco nd/1

36、0*16+seco nd%10);dswrite(0x82,mi nute/10*16+mi nute%10); dswrite(0x84,hour/10*16+hour%10);dswrite(0x8a,week/10*16+week%10); dswrite(0x86,day/10*16+day%10); dswrite(0x88,mo nth/10*16+mo nth%10);dswrite(0x8c,year/10*16+year%10); dswrite(0x8e,0x80); /*禁止写操作 */break;if(kmenunum!=0)/只有当功能键按下时,才检测增大,减小键.i

37、f(kup=0)delay(5);if(kup=0)while(!kup);di();switch(kmenunum) /根据功能键被按下的次数,调节相应数值。case 1: sec on d+;if(sec on d=60)second=0;送液晶显示光标复位.writetime(9,secon d); writecom(0x80+0x40+10); / 因为,上面break; / 一次,光标后移一位,所以要将case 2: minu te+;if(minu te=60)minu te=0;writetime(6,mi nute); writecom(0x80+0x40+7); break;

38、case 3: hour+;if(hour=24) hour=0;writetime(3,hour); writecom(0x80+0x40+4); break;case 4: week+;if(week=8) week=1;writeweek(week); writecom(0x80+11); break;case 5: day+;if(day=32)day=1;write nyr(6,day);writecom(0x80+7); break;case 6: mon th+;if(mo nth=13) mon th=1;write nyr(3,m on th);writecom(0x80+4

39、); break;case 7: year+;if(year=100)year=0;write nyr(O,year); writecom(0x80+1); break;if(kdow n=0)delay(5);if(kdow n=0)while(!kdow n);di();switch(kmenunum) /根据功能键被按次数调节相应数值 case 1: sec on d-;if(sec on d=-1) second=59;writetime(9,sec on d); writecom(0x80+0x40+10); break;case 2: minu te-;if(mi nu te=-1

40、)minu te=59;writetime(6,mi nute);writecom(0x80+0x40+7);break;case 3: hour-;if(hour=-1) hour=23;writetime(3,hour); writecom(0x80+0x40+4); break;case 4: week-;if(week=0) week=7;writeweek(week);writecom(0x80+11);break;case 5: day-;if(day=0) day=31;write nyr(6,day);writecom(0x80+7);break;case 6: mon th-

41、;if(mon th=O)mon th=12;write nyr(3,m on th); writecom(0x80+4); break;case 7: year-;if(year=-1)year=99; write nyr(O,year); writecom(0x80+1); break;if(kalarm=0) / 检测闹钟调节键是否按下,此条if 语句与 if(kme nunum!=0)/在同一个层次。dela y(5);if(kalarm=0)flagseta=flagseta; while(!kalarm); di();if(flagseta=0) / 此时,退出闹钟设置,保存各相关

42、数值。flagset=0; /清除时间设置标志,在if(kalarm=0) 这个if语句writecom(0x80+0x40)中,不用flagset=1这条语句来设置/flagset标志位,因为如果进行了闹钟时间的设置就会执行前面if(kmenunum=0) 语句中的flagset=1这条语句。writedata( ); /清除液晶上的“ Ri闹钟调节标志。”writedata();writecom(0x0c); /取消光标闪烁dswrite(0x8e,0x00); /*允许写操作 */dswrite(writealarmsec on d,seco nd/10*16+sec on d%10);

43、 /往DS1302中保存闹钟的时分秒值。dswrite(writealarmmi nute,mi nu te/10*16+mi nu te%10); dswrite(writealarmhour,hour/10*16+hour%10); dswrite(0x8e,0x80); /*禁止写操作 */else /进入闹钟设置。s=dsread(readalarmseco nd)/16*10+dsread(readalarmsec on d)%16;/*读取DS1302中保存的闹钟时分秒原始值,转化为十进制数存进 s,m,h保存,用 以后面判断闹钟时间是否到达。*/m=dsread(readalar

44、m minu te)/16*10+dsread(readalarm minu te)%16;h=dsread(readalarmhour)/16*10+dsread(readalarmhour)%16; second=s; /把闹钟时间的十进制数据传送给变量 sec ond,minu te,hour,用以调节其值。min ute=m;hour=h;writecom(0x80+0x40); writedata(R); /液晶显示闹钟调节标志。writedata(i);writetime(3,hour); /writetime(6,mi nute);writetime(9,secon d);送液晶

45、显示闹钟时间。if(keve nt=0) if(kme nunum!=0)/检测事件提醒调节键是否按下,此条if语句与/在同一个层次。语句设置语句。dela y(5); if(keve nt=0) flagsseta=flagsseta;while(!keve nt);di();if(flagsseta=0) /此时,退出事件提醒设置,保存各相关数值。flagset=0; /清除时间设置标志,在if(keve nt=0)这个ifwritecom(0x80+9);/flagset/,就会执行前面writedata( ); /中,不用flagset=1这条语句来设置标志位,因为,如果进行了事件提醒

46、时间的if(kmenunum=0) 语句中的 flagset=1 这条清除液晶上的“ Ti事件提醒调节标志。writedata();writedata();writecom(0x0c); /取消光标闪烁dswrite(0x8e,0x00); /* 允许写操作 */dswrite(writeeve ntyear,year/10*16+year%10);/ 往DS1302中保存事件提醒的年月日值。dswrite(writeeve ntmon th,m on th/10*16+m on th%10);dswrite(writeeve ntday,day/10*16+day%10); dswrite(

47、0x8e,0x80); /* 禁止写操作 */else /进入事件提醒设置。yy=dsread(readeve ntyear)/16*10+dsread(readeve ntyear)%16;/*读取DS1302中保存的事件提醒年月日原始值,转化为十进制数存进yy,mm,dd保存,用以后面判断事件提醒时间是否到达。*/mm=dsread(readeve ntmo nth)/16*10+dsread(readeve ntmon th)%16;dd=dsread(readeve ntday)/16*10+dsread(readeve ntday)%16;year=yy; /把事件提醒时间的十进制数

48、据传送给变量 hour,day,month,week 用以调节其值。mon th=mm;day=dd;writecom(0x80+9);writedata(T); /液晶显示事件提醒设置标志。writedata(i);writedata();writen yr(0,year);送液晶显示事件提醒时间。write nyr(3,m on th);write nyr(6,day);void dswritebyte(uchar d)/ 往 DS1302 写入一个字节。uchar i;ACC=d;for(i=8;i0;i-)dsdata=ACC0;dsclk=1; /*为什么这里时钟先为1后为0,因为d

49、sclk初始化为0 , 而,每次循环最后,都将其置0,这样就形成一个从0开始的上升沿,恰好满足ds1302写数据在上升沿,但是,时钟必须从0开始的要求*/dsclk=0;ACC=ACC1;uchar dsreadbyte()/ 从 DS1302 读出一个字节。uchar i;for(i=8;i0;i-)ACC=ACC1;ACC7=dsdata;dsclk=1; /读数据也一样,虽然是下降沿,但是,也要从0开始.这样设置dsclk刚好满足要求。dsclk=0; return ACC;向DS1302的指定地址写入一个字节void dswrite(uchar add,uchar dat) /dsrs

50、t=0;dsclk=0;dsrst=1; dswritebyte(add); /* dswritebyte(dat); /* dsclk=1;dsrst=0;uchar dsread(uchar add) / uchar dat;dsrst=0;dsclk=0;dsrst=1;dswritebyte(add); /* dat=dsreadbyte(); /* dsclk=1;先写入地址,命令字节*/再写1Byte数据*/从DS1302的指定地址读出一个字节先写入地址,命令字节*/再读1Byte数据*/dsrst=0; return dat;void in it1302time(uchar *p

51、Clock) /DS1302时间初始化函数uchar i;允许写操作*/uchar add=0x80; dswrite(0x8e,0x00); /* for(i=7;i0;i-)dswrite(add,*pClock); /*依次写入秒分时日月星期年*/pClock+;add+=2; /因为DS1302同一个时钟寄存器占两个地址,最低位为0 ,是 /用于写的地址,最低位为1,是用于读的地址.所以add加2. dswrite(0x8e,0x80); /*禁止写操作 */void in it() / 初始化函数。lcdrw=0;/DS1302初始化。dswrite(0x8e,0x00); /*ds

52、write(0x80,0x00);/dswrite(0x84,0x00);in it1302time(i nittime);/2018 年 7uchar num;/变量初始化. flagset=0; / flagseta=0; / flagalarm=0;/时间设置标志位置0,表示未进行时间设置 闹钟设置标志位置0.闹钟标志位置0.kmenunum=0; /功能键被按次数计数器置0.允许写操作*/打开DS1302晶振,使其开始工作。 设置为24小时制。初始化时间为:月5日星期四,11点59分59 秒,/从左往右的数据依次是,秒,分,时,日,月,星期,年。开显示开显示不显示光标写一个指针加1 清屏设置数据指针起点dswrite(0x8e,0x80); /* 禁止写操作 */ /1602液晶初始化 writecom(0x38); writecom(0x

温馨提示

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

评论

0/150

提交评论