《2022年单片机课程设计实验报告..》由会员分享,可在线阅读,更多相关《2022年单片机课程设计实验报告..(28页珍藏版)》请在金锄头文库上搜索。
1、1 基于单片机的电子钟设计目录第一章电子时钟设计 -21.1 设计原理简介-21.2 设计功能 -3第二章主要电路元器件介绍-32.1 STC89C52 单片机简介-32.1.1 单片机简介 -32.1.2 主要特性 -32.1.3 管脚功能说明 -4 2.1.4 LCD1602-5第三章单元电路的硬件设计-63.1 硬件原理框图 -63.2 单片机 STC89C52 系统的设计 -6 3.3 时钟电路 -7 3.4 复位电路 -7 3.5 键盘接口电路 -8 3.6 LCD1602 显示-8 第四章设计总原理图 -9 第五章心得体会 -9 第六章源程序 -10 精选学习资料 - - - -
2、- - - - - 名师归纳总结 - - - - - - -第 1 页,共 28 页2 前言:课 程 设 计 题 目电 子 时 钟 、 日 历任 务 下 达 日 期2013 年 6 月 17日设 计 提 交 期 限2013 年 7 月 5 日设 计 主 要内 容使 用 89C51 、 LCD1602, 设 计 一 个 能 同 时 显 示 “ 年 月 日 ”“ 时 分 秒 ” 和 “ 星 期 ” 的 电 子 作 品主 要 技 术 要求 及 参 数基 本 要 求 :1 时 钟 走 一 天 的 误 差 小 于 1 秒 钟2 时 间 、 星 期 、 日 历 均 可 以 通 过 按 键 调 节 设 置成
3、 果 提 交形 式技 术 报 告 一 份 , 制 作 实 物 一 件 。设 计 进 度 安排第 1 周 查 资 料 , 研 究 设 计 题 目 、 内 容 及 要 求 并 进 行 初 步 设 计 。第 2 周 设 计 、 安 装 及 调 试 , 并 撰 写 设 计 报 告 。第 2 周 周 五 上 午 提 交 设 计 报 告 并 现 场 答 辩 。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 28 页3 摘要数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。
4、由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、 性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。尽管目前市场上已有现成的数字钟集成电路芯片出售,价格便宜、使用也方便,但鉴于单片机的定时器功能也可以完成数字钟电路的设计,因此进行数字钟的设计是必要的。在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系来用于实际,来培养我们的综合分析和设计电路,写程序、调试电路的能力。单片机具有体积小、功能强可靠性高、价格低廉等一系列优点, 不仅已成为工业控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行的技术改造和产
5、品的更新换代,应用前景广阔。一、作品介绍该电子钟使用 AT89S51为核心,采用 LCD1602 液晶屏显示,动态显示技术。 产用外部接 5V电源供电,内部添加了一个 4.8V 左右的电池以防突然断电后还能保持原先数据不变。该产品简单易于操作,可以实现以下功能:1、显示年份,格式“年、月、日”2、时间显示为 24 小时制,格式“时时”“分分” “妙妙”3、显示星期 , 用英文字符表示如星期一“MON ”二、设计目的1、巩固、加深和扩大 51系列单片机应用的知识面, 提高综合及灵活运用所学知识解决工业控制的能力;2、学会怎么使用 LCM602 ,并且要知道它的组成与构造。3、学会查阅书籍,并且要
6、能够熟练编写程序、仿真、绘画流程图、 原理图及 BCP图。4、对课题设计方案的分析、选择、比较、熟悉用51 单片机做系统开发、研制的过程,软硬件设计的方法、内容及步骤。三、设计要求1 上电以后自动进入计时状态。2、设计键盘调整时间,完成年月日、星期、时间的设计。3、采用 AT89S51为核心控制芯片,用LCD1602 作为显示屏。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 28 页4 第一章1.1 设计原理简介该设计设计一个电子时钟,我们采用的是STC89C52 单片机用软件实现计数和显示。该单片机是一个微型计算机,包括中央处理器C
7、PU,RAM ,ROM 、I/O 接口电路、定时计数器、串行通讯等,是时钟计数设计的核心。该时钟原理框图如图1.1,总体原理为:利用STC89C52 单片机构造电子时钟,可显示年、月、日、星期、时、分、秒,通过C 语言对单片机的编程即可产生相应的计时功能,并可以通过键盘进行时间的调整的控制。图 2.1 信号发生器原理框图本方案其主要模块包括复位电路、时钟信号、键盘控制、LCD1602 显示。其各个模块的作原理如下:(1)复位电路是为单片机复位使用,使单片机接口初始化;89C52 等 CMOS51 系列单片机的复位引脚RET 是施密特触发输入脚,内部有一个上拉低电阻,当振荡器起振以后,在 RST
8、 引脚上输出2 个机械周期以上的高电平,器件变进入复位状态开始,此时ALE 、PSEN、P0、 P1、P2、P3 输出高电平,RST 上输入返回低电平以后,变退出复位状态开始工作。该方案采用的是人工开关复位,在系统运行时,按一下开关,就在RST 断出现一段高电平,使器件复位。(2)时钟信号是产生单片机工作的时钟信号,控制着计算机的工作节奏,可以通过提高时钟频率来提高CPU 的速度。 89C52 内部有一个可控的反相放大器,引脚XTAL1 、XTAL2 为反相放大器输入端和输出端,在XTAL1 、 XTAL2 上外接12MHZ 晶振和30pF 电容便组成振荡器。时钟信号常用于CPU 定时和计数。
9、(3)键盘模块是是用于控制信号输入的类型,当按键按下时, 可以通过单片机编STC89C52单片机数接口电路键盘输入程读取闭合的键号,实现相应的时间调整。其步骤主要是a、断是否有键按下;b、去抖动,延时20ms 左右; c、识别被按下的键号;d、处理,实现功能。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 4 页,共 28 页5 (4)LCD1602 显示,通过单片机控制把数据送到LCD1602 上显示。1.2 设计功能(1)本设计利用3 位( P3.0 、P3.1、P3.2)控制时间的调整,其中当P3.0=0 对要调整的年、月、日、星期、时、分、
10、秒的切换;当P3.1=0 进行加 1 设置;当P3.2=0 进行减 1设置。(2)本设计利用LCD1602 液晶显示进行时间的显示,由单片机的P0 端口进行数据的传输; LCD 的 4(RS)接 P2.5, 5(RW)接 P2.6, 6( E)接 P2.7。第二章主要电路元器件介绍2.1 STC89C52 单片机简介2.1.1 单片机简介AT89C51 是一种带4K 字节 FLASH存储器的低电压、高性能CMOS 8 位微处理器,俗称单片机。该芯片具有优异的性价比,集成度高, 体积小,可靠性强,控制功能强等优点。其外形及引脚排列如图2.1 所示。2.1.2 主要特性图2.1 (1)兼容性能强(
11、2)4K 字节可编程FLASH 存储器(3)全静态工作:0Hz-24MHz (4)1288 位内部RAM 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 5 页,共 28 页6 (5)32 可编程I/O 线(6)两个16 位定时器 /计数器(7)5 个中断源(8)可编程串行通道(9)低功耗的闲置和掉电模式(10)片内振荡器和时钟电路2.1.3 管脚功能说明VCC :供电电压。GND :接地。P0口: P0口为一个 8位漏级开路双向I/O 口,每脚可吸收8个 TTL门电流。当P0口的管脚第一次写“1”时,被定义为高阻输入。P0能够用于外部程序数据存储
12、器,它可以被定义为数据 / 地址的第八位。在FIASH编程时, P0 口作为原码输入口,当FIASH进行校验时, P0输出原码,此时P0外部必须被拉高。P1口:P1口是一个内部提供上拉电阻的8位双向 I/O 口,P1口缓冲器能接收输出4个 TTL门电流。 P1口管脚写入“1”后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时, P1口作为第八位地址接收。P2口: P2口为一个内部上拉电阻的8位双向 I/O 口, P2口缓冲器可接收,输出4个 TTL门电流,当P2口被写“ 1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作
13、为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或 16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在 FLASH编程和校验时接收高八位地址信号和控制信号。P3口: P3口管脚是 8个带内部上拉电阻的双向I/O 口,可接收输出4个 TTL门电流。当P3口写入“ 1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平, P3口将输出电流(ILL )这是由于上拉的缘故。P3口作为 AT89C51 的一些
14、特殊功能口,管脚备选功能P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 /INT0(外部中断 0)精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 6 页,共 28 页7 P3.3 /INT1(外部中断 1)P3.4 T0 (计时器 0外部输入)P3.5 T1 (计时器 1外部输入)P3.6 /WR(外部数据存储器写选通)P3.7 /RD (外部数据存储器读选通)RST :复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。ALE/PROG :当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在
15、 FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号, 此频率为振荡器频率的1/6 。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。 如想禁止ALE的输出可在 SFR8EH 地址上置 0。此时, ALE 只有在执行MOVX ,MOVC 指令是 ALE才起用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。/EA /
16、 VPP :当/EA 保持低电平时,则在此期间外部程序存储器(0000H-FFFFH) ,不管是否有内部程序存储器。注意加密方式1时, /EA 将内部锁定为RESET ;当 /EA 端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V 编程电源( VPP ) 。XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。XTAL2:来自反向振荡器的输出。2.1.4 LCD1602 这里介绍的字符型液晶模块是一种用 5x7 点阵图形来显示字符的液晶显示器,根据显示的容量可以分为 1 行 16 个字、2 行 16 个字、2 行 20 个字等等,这里以常用的 2 行 16
17、个字的 1602 液晶模块来介绍它的编程方法。1602 采用标准的 16 脚接口,其中: 第 1 脚: VSS 为地电源第 2 脚: VDD 接 5V 正电源第 3 脚:V0 为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K 的电位器调整对比度第 4 脚: RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 7 页,共 28 页8 第 5 脚:RW 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS
18、和 RW 共同为低电平时可以写入指令或者显示地址,当 RS 为低电平 RW 为高电平时可以读忙信号,当 RS 为高电平 RW 为低电平时可以写入数据。第 6 脚: E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。第 7 14 脚: D0D7 为 8 位双向数据线。第15脚:背光电源正极第16脚:背光电源负极第三章单元电路的硬件设计硬件原理硬件电路的设计决定一个系统的的功能,是设计的基础所在, 而一般设计的标:可靠,简洁,高效,优化,好的硬件电路可以给程序的编写带来极大的优势,同时使可以很好的提高该信号设计的精度和灵敏度,使整个系统工作协调有序。3.1 硬件原理框图对于该电子
19、时钟的设计,我们采用了以STC89C52单片机芯片作为核心处理器,编程实现时间的计时, 最后通过 LCD1602 的显示。 结构简单, 思路仅仅有条, 而根据设计的基本要求,我们又把其细分为不同的功能模块,各个功能模块相互联系,相互协调,通过单片机程序构成一个统一的整体,其整体电路原理框如图 3.1 所示:图 3.1 3.2 单片机 STC89C52 系统的设计89C52 单片机是该信号发生器的核心,具有2 个定时器, 32 个并行I/O 口, 1 个串行 I/O 口, 5 个中断源。由于本设计功能简单,数据处理容易,数据存储空间也足够,因为我们采用了片选法选择芯片,进行芯片的选择和地址的译码
20、。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 8 页,共 28 页9 单片机引脚分配如下:XTAL1 ,XTAL2 :外接晶振,产生时钟信号;RES:复位电路;P0 口:接 LCD1602 的第 714 脚进行数据的传输;P2 口: LCD 的 4(RS)接 P2.5, 5( RW)接 P2.6, 6(E)接 P2.7;P3 口:接按键开关,对时间进行设置。3.3 时钟电路单片机的时钟信号通常用两种电路形式得到:内部振荡和外部振荡方式。在引脚 XTAL1 和 XTAL2 外接晶体振荡器,构成了内部振荡方式。由于单片机内部有一个高增益的反相放器,
21、 当外接晶振后, 就构成了自激振荡, 并产生振动时钟脉冲。 晶振通常选用6MHZ 、 12MHZ 、24MHZ 。本设计中时钟电路图如图3.2,我们选择了12MHZ 和晶振分别接引脚XTAL1 和XTAL2 ,电容C1,C2 均选择为30pF,对振荡器的频率有稳定作用。图 3.2 3.4 复位电路复位引脚RST 通过一个斯密特触发器与复位电路相连,斯密特触发器用来抑制噪声,在每个机器周期的S5P2,斯密特触发器的输出电平由复位电路采样一次,然后才能得到内部复位操作所需要的信号。复位电路通常采用上电自动复位和按钮复位两种方式。本设计选择了按键复位如图4.3,在系统运行时, 按一下开关, 就在RS
22、T 断出现一段高电平,使器件复位。 此时ALE 、PSEN、P0、P1、P2、P4 输出高电平, RST 上输入返回低电平以后,变退出复位状态开始工作。3.5 键盘接口电路P3.0 、P3.1、 P3.2 控制时间的调整,其中当P3.0=0 对要调整的年、月、日、星期、时、分、秒的切换;当P3.1=0 进行加 1 设置;当P3.2=0 进行减精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 9 页,共 28 页10 1 设置。图 3.43.6 LCD1602 显示对于 1602 与单片机的连接方法如图3.5 所示:图 3.5 第四章设计总原理图精选学
23、习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 28 页11 五、实验心得体会该电子时钟在调试时,总是出现许多的错误,软件上出了许多的问题,之后纠正,和组员慢慢调试修改了好多次。可是在仿真时依然存在很多的问题,开始的时候是仿真没有时间显示,之后改了改电路的P0 数据传输线后时间就显示出来了。在时间的调整上问题更多,刚开始时按键没有反应,然后加上了消抖延时后才有反应,但是设的延时时间太长就出现按键不灵,再改后就正常了。在开发板上调试时,背光是亮着, 但是没有数字出现,经过查看 1602 的资料才发现仿真不需要调节3 脚的变位器,而在电路板上时
24、就需要调节变位器才能使它正常显示。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 11 页,共 28 页12 第六章源程序#include #define uchar unsigned char #define uint unsigned int uchar ds1302_readbyte(); void ds1302_writebyte(uchar dat); uchar ds1302_readdata(uchar addr); void ds1302_writedata(uchar addr,uchar dat); void ds1302_se
25、ttime(uchar *p); void ds1302_gettime(uchar *p); void ds1302_initial(); sbit dssclk=P16; sbit dsIO=P17; sbit dsrs=P15; sbit lcd_rs=P25; sbit lcd_write=P26; sbit lcd_en=P27; sbit key1=P30; /设置sbit key2=P31; /加sbit key3=P32; /减uchar table_r= 2013-01-01 MON ; uchar table_s= 00:00:00; uchar table_week3=M
26、,O,N, T,U,E, W,E,D, T,H,U, F,R,I, S,A,T, S,U,N ; uchar i,t,keynum1; char sec,min,hour,week,day=1,mon=1; uint year=2013; uchar Convert(uchar In_Date) uchar i, Out_Date = 0, temp = 0; for(i=0; i i) & 0x01; Out_Date |= (temp (7 - i); 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 12 页,共 28 页13 return O
27、ut_Date; void delay(uchar z) /延时程序 uchar x,y; for(x=0;x148;x+) for(y=0;yz;y+); void write_com(uchar com)/ 往液晶中写指令 lcd_rs=0; lcd_en=0; P0=Convert(com); delay(2); lcd_en=1; delay(2); lcd_en=0; void write_data(uchar date)/ 往液晶中写数据 lcd_rs=1; lcd_en=0; P0=Convert(date); delay(2); lcd_en=1; delay(2); lcd_
28、en=0; void data_refresh_0(uchar add,uchar date)/ 第一行二位数调整 uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+add); write_data(0x30+shi); write_data(0x30+ge); void data_refresh_1(uchar add,uchar date)/ 第二行二位数调整 uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+0x40+add); 精选学习资料 - - - - - - - -
29、 - 名师归纳总结 - - - - - - -第 13 页,共 28 页14 write_data(0x30+shi); write_data(0x30+ge); void data_refresh_2(uchar add,uchar date) /星期调整 switch(date) case 0:write_com(0x80+add); write_data(table_week00); write_data(table_week01); write_data(table_week02); break; case 1:write_com(0x80+add); write_data(table
30、_week10); write_data(table_week11); write_data(table_week12); break; case 2:write_com(0x80+add); write_data(table_week20); write_data(table_week21); write_data(table_week22); break; case 3:write_com(0x80+add); write_data(table_week30); write_data(table_week31); write_data(table_week32); break; case
31、4:write_com(0x80+add); write_data(table_week40); write_data(table_week41); write_data(table_week42); break; case 5:write_com(0x80+add); write_data(table_week50); write_data(table_week51); write_data(table_week52); break; case 6:write_com(0x80+add); write_data(table_week60); write_data(table_week61);
32、 write_data(table_week62); break; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 14 页,共 28 页15 void data_refresh_4(uchar add,uint date) /四位数调整 uchar qian,bai,shi,ge; qian=date/1000; bai=date%1000/100; shi=date%1000%100/10; ge=date%1000%100%10; write_com(0x80+add); write_data(0x30+qian); write_data(0
33、x30+bai); write_data(0x30+shi); write_data(0x30+ge); void lcd_init() /液晶显示初始化 lcd_write=0; lcd_rs=0; lcd_en=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(i=0;i15;i+) write_data(table_ri); delay(10); write_com(0x80+0x40); for(i=0;i11;i+) write_data(table_
34、si); delay(10); timer0_init() /定时器 0 初始化 TMOD=1; TH0=(65536-50000)/256; TL0=(65536-50000)%256; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 15 页,共 28 页16 EA=1; ET0=1; TR0=1; void keyscan() /按键扫描 if(key1=0) delay(5); if(key1=0) TR0=0; keynum1+; delay(10); while(!key1); write_com(0x80+0x40+10); writ
35、e_com(0x0f); if(keynum1=2)/ 分 write_com(0x80+0x40+7); if(keynum1=3)/ 时 write_com(0x80+0x40+4); if(keynum1=4)/ 年 write_com(0x80+4); if(keynum1=5)/ 月 write_com(0x80+7); if(keynum1=6)/ 日 write_com(0x80+10); if(keynum1=7)/ 星期 write_com(0x80+14); if(keynum1=8) keynum1=0; 精选学习资料 - - - - - - - - - 名师归纳总结 -
36、 - - - - - -第 16 页,共 28 页17 TR0=1; write_com(0x0c); if(keynum1!=0) if(keynum1=1) if(key2=0) delay(5); if(key2=0) sec+; if(sec=60) sec=0; delay(10); while(!key2); data_refresh_1(9,sec); write_com(0x80+0x40+10); if(key3=0) delay(5); if(key3=0) sec-; if(sec=-1) sec=59; delay(10); while(!key3); data_ref
37、resh_1(9,sec); write_com(0x80+0x40+10); if(keynum1=2) if(key2=0) delay(5); if(key2=0) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 17 页,共 28 页18 min+; if(min=60) min=0; delay(10); while(!key2); data_refresh_1(6,min); write_com(0x80+0x40+7); if(key3=0) delay(5); if(key3=0) min-; if(min=-1) min=59;
38、delay(10); while(!key3); data_refresh_1(6,min); write_com(0x80+0x40+7); if(keynum1=3) if(key2=0) delay(5); if(key2=0) hour+; if(hour=24) hour=0; delay(10); while(!key2); data_refresh_1(3,hour); write_com(0x80+0x40+4); if(key3=0) delay(5); 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 18 页,共 28 页19
39、if(key3=0) hour-; if(hour=-1) hour=23; delay(10); while(!key3); data_refresh_1(3,hour); write_com(0x80+0x40+4); if(keynum1=7) if(key2=0) delay(5); if(key2=0) week+; if(week=7) week=0; delay(10); while(!key2); data_refresh_2(12,week); write_com(0x80+14); if(key3=0) delay(5); if(key3=0) week-; if(week
40、=-1) week=7; delay(10); while(!key3); data_refresh_2(12,week); write_com(0x80+14); if(keynum1=6) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 19 页,共 28 页20 if(key2=0) delay(5); if(key2=0) day+; if(mon=1|mon=3|mon=5|mon=7|mon=8|mon=10|mon=12) if(day=32) day=1; if(mon=2) if(year%400=0|(year%100!=0&y
41、ear%4=0) if(day=30) day=1; else if(day=29) day=1; if(mon=4|mon=6|mon=9|mon=11) if(day=31) day=1; delay(10); while(!key2); data_refresh_0(9,day); write_com(0x80+10); if(key3=0) delay(5); if(key3=0) day-; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 20 页,共 28 页21 if(mon=1|mon=3|mon=5|mon=7|mon=8|mon
42、=10|mon=12) if(day=0) day=31; if(mon=2) if(year%400=0|(year%100!=0&year%4=0) if(day=0) day=29; else if(day=0) day=28; if(mon=4|mon=6|mon=9|mon=11) if(day=0) day=30; delay(10); while(!key3); data_refresh_0(9,day); write_com(0x80+10); if(keynum1=5) if(key2=0) delay(5); if(key2=0) mon+; if(mon=13) mon=
43、1; delay(10); while(!key2); data_refresh_0(6,mon); write_com(0x80+7); 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 21 页,共 28 页22 if(key3=0) delay(5); if(key3=0) mon-; if(mon=0) mon=12; delay(10); while(!key3); data_refresh_0(6,mon); write_com(0x80+7); if(keynum1=4) if(key2=0) delay(5); if(key2=0)
44、year+; if(year=2100) year=2010; delay(10); while(!key2); data_refresh_4(1,year); write_com(0x80+4); if(key3=0) delay(5); if(key3=0) year-; if(year=2009) year=2099; delay(10); while(!key3); data_refresh_4(1,year); 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 22 页,共 28 页23 write_com(0x80+4); void ma
45、in() /主函数 lcd_init(); timer0_init(); ds1302_initial(); ds1302_gettime(); while(1) delay(5); keyscan(); /按键扫描 void timer0() interrupt 1 TH0=(65536-50000)/256; TL0=(65536-50000)%256; t+; if(t=20) t=0; sec+; if(sec=60) sec=0; min+; if(min=60) min=0; hour+; if(hour=24) hour=0; day+; week+; if(week=7) we
46、ek=0; if(mon=1|mon=3|mon=5|mon=7|mon=8|mon=10|mon=12) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 23 页,共 28 页24 if(day=32) day=1; mon+; if(mon=13) mon=1; year+; if(year=2100) year=2010; data_refresh_4(1,year); data_refresh_0(6,mon); if(mon=2) if(year%400=0|(year%100!=0&year%4=0) if(day=30) day=1;
47、 mon+; if(mon=13) mon=1; year+; if(year=2100) year=2010; data_refresh_4(1,year); data_refresh_0(6,mon); else if(day=29) day=1; mon+; if(mon=13) mon=1; year+; if(year=2100) year=2010; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 24 页,共 28 页25 data_refresh_4(1,year); data_refresh_0(6,mon); if(mon=4|
48、mon=6|mon=9|mon=11) if(day=31) day=1; mon+; if(mon=13) mon=1; year+; if(year=2100) year=2010; data_refresh_4(1,year); data_refresh_0(6,mon); data_refresh_2(12,week); data_refresh_0(9,day); data_refresh_1(3,hour); data_refresh_1(6,min); data_refresh_1(9,sec); /*/ uchar ds1302_readbyte() /从 1302 读 1 字
49、节数据 uchar i; uchar dat=0; for(i=0;i=1; if(dsIO) dat |=0x80; dssclk=1; delay(5); return dat; /*/ void ds1302_writebyte(uchar dat) /向 1302 写 1 字节数据 uchar i; for(i=0;i=1; dsIO=CY; dssclk=1; delay(5); /*/ uchar ds1302_readdata(uchar addr) /读 13002 某个地址的数据 uchar dat; dsrs=0; delay(5); dssclk=0; delay(5);
50、 dsrs=1; delay(5); ds1302_writebyte(addr); /写地址dat=ds1302_readbyte(); /读数据dssclk=1; dsrs=0; return dat; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 26 页,共 28 页27 /*/ void ds1302_writedata(uchar addr,uchar dat) /往 13002 某个地址写数据 dsrs=0; delay(5); dsrs=1; delay(5); ds1302_writebyte(addr); /写地址ds1302
51、_writebyte(dat); /写数据dssclk=1; dsrs=0; /*/ void ds1302_settime(uchar *p) /写入时间 uchar addr=0x80; uchar n=7; ds1302_writedata(0x8e,0x00); /允许写while(n-) ds1302_writedata(addr,*p+); addr+=2; ds1302_writedata(0x8e,0x80); /写保护 /*/ void ds1302_gettime(uchar *p) /读取时间 uchar addr=0x81; uchar n=7; while(n-) *
52、p+=ds1302_readdata(addr); addr+=2; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 27 页,共 28 页28 /*/ void ds1302_initial() /初始化 1302 dsrs=0; dssclk=0; ds1302_writedata(0x8e,0x00); /允许写操作ds1302_writedata(0x80,0x00); /时钟启动ds1302_writedata(0x90,0xaa); ds1302_writedata(0x8e,0x80); /写保护 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 28 页,共 28 页