您好,欢迎来到欧得旅游网。
搜索
您的当前位置:首页电子万年历

电子万年历

来源:欧得旅游网


单片机课程设计报告

电子万年历设计

姓 名: 学 号: 专业班级: 指导老师: 所在学院:

河南理工大学万方科技学院单片机课程设计报告

摘要

本设计是电子万年历。具备三个功能:能显示:

(1) 显示年月日时分秒及星期信息 (2) 具有可调整日期和时间功能 (3) 与即时时间同步

我选用的是单片机ATC52来实现电子万年历的功能。该电子万年历能够成功实现时钟运行,调整,显示年月日时分秒及星期,温度等信息。

该电子万年历使用12MHZ晶振与单片机ATC52相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性。所以在该设计与制作中我选用了单片机本电路是由ATC52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由DS1302提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。

因此,采用单片机原理制作的电子万年历,不仅仅在原理上能够成功实现计时等功能,也更经济,更适用,更符合我们实际生活的需要,对我们大学生来说也更加有用。

1

河南理工大学万方科技学院单片机课程设计报告

目 录

1概述..............................................................3 1.1单片机原理及应用简介.........................................3 1.2系统硬件设计.................................................4 2系统的总体方案和硬件设计

2.1电路设计框图.................................................5 2.2系统硬件概述.................................................5 2.3主要单元电路的设计...........................................7 2.3.1单片机主控制模块的设计.....................................7 2.3.2时钟电路模块的设计........................................ 8 2.3.3电路原理及说明.............................................8 2.3.4显示模块的设计.............................................9 3系统的软件设计...................................................11 3.1程序流程框图................................................11 4prodeus软件仿真........................................ ..........错误!未定义书签。

4.1Proteus运行流程..............................................13 4.2Proteus功能仿真..............................................13 5课程设计总结与体会.......................................... .....16 参考文献...........................................................17 附录一:源程序代码.................................................17 附录二:系统电路图.................................................31

2

河南理工大学万方科技学院单片机课程设计报告

1 概述

1.1单片机原理及应用简介

随着国内超大规模集成电路的出现,微处理器及其外围芯片有了迅速的发展。集成技术的最新发展之一是将CPU和外围芯片,如程序存储器、数据存储器、并行、串行I/O口、定时/计数器、中断控制器及其他控制部件集成在一个芯片之中,制成单片计算机(Single-Chip Microcomputer)。而近年来推出的一些高档单片机还包括有许多特殊功能单元,如A/D、D/A转换器、调制解调器、通信控制器、锁相环、DMA、浮点运算单元等。因此,只要外加一些扩展电路及必要的通道接口就可以构成各种计算机应用系统,如工业控制系统、数据采集系统、自动测试系统、万年历电子表等。

单片机的出现,并在各个技术领域中得到如此迅猛的发展,与单片机构成计算机应用系统所形成的下述特点有关:

1、单片机构成的应用系统有较大的可靠性。这些可靠性的获得除了依靠单片机芯片本身的高可靠性以及应用有最少的联接外,还可以方便地采用软、硬件技术。

2、系统扩展、系统配置较典型、规范,容易构成各种规模的应用系统,应用系统有较高的软、硬件利用系数。

3、由于构成的应用系统是一个计算机系统,相当多的测、控功能由软件实现,故具有柔性特征,不须改变硬件系统就能适当地改变系统功能。

4、有优异的性能、价格比。

可以说,对于广大的电子应用专业技术人员,目前国和内国外面临的单片机应用技术,如同60年代面临晶体管技术,70年代面临数字集成电路一样。单片机和可编程门阵列相结合,构成新一代电子应用技术是不可能回避的一项新型的工程应用技术。

单片机是微型计算机的一个重要分枝,单片机是把处理器、随机存储器、只读存储器、定时器/计数器、并行接口接口、串行接口、A/D转换器等主要计算机部件,集中在一块集成电路芯片上。虽然只是一个芯片,但从功能上它就相当于一台完整的微机。随着科学技术的迅猛发展,单片计集成度高、体积小、运算速度快、功耗低、运行可靠、价格低廉等诸多优点,越来越显现出来。目前可以说单片机已经渗透到我们的生活的各个领域,在工业方面:像过程控制、数据采集,机电一体化、智能化仪器仪表,特别在军事武器控制方面尤为突出。在日

