基于单片机的万年历设计_第1页
基于单片机的万年历设计_第2页
基于单片机的万年历设计_第3页
免费预览已结束,剩余26页可下载查看

下载本文档

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

文档简介

.基于单片机的万年历设计二、实验要求设计一个万年历,将时钟显示在lcd1602的显示屏上并且可以进行年、月、日以及时、分、秒的设置。此外还可以通过按键进行闹钟设置以及事件提醒功能, 用蜂鸣器进行闹铃提醒。 最后附加一个温湿度检测的功能,用温湿度传感器检测室内的温湿度并将温湿度数据在显示屏上显示出来。三、实验设备和仪器1. 用 stc89c52芯片作为系统板的主控芯片2.dht11温湿度传感器3. ds1302时钟芯片4. lcd1602显示屏四、实验各模块原理介绍4.1 stc89c52 单片机stc89c52 是 stc 公司生产的一种低功耗、 高性能 cmos8 位微控制器, 具有 8k 字节系统可编程flash存储器。stc89c52 使用经典的 mcs-51 内核,具有传统 51 单片机不具备的功能。在单芯片上,拥有灵巧的8 位 cpu 和在系统可编程 flash,使得 stc89c52 为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。(1) ) 主要特性8k 字节程序存储空间;512 字节数据存储空间;内带 4k 字节 eeprom 存储空间; 可直接使用串口下载;(2) ) 器件参数1. 增强型 8051 单片机,6 时钟/机器周期和 12 时钟/机器周期可以任意选择, 指令代码完全兼容传统8051。2. 工作电压: 5.5v 3.3v(5v 单片机) /3.8v2.0v (3v 单片机)3. 工作频率范围: 040mhz ,相当于普通 8051 的 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 位定时器 /计数器。即定时器t0、t1、t2。10. 外部中断 4 路,下降沿中断或低电平触发电路,power down 模式可由外部中断低电平触发中断方式唤醒。11. 通用异步串行口( uart ),还可用定时器软件实现多个uart 。12. 工作温度范围: -40+85(工业级) /0 75(商业级)13. pdip 封装1、stc89c52单片机引脚图 主电源引脚 (2 根)图 4.1 stc89c52 单片机引脚图vcc(pin40):电源输入,接 +5v 电源gnd(pin20):接地线外接晶振引脚 (2 根)xtal1(pin19) :片内振荡电路的输入端xtal2(pin20) :片内振荡电路的输出端控制引脚 (4 根)rst/vpp(pin9):复位引脚,引脚上出现2 个机器周期的高电平将使单片机复位。ale/prog(pin30): 地 址 锁 存 允 许 信 号 psen(pin29): 外 部 存 储 器 读 选 通 信 号 ea/vpp(pin31):程序存储器的内外部选通,接低电平从外部程序存储器读指令,如果接高电平则从内部程序存储器读指令。可编程输入 /输出引脚 (32 根)stc89c52 单片机有 4 组 8 位的可编程 i/o 口,分别位 p0、p1、p2、p3口,每个口有 8 位(8 根引脚),共 32 根。po 口(pin39pin32):8 位双向 i/o 口线,名称为 p0.0p0.7 p1 口(pin1pin8): 8 位准双向 i/o 口线,名称为 p1.0 p1.7 p2口(pin21pin28):8 位准双向 i/o 口线,名称为 p2.0 p2.7 p3口(pin10pin17):8 位准双向 i/o 口线,名称为 p3.0 p3.7。2、stc89c52单片机最小系统stc89c52 单片机最小系统主要由复位电路和时钟电路组成。复位功能通过外部电路来实现,按下按键k1 控制单片机的复位。时钟电路主要通过晶振来实现,为单片机提供运行时钟。 根据不同的需求选用的晶振频率会有差异,在本次课程设计中采用11.0592mhz 的晶振频率。单片机复位电路如图4.2 所示,晶振电路如图 4.3 所示。图 4.2复位电路4.2 ds1302 芯片图 4.3 晶振电路ds1302 是 dallas公司出的一款实时时钟芯片, 它广泛应用于电话、 传真、便携式仪器等产品领域,主要性能指标如下:1、ds1302 是一个实时时钟芯片, 可以提供秒、 分、小时、日期、月、年等信息,具有软件自动调整的能力,可以通过配置am/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引脚及其功能图 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 进行读写。(6) )i/o:该引脚是一个双向通信引脚,且内部含有一个40k 的下拉电阻,可进行数据的读写。(7) )sclk :该引脚是输入引脚,且内部含有一个40k 的下拉电阻,作为通信的时钟信号。(8) ) vcc1:备用电源引脚。(2) ds1302 与单片机接线图ds1302 引脚与单片机接线图如图4.5 所示,从图 4.5 可看出,引脚 x1 与x2 之间接一个 32.768k 的晶体正振荡器, vcc1 通过一个纽扣能电池再接地。图 4.5 ds1302 与单片机连接图4.3 lcd1602 液晶显示屏lcd1602 液晶屏能够能够同时显示32 个字符,价格便宜,编程简单而且稳定可靠。 lcd1602 液晶屏是一种图形点阵显示器,显示原理简单易懂,都是液晶屏内部的液晶材料变化而显示不同的字符,因为液晶是具有流动特性的物质, 所以只需外加很微小的力量即可使液晶分子运动。( 1) lcd1602引脚1602lcd 采用标准的 14 脚(无背光)或16 脚(带背光)接口,各引脚接口图如图 4.6 所示:图 4.6 lcd1602 引脚图(a) 各个引脚说明1 脚: vss 为地电源2 脚: vdd 接 5v 正电源3 脚: v0 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比对比度过高时会产生“鬼影”,使用时可以通过一个10k 的电位器调整。4 脚: rs 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器5 脚: r/w 为读写信号线,高电平时进行读操作,低电平时进行写操作。当rsr/w 共同为低电平时可以写入指令或者显示地址,当rs 为低电平, r/w 为高电平;rs 为高电平, r/w 为低电平时可以写入数据。6 脚: e 端为使能端,当e 端由高电平跳变成低电平时,液晶模块执行命令。7 14 脚: d0 d7 为 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 ( 2)均接电源,将液晶显示器接地保证对比度最强,可使用一个10k 的电位器进行调整。4.4 温湿度传感器 dht11dht11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它采用专用的数字模块采集技术、温湿度传感技术,确保产品的可靠性、 长期稳定性。传感器包括一个电阻式感湿元件和一个ntc 测温元件,并与一个高性能 8 位单片机相连接。因此,该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个 dht11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在otp 内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功 耗,信号传输距离可达20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。 产品为 4 针单排引脚封装, 连接方便, 特殊封装形式可根据用户需求而提供。( 1) dht11引脚及其功能dht11 的引脚图如图 4.8 所示,一般情况下它有四个引脚,分别为:vcc、dout 、nc、gnd 。各引脚以及功能如表4-1 所示。pin图 4.8 dht11 引脚图表 4-1 dht11 引脚及其功能名称注释1vdd供电 3-5.5vdc2data串行数据,单总线3nc空脚,请悬空4gnd接地,电源负极1. 电源引脚dht11 的供电电压为 3-5.5v。传感器上电后, 要等待 1s 以越过不稳定状态在此期间无需发送任何指令。 电源引脚(vdd ,gnd )之间可增加一个100nf 的电容,作用在于去耦滤波。2. 串行接口 ( 单线双向 )data 是用于微处理器与 dht11 之间的通信和同步的串行双向接口,采用单总线数据格式。每次通信都是以高位先出的顺序传输 40 位数据,用时约为4 ms 。数据格式为:8 位湿度整数数据 +8 位湿度小数数据 +8 位温度整数数据 +8 位温度小数数据+8 位校验和数据。数据分小数部分和整数部分,当前小数部分用于以后扩展,现读出为零。 数据传送正确时, 校验和数据等于 “ 8 位湿度整数数据 +8 位湿度小数数据+8 位温度整数数据 +8 位温度小数数据”所得结果的末8 位。( 2) dht11与单片机接线图dht11 与单片机的接线图如图4.9 所示,由图 4.9 中可看出, dht11 第三个引脚接单片机的p2.2 引脚,第一个引脚接电阻和发光二极管。4.5 蜂鸣器图 4.9 dht11 与单片机接线图蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电, 广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等 电子产品中作发声器件。 蜂鸣器可分为无源蜂鸣器和有源蜂鸣器两种,此处我们用到的是有源蜂鸣器。有源蜂鸣器工作的理想信号是直流电,通常标示为vdc、 vdd等。因为蜂鸣器内部有一简单的振荡电路,能将恒定的直流电转化成一定频率的脉冲信号,从而带动钼片振动发音。有源蜂鸣器主要靠压电效应的原理来发声的,且内部带有多谐振荡器, 可产生 1.5-2.5khz的电压信号。由此有源蜂鸣器才能发声。有源蜂鸣器在单片机中 的电路图较为简单,图4.10 为蜂鸣器与单片机的接线图。图 4.10蜂鸣器与单片机的接线图有源蜂鸣器直接接上额定电源就可连续发声,i/o 口输出后接一个1k 的电阻,目的在于基极限流,以低电平方式,启动蜂鸣器发声。五、流程图(1)主程序流程图图 5.1 是系统主程序流程图,系统开始时先进行初始化,然后再调整时间和闹钟,再通过串口屏将时间显示出来。主程序流程图开始系统初始化是否调整时间y时间调整子程序n是否设置时间y闹钟、事件设置子程序nlcd1602显示结束( 2)子程序流程图图 5.1主程序流程图系统从主程序开始执行,分别调用各个子程序,其中子程序包括ds1302 子程序, dht11 子程序和 lcd1602 子程序等。(1) ) ds1302芯片子程序流程图ds1302为实时时钟芯片,可以提供秒、分、时、日、月、年及星期等信息, 具有软件自动调整的能力, 可以通过配置 am/pm来决定采用 24 小时格式还是 12 小时格式。从 ds1302中可以读出年、月、日、时、分、秒等信息。图 5.2 为 ds1302 芯片的子程序流程图:ds1302子程序流程图开始初始化 ds1302ds1302 开始震荡从 ds1302 中读出年、月、日、时、分、秒(2) ) dht11子程序流程图图 5.2 ds1302 子程序流程图dht11 为温湿度传感器,可以实时显示环境中的温湿度。其数据由 8 位湿度整数数据, 8 位湿度小数数据, 8 位温度整数数据和 8 位温度小数数据以及 8 位校验和数据。 dht11 子程序流程图如 5.3 所示:dht11子程序流程图开始发出读命令读取湿度读取温度读取校验和校验数据是否出n错?y丢弃当前数据结束图 5.3 dht11 子程序流程图( 3) lcd1602子程序流程图lcd1602 显示时,也要先进行初始化,紧接着读指令,读完之后写指令,再对数据进行读写,然后显示出来,其流程图如图5.4 所示。lcd1602 子程序库程图开始初始化读写指令读写数据返回图 5.4 lcd1602 显示屏子程序流程图六、实验目的1. 学会并掌握可 keil软件的使用;2. 学会并掌握 altium designer软件的使用;3. 实现万年历的基本功能;4. 通过实验巩固单片机相关知识和检验自身动手能力七、实验内容本次实验使用 stc89c52单片机作为主控芯片, 使用 ds1302芯片作为时钟芯片,在 lcd1602显示屏上显示, 并可以设置闹钟和事件提醒功能, 此外还可以进行室内温湿度的检测和显示,最终完成万年历的设计。八、实验步骤1. 查询资料, 确定主控芯片、 温湿度传感器、 时钟芯片以及 lcd1602显示屏的使用说明。2. 根据功能要求进行硬件电路的设计, 使用 altiumdesigner 软件设计电路。整个电路分为主控芯片控制模块、lcd1602显示模块、按键设置模块、蜂鸣器电路模块以及 dht11温湿度传感器模块。硬件电路图如图1 所示:图 8.1 :硬件电路图3. 根据电路图编写 c语言代码: 代码如下:#include #define uchar unsigned char#define uint unsigned int#define lcddata p0#define readalarmsecond 0xc7/定义从ds1302中读闹钟秒值的命令字节#define writealarmsecond 0xc6 /定义往ds1302中写闹钟秒值的命令字节#define readalarmminute 0xc5/定义从ds1302中读闹钟分值的命令字节#define writealarmminute 0xc4 /定义往ds1302中写闹钟分值的命令字节#define readalarmhour 0xc3/定义从ds1302中读闹钟小时值命令字节#define writealarmhour 0xc2/定义往ds1302中写闹钟小时值命令字节#define readeventday 0xd7/定义从ds1302中读事件提醒日期值的命令字节#define writeeventday 0xd6/定义往ds1302中写事件提醒日期值的命令字节#define readeventmonth 0xd5/定义从ds1302中读事件提醒月份值的命令字节#define writeeventmonth 0xd4/定义往ds1302中写事件提醒月份值的命令字节#define readeventyear 0xd3/定义从ds1302中读事件提醒年份值的命令字节#define writeeventyear 0xd2/定义往ds1302中写事件提醒年份值的命.令字节sbit lcdrs=p27;/lcd数据 / 命令选择端 (h/l) sbit lcdrw=p26;/lcd读/ 写选择端 (h/l)sbit lcden=p25;/lcd使能控制sbit beep=p13;/蜂鸣器控制端sbit dq = p14;/温湿度传感器 sbit kmenu=p32;/功能键sbit kup=p33;/增大键sbit kdown=p34;/减小键sbit kalarm=p35;/闹钟查看键 ring:显示闹钟需要调到的时间sbit kevent=p36;/事件查看键 ding:显示事件提醒需要调到的时间/sbit kmode=p37;/切换温湿度显示sbit dsclk=p22;/ds1302的时钟信号端sbit dsdata=p21; /ds1302的数据 i/o端sbit dsrst=p20;/ds1302的复位端sbit acc7=acc7;/定义累加器的最高和最低位。sbit acc0=acc0;bit flagalarm,flagseta,flagset; /分别定义闹钟响标志位,闹钟设置标志位,时间设置标志位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 second,minute,hour,year,month,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(uint z); /毫秒级延时函数。void di(); /蜂鸣器发声函数。void writecom(uchar com); /液晶写命令函数。void writedata(uchar dat); /液晶写数据函数。void writetime(uchar add,uchar dat); /液晶刷新时分秒。void writenyr(uchar add,uchar dat); /液晶刷新日期。void writeweek(uchar week); /液晶星期几显示函数。 void keyscan(); /键盘扫描函数。void dswritebyte(uchar d);/往 ds1302 写入一个字节。uchar dsreadbyte(); /从 ds1302 读出一个字节。void dswrite(uchar add, uchar dat); /向 ds1302 的指定地址写入一个字节uchar dsread(uchar add); /从 ds1302 的指定地址读出一个字节void init1302time(uchar *pclock); /ds1302时间初始化函数void init(); /初始化函数void delay_100us(uint j);/延时 100us void delay_10us(void);/延时 10usvoid com(void);void read_dht11(void);void delay(uint z) /毫秒级延时函数。uint x,y; for(x=z;x0;x-)for(y=110;y0;y-);void di() /蜂鸣器发声函数。beep=0; delay(100); beep=1;void writecom(uchar com) /液晶写命令函数。lcdrs=0;/ 置为写入命令lcddata=com;/ 送入数据delay(1);lcden=1;/拉高使能端delay(1);lcden=0;/完成高脉冲void writedata(uchar dat) /液晶写数据函数。lcdrs=1;/ 置为写入数据lcddata=dat;/ 送入数据delay(1);lcden=1; delay(1); lcden=0;void writetime(uchar add,uchar dat) /液晶刷新时分秒。/3为时的开始位置, 6 为分, 9为秒。uchar shi,ge; shi=dat/10; ge=dat%10;writecom(0x80+0x40+add); writedata(0x30+shi); writedata(0x30+ge);void writenyr(uchar add,uchar dat) /液晶刷新日期。/0为年, 3为月, 6为日。uchar shi,ge; shi=dat/10; ge=dat%10; writecom(0x80+add); writedata(0x30+shi); writedata(0x30+ge);void writeweek(uchar week) /液晶星期几显示函数。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(f);writedata(r);writedata(i); break;case 6: writedata(s);writedata(a);writedata(t); break;case 7: writedata(s);writedata(u);writedata(n); break;void keyscan() /键盘扫描函数。if(flagalarm=1)|(flagevent=1) /如果闹钟在响或者有事件提醒, 任意键停止闹钟响或者取消事件提醒if(kmenu=0)|(kup=0)|(kdown=0)|(kalarm=0)|(kevent=0)delay(5);if(kmenu=0)|(kup=0)|(kdown=0)|(kalarm=0)|(kevent=0)while(!(kmenu&kup&kdown&kalarm&kevent); di();flagalarm=0; /清除闹钟标志。flagevent=0; /清除事件提醒标志。if(kmenu=0) /检测功能键。delay(5); if(kmenu=0)kmenunum+; /记录功能键按下次数。if(flagseta=1) /检测是否在进行闹钟设置。if(kmenunum=4) kmenunum=1; /因为进行闹钟设置时,只调节时分秒,所以,kmenunum 只能等于 1,2,3。if(flagsseta=1) /检测是否在进行事件提醒设置。if(kmenunum=8) kmenunum=5; /因为进行事件提醒设置时,只调节年月日,所以,kmenunum 只能等于 5,6,7flagset=1; /设置标志位,表示在进行各种时间设置。while(!kmenu); di();switch(kmenunum) /定位光标闪烁点。case 1: writecom(0x80+0x40+10); /秒闪烁。writecom(0x0f); /开光标闪烁。break;case 2: writecom(0x80+0x40+7); /分闪烁。break;case 3: writecom(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: kmenunum=0;writecom(0x0c); /取消光标闪烁。flagset=0; /取消时间调节标志。dswrite(0x8e,0x00); /*允许写操作 */ dswrite(0x80,second/10*16+second%10);dswrite(0x82,minute/10*16+minute%10); dswrite(0x84,hour/10*16+hour%10);dswrite(0x8a,week/10*16+week%10);dswrite(0x86,day/10*16+day%10); dswrite(0x88,month/10*16+month%10); dswrite(0x8c,year/10*16+year%10); dswrite(0x8e,0x80); /*禁止写操作 */ break;if(kmenunum!=0) /只有当功能键按下时, 才检测增大 , 减小键 .if(kup=0)delay(5); if(kup=0)while(!kup);di();switch(kmenunum) / 根据功能键被按下的次数, 调节相应数值。送液晶显示光标复位 .case 1: second+;if(second=60) second=0;writetime(9,second); writecom(0x80+0x40+10); /因为,上面break; /一次 , 光标后移一位, 所以要将case 2: minute+;if(minute=60) minute=0;writetime(6,minute); writecom(0x80+0x40+7); break;case 3: hour+;case 4: week+;case 5: day+;if(hour=24)hour=0; writetime(3,hour); writecom(0x80+0x40+4); break;if(week=8)week=1; writeweek(week); writecom(0x80+11); break;if(day=32)day=1; writenyr(6,day); writecom(0x80+7); break;case 6: month+;if(month=13)month=1; writenyr(3,month); writecom(0x80+4); break;case 7: year+;if(year=100)year=0;writenyr(0,year); writecom(0x80+1); break;if(kdown=0)delay(5); if(kdown=0)while(!kdown); di();switch(kmenunum) /根据功能键被按次数调节相应数值.case 1: second-;if(second=-1) second=59;writetime(9,second); writecom(0x80+0x40+10); break;case 2: minute-;case 3: hour-;case 4: week-;case 5: day-;if(minute=-1)minute=59; writetime(6,minute); writecom(0x80+0x40+7); break;if(hour=-1)hour=23; writetime(3,hour); writecom(0x80+0x40+4); break;if(week=0)week=7; writeweek(week); writecom(0x80+11); break;if(day=0)day=31; writenyr(6,day); writecom(0x80+7);case 6: month-;case 7: year-;break;if(month=0)month=12; writenyr(3,month); writecom(0x80+4); break;if(year=-1)year=99; writenyr(0,year); writecom(0x80+1); break;if(kalarm=0)/检 测 闹 钟 调 节 键 是 否 按 下 , 此 条if语 句 与if(kmenunum!=0)/在同一个层次。delay(5); if(kalarm=0)flagseta=flagseta; while(!kalarm); di();if(flagseta=0) /此时,退出闹钟设置,保存各相关数值。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(writealarmsecond,second/10*16+second%10); /往ds1302 中保存闹钟的时分秒值。dswrite(writealarmminute,minute/10*16+minute%10); dswrite(writealarmhour,hour/10*16+hour%10); dswrite(0x8e,0x80); /*禁止写操作 */else /进入闹钟设置。s=dsread(readalarmsecond)/16*10+dsread(readalarmsecond)%16; /* 读取 ds1302 中保存的闹钟时分秒原始值,转化为十进制数存进 s,m,h 保存,用以后面判断闹钟时间是否到达。 */m=dsread(readalarmminute)/16*10+dsread(readalarmminute)%16; h=dsread(readalarmhour)/16*10+dsread(readalarmhour)%16; second=s;/把 闹 钟 时 间 的 十 进 制 数 据 传 送 给 变 量second,minute,hour,用以调节其值。minute=m; hour=h;writecom(0x80+0x40);writedata(r); /液晶显示闹钟调节标志。writedata(i);writetime(3,hour); /送液晶显示闹钟时间。writetime(6,minute); writetime(9,second);if(kevent=0)/检 测事 件提 醒调 节键 是否 按下 , 此条if语 句与if(kmenunum!=0)/在同一个层次。delay(5); if(kevent=0)flagsseta=flagsseta; while(!kevent);di();if(flagsseta=0) /此时,退出事件提醒设置,保存各相关数值。语句设 置 语句。志 。 ”flagset=0; /清除时间设置标志,在if(kevent=0)这个 ifwritecom(0x80+9);/中,不用 flagset=1这条语句来设置/flagset标志位,因为 , 如果进行了事件提醒时间的/,就会执行前面 if(kmenunum=0)语句中的 flagset=1这条writedata( ); /清除液晶上的“ ti事件提醒调节标writedata( );writedata( );writecom(0x0c); /取消光标闪烁dswrite(0x8e,0x00); /*允许写操作 */dswrite(writeeventyear,year/10*16+year%10);/往ds1302 中保存事件提醒的年月日值。dswrite(writeeventmonth,month/10*16+month%10); dswrite(writeeventday,day/10*16+day%10); dswrite(0x8e,0x80); /*禁止写操作 */else /进入事件提醒设置。yy=dsread(readeventyear)/16*10+dsread(readeventyear)%16;/*读取 ds1302 中保存的事件提醒年月日原始值,转化为十进制数存进yy,mm,dd 保存,用以后面判断事件提醒时间是否到达。*/mm=dsread(readeventmonth)/16*10+dsread(readeventmonth)%16; dd=dsread(readeventday)/16*10+dsread(readeventday)%16; year=yy;/把 事 件 提 醒 时 间 的 十 进 制 数 据 传 送 给 变 量hour,day,month,week用以调节其值。month=mm; day=dd; writecom(0x80+9);writedata(t); /液晶显示事件提醒设置标志。writedata(i);writedata( );writenyr(0,year);/送液晶显示事件提醒时间。writenyr(3,month); writenyr(6,day);void dswritebyte(uchar d)/往 ds1302 写入一个字节。uchar i;acc=d;for(i=8;i0;i-)dsdata=acc0;dsclk=1; /*为什么这里时钟先为1后为 0 ,因为 dsclk初始化为 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;void dswrite(uchar add,uchar dat) /向 ds1302 的指定地址写入一个字节。dsrst=0; dsclk=0; dsrst=1;dswritebyte(add); /*先写入地址, 命令字节 */dswritebyte(dat); /*再写 1byte数据 */dsclk=1;dsrst=0;uchar dsread(uchar add) /从 ds1302 的指定地址读出一个字节.uchar dat; dsrst=0; dsclk=0; dsrst=1;dswritebyte(add);

温馨提示

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

评论

0/150

提交评论