3

河南理工大学万方科技学院单片机课程设计报告

常生活方面,我们使用彩电、洗衣机、电冰箱,录放机、VCD、照相机、手机、高级定时闹钟以及公共汽车上的报站器等等可以说举不胜举。

把单片机的诞生称为计算机发展史上的一个重要里程碑并不过分。单片机的应用,使许多领域的技术水平和自动化程度大大提高。可以说当今世界正在经受一场以单片机技术为标志的新技术浪潮的冲击。人们需要掌握单片机知识,跨入单片机应用与开发领域的大门。我们作为理工科的大学生,学习单片机课程尤其显得越来越重要。 1.2系统硬件设计

ATC52是51系列单片机的一个型号,它是ATMEL公司生产的。 ATC52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位处理器和Flash存储单元,功能强大的ATC52单片机可为您提供许多较复杂系统控制应用场合。 ATC52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,ATC52可以按照常规方法进行编程,但不可以在线编程(S系列的才支持在线编程)。其将通用的微处理器和Flash存储器结合在一

ATC52主要功能特性

· 兼容MCS51指令系统

· 8k可反复擦写(>1000次)Flash ROM · 32个双向I/O口 · 256x8bit内部RAM

· 3个16位可编程定时/计数器中断 · 时钟频率0-24MHz · 2个串行中断

· 可编程UART串行通道 · 2个外部中断源 · 共8个中断源 · 2个读写中断口线

· 3级加密位 起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

4

河南理工大学万方科技学院单片机课程设计报告

2系统的总体方案和硬件设计

2.1 电路设计框图

LCD液晶显示屏显 键盘模块 示模块 ATC52 主控制模 DS1302时钟模块 2.2 系统硬件概述

本电路是由1.1单片机原理及应用简介

块 图1系统原理图

5

河南理工大学万方科技学院单片机课程设计报告

随着国内超大规模集成电路的出现,微处理器及其外围芯片有了迅速的发展。集成技术的最新发展之一是将CPU和外围芯片,如程序存储器、数据存储器、并行、串行I/O口、定时/计数器、中断控制器及其他控制部件集成在一个芯片之中,制成单片计算机(Single-Chip Microcomputer)。而近年来推出的一些高档单片机还包括有许多特殊功能单元,如A/D、D/A转换器、调制解调器、通信控制器、锁相环、DMA、浮点运算单元等。因此,只要外加一些扩展电路及必要的通道接口就可以构成各种计算机应用系统,如工业控制系统、数据采集系统、自动测试系统、万年历电子表等。

单片机的出现,并在各个技术领域中得到如此迅猛的发展,与单片机构成计算机应用系统所形成的下述特点有关:

1、单片机构成的应用系统有较大的可靠性。这些可靠性的获得除了依靠单片机芯片本身的高可靠性以及应用有最少的联接外,还可以方便地采用软、硬件技术。

2、系统扩展、系统配置较典型、规范,容易构成各种规模的应用系统,应用系统有较高的软、硬件利用系数。

3、由于构成的应用系统是一个计算机系统,相当多的测、控功能由软件实现,故具有柔性特征,不须改变硬件系统就能适当地改变系统功能。

4、有优异的性能、价格比。

可以说,对于广大的电子应用专业技术人员,目前国和内国外面临的单片机应用技术,如同60年代面临晶体管技术,70年代面临数字集成电路一样。单片机和可编程门阵列相结合,构成新一代电子应用技术是不可能回避的一项新型的工程应用技术。

单片机是微型计算机的一个重要分枝,单片机是把处理器、随机存储器、只读存储器、定时器/计数器、并行接口接口、串行接口、A/D转换器等主要计算机部件,集中在一块集成电路芯片上。虽然只是一个芯片,但从功能上它就相当于一台完整的微机。随着科学技术的迅猛发展,单片计集成度高、体积小、运算速度快、功耗低、运行可靠、价格低廉等诸多优点,越来越显现出来。目前可以说单片机已经渗透到我们的生活的各个领域,在工业方面:像过程控制、数据采集,机电一体化、智能化仪器仪表,特别在军事武器控制方面尤为突出。在日常生活方面,我们使用彩电、洗衣机、电冰箱,录放机、VCD、照相机、手机、高级定时闹钟以及公共汽车上的报站器等等可以说举不胜举。

6

河南理工大学万方科技学院单片机课程设计报告

把单片机的诞生称为计算机发展史上的一个重要里程碑并不过分。单片机的应用,使许多领域的技术水平和自动化程度大大提高。可以说当今世界正在经受一场以单片机技术为标志的新技术浪潮的冲击。人们需要掌握单片机知识,跨入单片机应用与开发领域的大门。我们作为理工科的大学生,学习单片机课程尤其显得越来越重要。

单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由DS1302提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31*8的用于临时性存放数据的RAM寄存器。可产生年、月、日、周日、时、分、秒,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能;温度的采集由DS18B20构成;显示部份由LCD液晶显示屏显示。 2.3 主要单元电路的设计 2.3.1 单片机主控制模块的设计

ATS52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3, MCS-51

单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能地作输出或输入。

单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端。 如图2 所示:

7

河南理工大学万方科技学院单片机课程设计报告

图2 主控制系统

2.3.2 时钟电路模块的设计

图.3示出DS1302的引脚排列,其中Vcc1为后备电源,Vcc2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768KHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RSTS置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。中有在SCLK 为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。SCLK始终是输入端。

图3 DS1302的引脚图

2.3.3 电路原理及说明

(1) 时钟芯片DS1302的工作原理:

DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图4所示。DS1302的控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0,位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。表.2为DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停

8

河南理工大学万方科技学院单片机课程设计报告

止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。 (2) DS1302的控制字节:

DS1302控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出 (3) 数据输入输出(I/O)

在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。 (4) DS1302的寄存器

DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。

此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。

2.3.4 显示模块的设计

如图.4为LCD显示模块,和最小系统上的连线一样,无需修改。

9

河南理工大学万方科技学院单片机课程设计报告

图4 LCD液晶显示屏显示模块

10

河南理工大学万方科技学院单片机课程设计报告

3 系统的软件设计

3.1 程序流程框图

开始 初始化 读日期、时间 写日期、时间 显示子程序 开关控制子程序

日期修改子程序 时间修改子程序 显示结果 返回

图5主程序流程图

11

河南理工大学万方科技学院单片机课程设计报告

图6 时间调整程序流程图

12

河南理工大学万方科技学院单片机课程设计报告

4 Proteus软件仿真

5.1Proteus运行流程

Proteus ISIS的工作界面是一种标准的Windows界面,如图所示。 包括:标题栏、主菜单、标准工具栏、绘图工具栏、状态栏、对象选择按钮、预览对象方位控制按钮、仿真进程控制按钮、预览窗口、对象选择器窗口、图形编辑窗口。

运行Proteus程序后,进入软件的主界面。通过左侧工具栏中的P(从库中选择元件命令)命令,在Pick Devices 左侧窗口中选择所需元件的关键字,然后放置元件并调整方向和位置以及参数设置,最后进行连线。 5.2Proteus功能仿真

Proteus仿真效果

最后载入hex文件后可以进行模拟仿真,可以全速运行也可以单步调试运行。

13

河南理工大学万方科技学院单片机课程设计报告

上电后后LED显示:

调节秒钟:

调节分钟:

调节时钟:

调节星期:

图10

图11

图12

图13

14

河南理工大学万方科技学院单片机课程设计报告

图14

调节日期:

调节月份:

调节年份:

点击确定键显示:

图15

图16

图17

图18

15

河南理工大学万方科技学院单片机课程设计报告

按键功能自上而下依次为:选择修改项键、增大键、减小键、确定键。

图19

5课程设计总结与体会

通过这次的单片机课程设计使我学到了很多知识,真真正正的把以前书本上学到的知识用于实践中,在此次课程设计过程中我花费了很大力气,查找了网络,图书馆,期刊室相关的资料,用了近一个星期的时间才刚刚完成任务,在查找的同时既找到了自己所需要的知识,又拓展了眼界,使我深受启发感触良多。 在刚接到这个题目时,我想了许久比较了很多器件,最终定了题目万年历。但是在随后的设计中,又遇到了更多的难题,程序不正确,出不来HEX文件,器件不工作。于是我问了许多会做的同学,在他们的指导下一步一步的寻找错误原因,查漏补缺。运行文件后又有器件不会亮,经过耐心寻找发现器件型号选择不正确。经过7天不懈的努力,在老师同学的细心指导下,我的万年历终于做了出来。在灯亮的那一瞬间我兴奋极了,觉得这几天的努力全值了。在此次设计中,我知道了做凡事要有一颗平常的心,不要想着走捷径,一步一脚印。也练就了我的耐心,做什么事都在有耐心。此次课程设计中学到了很多很多东西,而这是最重要的。

这次课程设计大大提高了我动手能力,加强了我对单片机电子电路的认识,对元器件的工作原理有了更深一步的了解。

16

河南理工大学万方科技学院单片机课程设计报告

参考文献

[1]陈正振 编 电子电路设计与制作 广西交通职业技术学院信息工程系 2007 [2]余发山.单片机原理及及应用技术.中国矿业大学出版社 2003.12 [3]杨凌霄.微型计算机原理及应用.中国矿业大学出版社 2004.08 [4]何立民.单片机应用技术选编.北京航空航天大学出版社 2000.08 [5]万光毅.单片机实验与实践教程.北京航空航天大学出版社 2005.01

17

河南理工大学万方科技学院单片机课程设计报告

附录一:系统程序

#include #include //#include \"LCD1602.h\" //#include \"DS1302.h\" #define uint unsigned int #define uchar unsigned char

sbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚 sbit ACC0 = ACC^0; sbit ACC7 = ACC^7;

char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数

sbit Set = P2^0; //模式切换键 sbit Up = P2^1; //加法按钮 sbit Down = P2^2; //减法按钮

sbit out = P2^3; //立刻跳出调整模式按钮 char done,count,temp,flag,up_flag,down_flag; uchar TempBuffer[5],week_value[2]; void show_time(); //液晶显示程序

/***********1602液晶显示部分子程序****************/

//Port Definitions********************************************************** sbit LcdRs sbit LcdRw

= P2^5; = P2^6;

//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

sbit LcdEn = P2^7; sfr DBPort = 0x80; //内部等待函数

************************************************************************** unsigned char LCD_Wait(void) {LcdRs=0;LcdRw=1;

_nop_();LcdEn=1; _nop_(); LcdEn=0;return DBPort; }

//向LCD写入命令或数据

************************************************************ #define LCD_COMMAND #define LCD_DATA

0 // Command 1 // Data

0x02 // 光标返回原点

#define LCD_CLEAR_SCREEN 0x01 // 清屏 #define LCD_HOMING

void LCD_Write(bit style, unsigned char input)

18

河南理工大学万方科技学院单片机课程设计报告

{LcdEn=0;LcdRs=style;LcdRw=0; LcdEn=1; LcdEn=0; }

_nop_();DBPort=input; _nop_();//注意顺序

_nop_();//注意顺序 _nop_();LCD_Wait();

//设置显示模式************************************************************ #define LCD_SHOW #define LCD_HIDE

0x04 //显示开 0x00 //显示关 0x02

//显示光标

0x00 //无光标 0x01 //光标闪动 0x00 //光标不闪动

}

#define LCD_CURSOR #define LCD_FLASH

#define LCD_NO_CURSOR #define LCD_NO_FLASH

void LCD_SetDisplay(unsigned char DisplayMode) {LCD_Write(LCD_COMMAND, 0x08|DisplayMode); #define LCD_AC_UP #define LCD_MOVE

0x02

0x00 // default 0x00 //default 0x01 // 画面可平移

//设置输入模式************************************************************ #define LCD_AC_DOWN #define LCD_NO_MOVE

void LCD_SetInput(unsigned char InputMode) {LCD_Write(LCD_COMMAND, 0x04|InputMode);}

//初始化LCD************************************************************ void LCD_Initial() {LcdEn=0;

LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵 LCD_Write(LCD_COMMAND,0x38);

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}

//液晶字符输入的位置************************ void GotoXY(unsigned char x, unsigned char y) {if(y==0)LCD_Write(LCD_COMMAND,0x80|x);

if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));} //将字符输出到液晶显示 void Print(unsigned char *str) {while(*str!='\\0')

{LCD_Write(LCD_DATA,*str);str++;}}

/***********DS1302时钟部分子程序******************/ typedef struct __SYSTEMTIME__

19

河南理工大学万方科技学院单片机课程设计报告

{

unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[11]; unsigned char TimeString[9];

}SYSTEMTIME; //定义的时间类型 SYSTEMTIME CurrentTime; #define AM(X) #define PM(X)

X

(X+12) // 转成24小时制

#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间 #define DS1302_MINUTE 0x82 #define DS1302_HOUR #define DS1302_WEEK #define DS1302_DAY #define DS1302_MONTH #define DS1302_YEAR

0x84 0x8A 0x86 0x88 0x8C

void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) { unsigned char i;ACC = d; for(i=8; i>0; i--) {DS1302_IO = ACC0; unsigned char DS1302OutputByte(void) { unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; return(ACC); }

void Write1302(unsigned char ucAddr, unsigned char ucDa) 要写的数据 { DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1;

DS1302InputByte(ucAddr); DS1302_CLK = 1;

// 地址,命令

DS1302InputByte(ucDa); // 写1Byte数据

//ucAddr: DS1302地址, ucData:

//相当于汇编中的 RRC

ACC7 = DS1302_IO; DS1302_CLK = 1;DS1302_CLK = 0; }

//相当于汇编中的 RRC

//实时时钟读取一字节(内部函数)

DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } }

20

河南理工大学万方科技学院单片机课程设计报告

DS1302_RST = 0;

} unsigned char Read1302(unsigned char ucAddr) { unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1;

DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);}

void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组

{unsigned char ReadValue;

ReadValue = Read1302(DS1302_SECOND);

Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE);

Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR);

Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY);

Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK);

Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH);

Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR);

Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

}

//读取DS1302某地址的数据

void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]

{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 { Time->DateString[0] = '2';

Time->DateString[1] = '0';

Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0';}

else{ Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' ';}

21

河南理工大学万方科技学院单片机课程设计报告

Time->DateString[4] = '/'; if(hide_month<2)

{Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0';}

else{ Time->DateString[5] = ' '; Time->DateString[6] = ' ';} Time->DateString[7] = '/'; if(hide_day<2)

{Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0';}

else{Time->DateString[8] = ' ';Time->DateString[9] = ' '; } if(hide_week<2){

week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里, else { week_value[0] = ' ';} week_value[1] = '\\0';

Time->DateString[10] = '\\0'; //字符串末尾加 '\\0' ,判断结束字符}

跟年,月,日的分开存放,因为等一下要在最后显示}

void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[]; { if(hide_hour<2)

{ Time->TimeString[0] = Time->Hour/10 + '0';

Time->TimeString[1] = Time->Hour%10 + '0';}

else{ Time->TimeString[0] = ' ';Time->TimeString[1] = ' ';} Time->TimeString[2] = ':';

Time->TimeString[4] = Time->Minute%10 + '0';}

else {Time->TimeString[3] = ' ';Time->TimeString[4] = ' '; } Time->TimeString[5] = ':';

if(hide_min<2){ Time->TimeString[3] = Time->Minute/10 + '0';

if(hide_sec<2)

{Time->TimeString[6] = Time->Second/10 + '0';

Time->TimeString[7] = Time->Second%10 + '0';} Time->DateString[8] = '\\0';}

else{Time->TimeString[6] = ' ';Time->TimeString[7] = ' '; } void Initial_DS1302(void) //时钟芯片初始化

{ unsigned char Second=Read1302(DS1302_SECOND);

if(Second&0x80) //判断时钟芯片是否关闭

Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55 Write1302(0x88,0x07);Write1302(0x86,0x25); {Write1302(0x8e,0x00); //写入允许

22

河南理工大学万方科技学院单片机课程设计报告

Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59); Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}}

void Delay1ms(unsigned int count)

{unsigned int i,j;for(i=0;iuint i;for(;delay>0;delay--){for(i=0;i<62;i++) //1ms延时. {;}}}

void outkey() //跳出调整模式,返回默认显示 { uchar Second;if(out==0) { mdelay(8); count=0;

hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0; Second=Read1302(DS1302_SECOND); Write1302(0x80,Second&0x7f);

Write1302(0x8E,0x80); //禁止写入 done=0; while(out==0); }}

Write1302(0x8e,0x00); //写入允许

/////////////////////////////////////////////////////////////////////////////// void Upkey()//升序按键 {

Up=1;if(Up==0)

{

mdelay(8); switch(count) {case 1:

temp=Read1302(DS1302_SECOND); //读取秒数 temp=temp+1; //秒数加1

up_flag=1; //数据调整后更新标志 if((temp&0x7f)>0x59) //超过59秒,清零 temp=0; case 2:

temp=Read1302(DS1302_MINUTE); //读取分数 temp=temp+1; //分数加1 up_flag=1;

if(temp>0x59) //超过59分,清零 temp=0;break; case 3:

temp=Read1302(DS1302_HOUR); //读取小时数 temp=temp+1; //小时数加1 up_flag=1;

break;

23

河南理工大学万方科技学院单片机课程设计报告

if(temp>0x23) //超过23小时,清零 temp=0; break;

case 4:

temp=Read1302(DS1302_WEEK); //读取星期数

temp=temp+1; //星期数加1 if(temp>0x7) temp=1; break;

up_flag=1;

case 5:

temp=temp+1; //日数加1 if(temp>0x31) temp=1; break;

temp=Read1302(DS1302_DAY); //读取日数 up_flag=1;

case 6:

temp=temp+1; //月数加1 if(temp>0x12) temp=1; break;

temp=Read1302(DS1302_MONTH); //读取月数 up_flag=1;

case 7:

temp=temp+1; //年数加1 if(temp>0x85) temp=0; break;

temp=Read1302(DS1302_YEAR); //读取年数 up_flag=1;

default:break;}

while(Up==0); }}

/////////////////////////////////////////////////////////////////////////////// void Downkey()//降序按键 {

Down=1;if(Down==0)

{ mdelay(8);

switch(count) {case 1:

24

河南理工大学万方科技学院单片机课程设计报告

temp=Read1302(DS1302_SECOND); //读取秒数

temp=temp-1;

//秒数减1

down_flag=1; //数据调整后更新标志

if(temp==0x7f) //小于0秒,返回59秒 temp=0x59; break;

case 2:

temp=temp-1; //分数减1 if(temp==-1)

temp=0x59; //小于0秒,返回59秒 break;

temp=Read1302(DS1302_MINUTE); //读取分数 down_flag=1;

case 3:

temp=temp-1; //小时数减1 if(temp==-1) temp=0x23; break;

temp=Read1302(DS1302_HOUR); //读取小时数 down_flag=1;

case 4:

temp=temp-1; //星期数减1 if(temp==0) temp=0x7;; break;

temp=Read1302(DS1302_WEEK); //读取星期数 down_flag=1;

case 5:

temp=temp-1; //日数减1 if(temp==0) temp=31; break;

temp=Read1302(DS1302_DAY); //读取日数 down_flag=1;

case 6:

temp=temp-1; //月数减1

temp=Read1302(DS1302_MONTH); //读取月数 down_flag=1;

25

河南理工大学万方科技学院单片机课程设计报告

if(temp==0) temp=12; break;

case 7:

temp=temp-1; //年数减1 if(temp==-1) temp=0x85; break;

temp=Read1302(DS1302_YEAR); //读取年数 down_flag=1;

default:break;}while(Down==0); }}

void Setkey()//模式选择按键 {Set=1;if(Set==0)

{ mdelay(8); count=count+1; //Setkey按一次,count就加1

done=1;

//进入调整模式

while(Set==0); }} void keydone()//按键功能执行 { uchar Second;

if(flag==0) //关闭时钟,停止计时

{ Write1302(0x8e,0x00); //写入允许 temp=Read1302(0x80); Write1302(0x80,temp|0x80);

Write1302(0x8e,0x80); //禁止写入

//扫描模式切换按键

//count=1,调整秒 //扫描跳出按钮

flag=1; } Setkey();

{case 1:do

switch(count) { outkey();

Upkey(); //扫描加按钮 Downkey(); //扫描减按钮

if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据 {

Write1302(0x8e,0x00); //写入允许

Write1302(0x80,temp|0x80); //写入新的秒数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; }

hide_sec++; //位闪计数

26

河南理工大学万方科技学院单片机课程设计报告

if(hide_sec>3) hide_sec=0;

}while(count==2);break;

//count=2,调整分

show_time(); //液晶显示数据

case 2:do

{ hide_sec=0;

outkey(); Upkey(); Downkey(); if(temp>0x60) temp=0;

if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x82,temp); //写入新的分数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_min++; if(hide_min>3) hide_min=0; }while(count==3);break;

//count=3,调整小时

show_time();

case 3:do

{ hide_min=0;

outkey(); Upkey(); Downkey();

if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x84,temp); //写入新的小时数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_hour++; if(hide_hour>3) hide_hour=0; }while(count==4);break;

show_time();

27

河南理工大学万方科技学院单片机课程设计报告

case 4:do

//count=4,调整星期

{ hide_hour=0;

outkey(); Upkey(); Downkey();

if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x8a,temp); //写入新的星期数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0;} hide_week++; if(hide_week>3) hide_week=0; }while(count==5);break;

//count=5,调整日

show_time();

case 5:do

{hide_week=0;

outkey(); Upkey(); Downkey();

if(up_flag==1||down_flag==1) {Write1302(0x8e,0x00); //写入允许 Write1302(0x86,temp); //写入新的日数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_day++; if(hide_day>3) hide_day=0; }while(count==6);break;

//count=6,调整月

show_time();

case 6:do

{ hide_day=0;

outkey(); Upkey(); Downkey();

if(up_flag==1||down_flag==1)

28

河南理工大学万方科技学院单片机课程设计报告

{ Write1302(0x8e,0x00); //写入允许 Write1302(0x88,temp); //写入新的月数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_month++; if(hide_month>3) hide_month=0; }while(count==7);break;

//count=7,调整年

show_time();

case 7:do

{ hide_month=0;

outkey(); Upkey(); Downkey();

if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x8c,temp); //写入新的年数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_year++; if(hide_year>3) hide_year=0; }while(count==8);break;

show_time();

case 8: count=0;hide_year=0; //count8, 跳出调整模式,返回默认显示状态

Second=Read1302(DS1302_SECOND); Write1302(0x80,Second&0x7f);

Write1302(0x8E,0x80); //禁止写入

done=0;

break; //count=7,开启中断,标志位置0并退出 default:break; }}

Write1302(0x8e,0x00); //写入允许

void show_time() //液晶显示程序

{ DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据 TimeToStr(&CurrentTime); //时间数据转换液晶字符 DateToStr(&CurrentTime); //日期数据转换液晶字符

29

河南理工大学万方科技学院单片机课程设计报告

GotoXY(0,1);

Print(CurrentTime.TimeString); //显示时间 GotoXY(0,0);

Print(CurrentTime.DateString); //显示日期 GotoXY(15,0);

Print(week_value); //显示星期 GotoXY(11,0);

Print(\"Week\"); //在液晶上显示 字母 week Delay1ms(400); //扫描延时} main()

{ flag=1; //时钟停止标志 LCD_Initial(); //液晶初始化 Initial_DS1302(); //时钟芯片初始化 up_flag=0; down_flag=0;

done=0; //进入默认液晶显示 while(1)

{ while(done==1) keydone(); //进入调整模式

while(done==0)

{ show_time(); //液晶显示数据 flag=0; Setkey();

}

} }

30

//扫描各功能键

河南理工大学万方科技学院单片机课程设计报告

附录二:系统电路图

31

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务