推荐-基于51单片机控制的语音报时万年历课程设计1 精品
- 格式:doc
- 大小:306.00 KB
- 文档页数:35
课程设计说明书设计题目:基于单片机的万年历设计毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。
尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得及其它教育机构的学位或学历而使用过的材料。
对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。
作者签名:日期:指导教师签名:日期:使用授权说明本人完全了解大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。
作者签名:日期:学位论文原创性声明本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。
除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。
对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。
本人完全意识到本声明的法律后果由本人承担。
作者签名:日期:年月日学位论文版权使用授权书本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。
本人授权大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
涉密论文按学校规定处理。
作者签名:日期:年月日导师签名:日期:年月日注意事项1.设计(论文)的内容包括:1)封面(按教务处制定的标准封面格式制作)2)原创性声明3)中文摘要(300字左右)、关键词4)外文摘要、关键词5)目次页(附件不统一编入)6)论文主体部分:引言(或绪论)、正文、结论7)参考文献8)致谢9)附录(对论文支持必要时)2.论文字数要求:理工类设计(论文)正文字数不少于1万字(不包括图纸、程序清单等),文科类论文正文字数不少于1.2万字。
课程设计基于51单片机电子闹钟或万年历的设计目录目录 (1)1.项目背景 (3)1.1 项目研究的目的和意义 (3)1.2课题研究的容 (3)2.方案的选择和和论证 (4)2.1 单片机型号的选择 (4)2.2 按键的选择 (4)2.3 显示器的选择 (4)2.4 计时部分的选择 (5)2.5 发音部分的设计 (5)2.6电路设计最终方案 (5)3. AT89C52单片机简介 (6)3.1单片机基本特性 (6)3.2单片机部结构图 (6)3.3 单片机I/O引脚结构 (6)3.3.1 P0口 (6)3.3.2 P1口 (7)3.3.3 P2口 (7)3.3.4 P3口 (7)3.4单片机最小系统板 (8)4. 数字电子钟的设计原理和方法 (9)4.1 设计原理 (9)4.2 硬件电路的设计 (9)4.2.1 DS1302时钟芯片 (9)4.2.2 1602 液晶简介 (11)4.2.3 蜂鸣器驱动电路 (12)4.2.4 独立键盘电路 (13)5.软件部分的设计 (14)5.1程序流程图 (14)5.1.1 系统总流程图 (14)5.1.2 DS1302时钟程序流程图 (15)5.1.3 LCD显示程序流程图 (16)5.2程序的设计 (17)5.2.1 DS1302读写程序 (17)5.2.2液晶显示程序 (17)7.心得体会 (20)参考文献 (21)附录一系统原理图 (22)附录二系统程序 (23)1.项目背景1.1 项目研究的目的和意义20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。
时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前的时间。
忘记了要做的事情,当事情不是很重要的时候,这种遗忘无伤大雅。
但是,一旦重要事情,一时的耽误可能酿成大祸。
基于51单片机DS1302万年历课程设计报告课程名称:微机原理课程设计题目:基于DS1302芯片万年历摘要DS1302 是DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31 字节静态RAM,通过简单的串行接口与单片机进行通信实时时钟/日历电路.提供秒、分、时、日、日期.、月、年的信息,每月的天数和闰年的天数可自动调整时钟。
本次课程设计的是使用专门的时钟芯片DS1302在数码管上显示的数字电子钟,并能通过按键对其进行调时和校准以及实现年月日。
DS1302是一种高性能、低功耗、带RAM的实时时钟芯片,它能够对时,分,秒进行精确计时,它与单片机的接口使用同步串行通信,仅用3条线与之相连接,就可以实现STC-51单片机对其进行读写操作,把读出的时间数据送到数码管上显示。
程序运行时,数码管将从当前时间开始显示,通过调节K2键和K3键可以分别对小时和分钟进行调整,调整后,时钟以新的时间为起点继续刷新显示,通过调节K1键可以切换年月日和时钟显示。
关键字:STC-51单片机,DS1302,数码管,动态扫描,调时,切换,秒闪;目录一、设计任务与要求 (4)1.1设计任务 (4)1.2设计要求 (4)1.3发挥部分 (4)1.4创新部分 (4)二、方案总体设计 (5)2.1设计目的 (5)2.2硬件功能描述 (5)2.3设计方案选择 (5)2.4总体设计 (6)2.5总体方案及基本工作原理 (6)三、硬件设计 (7)3.1 STC89C51芯片 (7)3.2电源模块及晶振模块 (7)3.3 DS1302 (8)3.4数码管显示模块 (9)3.5蜂鸣器部分 (10)3.6按键部分 (11)四、软件设计 (13)4.1软件流程图 (13)4.2 软件设计 (13)主函数部分: (13)五、系统仿真和调试 (15)5.1 仿真软件简介 (15)5.2硬件调试 (15)5.3软件调试 (15)5.4使用说明 (16)六、设计总结与体会 (18)6.1学习方面 (18)6.2工作方面 (18)七、参考文献 (19)一、设计任务与要求1.1设计任务DS1302万年历;1.2设计要求利用DS1302生成万年历,时钟可调,通过四位数码管显示,并可实现秒闪功能,同时蜂鸣器闹铃;1.3发挥部分设置按键K3用来切换显示时钟和年月日;1.4创新部分只设置了两个按键K1和K2来调节时分,时钟到24归零,分钟到60归零,分钟有长按迅速调节功能。
一、前言随着电子技术的迅速发展,特别是随大规模集成电路出现,给人类生活带来了根本性的改变。
由其是单片机技术的应用产品已经走进了千家万户。
电子万年历的出现给人们的生活带来的诸多方便。
本设计是基于51系列的单片机进行的电子万年历设计,采用八位数码管显示年月日时分秒及温度信息,具有可调整日期和时间功能。
时间、日期调整由三个按键来实现,并可对闹铃开关进行设置。
日历能显示阳历和阴历年、月、日以及星期、时、分、秒。
设计以STC89C52RC 单片机为核心,构成单片机控制电路;以DS1302时钟芯片作为万年历信号发生器;以DS18B20作为检测温度的传感器。
关键词时钟电钟;DS1302;DS18B20;数码管;单片机。
二、系统概述及总体方案2.1系统概述本电子万年历采用单片机控制技术和数码管显示方案,可以很好的完成万年历和实时温度显示。
它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
2.2总体方案2.2.1单片机芯片:采用AT89S52,片内ROM全都采用Flash ROM;能以3V的超低压工作;同时也与MCS-51系列单片机完全相同,该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用AT89S52作为主控制系统.2.2.2 时钟芯片:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA.且同组同学已从Maxim申请到了这种芯片,所以本设计采用了这种芯片。
《单片机应用实训》课程设计报告姓名:班级:指导老师:实习时间:基于51单片机的数字万年历设计摘要:利用单片机、DS1302芯片、DS18B20芯片搭建一个数字万年历模块,编写程序,实现了年、月、日、时、分、秒计数,温度测量、时钟报警等功能。
关键词: STC89C51 数字时钟一、 实训目的电子时间显示器现在在任何地方都有涉及到,例如电子表和商场的时间显示等等,所以它是一种既方便又实用的技术,而我们所做的万年历则是在它的基础上做出来的,通过万年历的制作,我们可以进一步了解计数器的使用,了解各个进制之间的转换,以及其他的任意进制计数器的构成方法等,并且进一步了解DS1302芯片、DS18B20芯片的使用等。
二、总体设计方案根据项目任务,该系统采用STC89C51为控制核心,以电子大赛开发板为实验平台,利用各种芯片实现相应功能,三、硬件设计1、单片机最小系统STC89C52为40引脚双列直插芯片,有四个I/O 口P0,P1,P2,P3,每一条I/O 线都能独立地作输出或输入。
单片机的最小系统如下图所示,18引脚和19引脚接晶振电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。
第9引脚为复位输入端,接上电容,电阻及开关后够成上电复位电路,20引脚为接地端,40引脚为电源端。
时钟振荡电路用于产生单片机正常工作时所需要的时钟信号,电路由两个22pF的瓷片电容和一个12MHz的晶振组成,并接入到单片机的XTAL1和XTAL2引脚处 使单片机工作于内部振荡模式。
此电路在加电后延迟大约10ms振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率决定。
时钟振荡电路如下图所示。
复位电路由电阻和极性电容组成,如下图所示,通过高电平使单片机复位,在时钟电路开始工作后,当高电平的时间超过大约2us时,即可实现复位。
目录目录............................................... 错误!未定义书签。
1.项目背景......................................... 错误!未定义书签。
项目研究的目的和意义.......................... 错误!未定义书签。
课题研究的内容................................. 错误!未定义书签。
2.方案的选择和和论证............................... 错误!未定义书签。
单片机型号的选择.............................. 错误!未定义书签。
按键的选择.................................... 错误!未定义书签。
显示器的选择.................................. 错误!未定义书签。
计时部份的选择................................ 错误!未定义书签。
发音部份的设计................................ 错误!未定义书签。
电路设计最终方案............................... 错误!未定义书签。
3. AT89C52单片机简介.............................. 错误!未定义书签。
单片机大体特性................................. 错误!未定义书签。
单片机内部结构图............................... 错误!未定义书签。
单片机I/O引脚结构............................ 错误!未定义书签。
P0口..................................... 错误!未定义书签。
洛阳理工学院课程设计报告课程名称单片机原理与应用设计题目基于STC89C51万年历得设计与实现专业物联网工程班级学号姓名完成日期大约在冬季目录摘要 (1)一、设计目标与内容 (2)1、1设计目标 (2)1、2 设计内容 (2)1、3设计要求 (2)1、4 本章小结 (2)二、系统设计 (3)2、1 电路设计框图 (3)2、2 系统硬件概述 (3)2、3 主要单元电路得设计 (4)2、3、1 时钟电路模块得设计 (4)2、3、2温度传感器电路设计 (5)2、3、3显示模块得设计 (7)2、4本章小结 (7)三、系统得软件设计 (7)3、1程序流程图 (7)3、1、1 系统总流程图 (7)3、1、2 温度程序流程图 (8)3、1、3 DS1302时钟程序流程图 (8)3、1、4 LCD显示程序流程图 (9)3、2程序得设计 (10)3、2、1 DS18B20测温程序 (10)3、2、2 DS1302读写程序 (11)3、2、3液晶显示程序 (13)3、3本章小结 (13)四、仿真与调试 (14)4、1 Keil软件调试流程 (14)4、2 Proteus软件运行流程 (16)4、3本章小结 (16)总结 (16)基于STC89C51万年历得设计与实现摘要古人依靠日冕、漏刻记录时间,而随着科技得发展,电子万年历已经成为日渐流行得日常计时工具。
本文研究得万年历系统拟用STC89C52单片机控制,以DS1302时钟芯片计时、DS18B20采集温度、1602液晶屏显示。
系统主要由温度传感器电路,单片机控制电路,显示电路以及校正电路四个模块组成。
本文阐述了系统得硬件工作原理,所应用得各个接口模块得功能以及其工作过程,论证了设计方案理论得可行性。
系统程序采用C语言编写,经Keil软件进行调试后在Proteus软件中进行仿真,可以显示年、月、日、星期、时、分、秒与温度并具有校准功能与与即时时间同步得功能。
实验结果表明此万年历实现后具有读取方便、显示直观、功能多样、电路简洁等诸多优点,符合电子仪器仪表得发展趋势,具有广阔得市场前景。
单片机课程实训SCM PRACTICAL TRAINING目录第一部分课程设计任务书 (1)一、课程设计题目 (1)二、课程设计时间 (1)三、实训提交方式 (1)四、设计要求 (1)第二部分课程设计报告 (2)一、单片机发展概况 (2)二、MCS-51单片机系统简介 (2)三、设计思想 (3)四、硬件电路设计 (3)1. 总体设计 (3)2. 晶振电路 (4)3. 复位电路 (4)4. DS1302时钟电路 (5)5. 温度采集系统电路 (5)6. 按键调整电路 (6)7. 闹钟提示电路 (6)五、软件设计框图 (7)六、程序源代码 (8)1. 主程序 (8)2. 温度控制程序 (11)3. 日历设置程序 (13)4. 时钟控制程序 (18)5. 显示设置程序 (20)七、结束语 (23)八、课程设计小组分工 (23)九、参考文献 (23)第一部分课程设计任务书一、课程设计题目用中小规模集成芯片设计制作万年历。
二、课程设计时间五天三、实训提交方式提交实训设计报告电子版与纸质版四、设计要求(1)显示年、月、日、时、分、秒和星期,并有相应的农历显示。
(2)可通过键盘自动调整时间。
(3)具有闹钟功能。
(4)能够显示环境温度,误差小于±1℃(5)计时精度:月误差小于20秒。
第二部分课程设计报告一、单片机发展概况单片机诞生于20世纪70年代末,它的发展史大致可分为三个阶段:第一阶段(1976-1978):初级单片机微处理阶段。
该时期的单片机具有 8 位CPU,并行 I/O 端口、8 位时序同步计数器,寻址范围 4KB,但是没有串行口。
第二阶段(1978-1982):高性能单片机微机处理阶段,该时期的单片机具有I/O 串行端口,有多级中断处理系统,15 位时序同步技术器,RAM、ROM 容量加大,寻址范围可达 64KB。
第三阶段(1982-至今)位单片机微处理改良型及 16 位单片机微处理阶段民用电子产品、计算机系统中的部件控制器、智能仪器仪表、工业测控、网络与通信的职能接口、军工领域、办公自动化、集散控制系统、并行多机处理系统和局域网络系统。
课程设计说明书课程名称:《单片机技术》设计题目:基于单片机的万年历设计院(部):电子信息与电气工程学院学生:学号:专业班级:电子信息工程10-1指导教师:2013年 05 月 17 日课程设计任务书万年历设计摘要:以AT89S52为主控芯片设计了一个带温度显示的万年历电路系统,该电路具有年、月、日、星期、时、分、秒、闹钟显示和调整,并且还能显示温度和按键提示音、整点鸣叫、定时闹钟鸣叫等功能。
本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成。
温度采集选用DS18B20芯片,数据显示采用1602A液晶显示模块,主芯片利用定时中断产生时间,控制着液晶的显示更新、温度的实时变化以及按键的读取处理,而对于闹钟,实际上就是时间里的一个嵌套程序。
时间和闹钟的值由按键调整设置,采用通用的二十四小时制。
关键词:单片机;液晶显示屏;温度传感器;时钟芯片目录1. 设计背景 (1)1.1 概述 (1)1.2 万年历设计目的 (1)2.设计方案 (2)2.1 按键控制模块设计与论证 (2)2.2 时钟模块设计与论证 (2)2.3 显示模块模块设计与论证 (3)3. 方案实施 (4)3.1系统整体框图 (4)3.2原理图设计 (4)3.2.1 单片机最小系统模块 (4)3.2.2 电源模块 (5)3.2.3 时钟芯片DS1302模块 (6)3.2.4温度采集DS18B20模块 (6)3.2.5 闹钟模块 (7)3.2.6 LCD1602显示模块 (8)3.2.7 按键模块 (9)3.3 软件设计 (9)3.4 系统仿真 (10)3.5系统制作 (11)4. 结果与结论 (12)4.1 结果 (12)4.2 结论 (12)5. 收获与致 (13)6. 参考文献 (14)7. 附件 (15)7.1 原理图 (15)系统电路图如图7.1所示: (15)7.2 元器件清单 (15)7.3 实物图 (16)7.3.1 正常工作 (16)7.3.2 调试状态 (17)7.3.3 闹钟设置状态 (18)1. 设计背景1.1 概述如今万年历已经在人们生活中广泛的使用,它不仅是记录日期和时间的工具,而且也成为了一种装饰品。
基于51单片机电子万年历设计大连民族学院机电信息工程学院自动化系单片机系统课程设计报告题目:电子万年历专业:自动化班级:106学生姓名:指导教师:设计完成日期:2012年11月30日1任务分析和性能指标1.1任务分析设计一个具有报时功能、停电正常运行(来电无需校时)、闹钟功能、带有年月日、时分秒及星期显示的电子日历。
电子万年历是日常生活中常见的小型电子产品,其形式多种多样,小到带有日期的电子腕表,大到公共场所悬挂的大型电子日历,此外,眼下我们还常能在宾馆、饭店等场所见到一种带有年、月、日、时、分、秒、星期甚至节气等信息的电子日历牌。
电子日历的主要功能是给人们提供时间和日期信息,无论其形式如何,从外部都可分为显示和校准两部分。
为使电子日历协调工作,整个系统从功能上可分为实时时钟、显示和键盘三个模块,分别完成时间和日期的计算以及人机交互的管理等。
1.2性能指标实时时钟(RTC:Real Time Clock)是系统的核心,其运行精度直接影响产品质量。
实时时钟的实现有两种方案可选,一是利用单片机系统时钟和中断完成时间和日期的计算;二是利用专用时钟芯片。
前者不用附加芯片,系统简单,但是累计误差较大,只有短时计时才可使用。
长时间计时一般都采用后者。
后者采用32.768KHz晶体振荡器振作为脉冲源,内部的15位计数器刚好产生标准秒脉冲。
该类芯片除时钟计时外,还有年月日和星期的计算功能,并且还可计算闰年。
芯片初始化后可脱离CPU自动运行,有些芯片内部带有电池,出厂时芯片即开始运行。
专用时钟芯片的种类很多,与CPU的通信方式有并行,也有串行。
常见的芯片有DALLAS 公司生产的DS1302和DS12C887,前者为串行,需要外加后备电池;后者为并行,芯片内置锂电池和晶体振荡器,无外加电源的情况下可运行10年。
此外,还有许多时钟芯片,如Epson、Holtek、深圳兴威帆等公司都推出自己的时钟芯片。
这次我们选用的芯片是DS12C887。
洛阳理工学院课程设计报告课程名称单片机原理与应用设计题目基于STC89C51万年历的设计与实现专业物联网工程班级学号姓名完成日期大约在冬季目录摘要 (2)一、设计目标与内容 (3)1.1设计目标 (3)1.2 设计内容 (3)1.3设计要求 (3)1.4 本章小结 (3)二、系统设计 (3)2.1 电路设计框图 (3)2.2 系统硬件概述 (4)2.3 主要单元电路的设计 (4)2.3.1 时钟电路模块的设计 (4)2.3.2温度传感器电路设计 (6)2.3.3显示模块的设计 (8)2.4本章小结 (8)三、系统的软件设计 (9)3.1程序流程图 (9)3.1.1 系统总流程图 (9)3.1.2 温度程序流程图 (9)3.1.3 DS1302时钟程序流程图 (10)3.1.4 LCD显示程序流程图 (11)3.2程序的设计 (11)3.2.1 DS18B20测温程序 (11)3.2.2 DS1302读写程序 (13)3.2.3液晶显示程序 (14)3.3本章小结 (15)四、仿真与调试 (15)4.1 Keil软件调试流程 (15)4.2 Proteus软件运行流程 (17)4.3本章小结 (18)总结 (18)基于STC89C51万年历的设计与实现摘要古人依靠日冕、漏刻记录时间,而随着科技的发展,电子万年历已经成为日渐流行的日常计时工具。
本文研究的万年历系统拟用STC89C52单片机控制,以DS1302时钟芯片计时、DS18B20采集温度、1602液晶屏显示。
系统主要由温度传感器电路,单片机控制电路,显示电路以及校正电路四个模块组成。
本文阐述了系统的硬件工作原理,所应用的各个接口模块的功能以及其工作过程,论证了设计方案理论的可行性。
系统程序采用C语言编写,经Keil软件进行调试后在Proteus软件中进行仿真,可以显示年、月、日、星期、时、分、秒和温度并具有校准功能和与即时时间同步的功能。
实验结果表明此万年历实现后具有读取方便、显示直观、功能多样、电路简洁等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
课程名称:《单片机技术》设计题目:基于单片机地万年历设计院(部):电子信息与电气工程学院学生姓名:学号:专业班级:电子信息工程10-1指导教师:2013年 05 月 17 日课程设计任务书万年历设计摘要:以AT89S52为主控芯片设计了一个带温度显示地万年历电路系统,该电路具有年、月、日、星期、时、分、秒、闹钟显示和调整,并且还能显示温度和按键提示音、整点鸣叫、定时闹钟鸣叫等功能.本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成. 温度采集选用DS18B20芯片,数据显示采用1602A液晶显示模块,主芯片利用定时中断产生时间,控制着液晶地显示更新、温度地实时变化以及按键地读取处理,而对于闹钟,实际上就是时间里地一个嵌套程序.时间和闹钟地值由按键调整设置,采用通用地二十四小时制.关键词:单片机;液晶显示屏;温度传感器;时钟芯片目录1. 设计背景 01.1 概述 01.2 万年历设计目地 02.设计方案 (1)2.1 按键控制模块设计与论证 (1)2.2 时钟模块设计与论证 (1)2.3 显示模块模块设计与论证 (2)3. 方案实施 (2)3.1系统整体框图 (2)3.2原理图设计 (3)3.2.1 单片机最小系统模块 (3)3.2.2 电源模块 (4)3.2.3 时钟芯片DS1302模块 (4)3.2.4温度采集DS18B20模块 (5)3.2.5 闹钟模块 (6)3.2.6 LCD1602显示模块 (6)3.2.7 按键模块 (7)3.3 软件设计 (8)3.4 系统仿真 (8)3.5系统制作 (9)4. 结果与结论 (10)4.1 结果 (10)4.2 结论 (10)5. 收获与致谢 (11)6. 参考文献 (12)7. 附件 (13)7.1 原理图 (13)系统电路图如图7.1所示: (13)7.2 元器件清单 (13)7.3 实物图 (14)7.3.1 正常工作 (14)7.3.2 调试状态 (15)7.3.3 闹钟设置状态 (16)1. 设计背景1.1 概述如今万年历已经在人们生活中广泛地使用,它不仅是记录日期和时间地工具,而且也成为了一种装饰品.现在地万年历可以说是多种多样,外观精美.放在家里既可以计时也可作为风景壁画,因此越来越受到大众消费者地喜爱.1.2万年历设计目地随着电子技术地发展,人类不断研究,不断创新纪录.万年历目前已经不再局限于以书本形式出现.以电脑软件或者电子产品形式出现地万年历被称为电子万年历.与传统书本形式地万年历相比,电子万年历得到了越来越广泛地应用,采用电子时钟作为时间显示已经成为一种时尚.目前市场上各式各样地电子时钟数不胜数,但多数是只针对时间显示,功能单一不能满足人们日常生活需求.本文提出了一种基于A T89S52单片机地万年历设计方案,利采用一个LCD显示.本方案以A T89S52单片机作为主控核心,与时钟芯片DS1302、温度芯片DS18B20、闹钟模块、按键、LCD显示等模块组成硬件系统.在硬件系统中设有5个独立按键和一个LCD显示器,能显示丰富地信息,根据使用者地需要可以随时对时间进行校准、选择时间、温度显示、综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表地发展趋势,具有广阔地市场前景.2.设计方案2.1 按键控制模块设计与论证方案一:直接加减:使用7按键,1按键切换闹钟,6按键对时分秒分别加减,控制方式相当简单,但需要较多按键与I/O口,功能一般,成本较高.方案二:矩阵键盘:使用16按键对时分秒直接设置,能最为灵活地对数字钟进行设置,功能强大,但控制方式相对困难,成本较高,需要较多按键与I/O口.方案三:换位调整:使用4按键,1设置闹钟,1键设置调整时间,1键调整,1键确定,此种控制方式相对简单,占用I/O口少,成本低廉,但功能一般.经过反复比较,在3种方案中选取了第3种——换位调整,此方案成本低,功能已经足够满足数字钟地需要,而且硬件软件均比较简单.2.2 时钟模块设计与论证方案一:不使用芯片,采用单片机地定时计数器这种方法原理是利用单片机芯片地定时器来产生固定地时间,模拟时钟地时, 分,秒.如:利用A T80C52芯片,定时器用工作方式1,每50ms产生一个中断,循环20次,即1s周期.每一个周期加1,那么1min为60个周期,1h就是60*60=3600个周期,一天就是3600*24=86400个周期.此方法优点是可以省去一些外围地芯片,但这种方法只能适用于一些要求不是十分精确,不做长期保留地场合.方案二:并行接口时钟芯片 DS12887特点:采用单片机应用系统并行总线(三总线)扩展地接口电路,采用这种接口电路具有操作速度快,编程方便地优点.但是对于80C52单片机来说,低位地址线要通过锁存器输出,还要地址译码器,而且并行口芯片地体积相对较大,会占用较多地空间.方案三:串行接口时钟芯片DS1302芯片主特性:(1)实时时钟具有能计算2100 年之前地秒分时日日期星期月年地能力,还有闰年调整地能力(2) 8 位暂存数据存储RAM(3)串行 I/O 口方式使得管脚数量最少(4)宽范围工作电压2.0~5.5V(5)工作电流 2.0V 时,小于300nA(6)读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式(7)8 脚DIP 封装或可选地8 脚SOIC 封装根据表面装配(8)简单 3 线接口(9)与 TTL 兼容V cc=5V(10)可选工业级温度范围-40~+85优点:串行接口地日历时钟芯片,使用简单,接口容易,与微型计算机连线较少等特点,在单片机系统尤其是手持式信息设备中己得到了广泛地应用.比较以上三种方案地优缺点,综合考虑最终选择串行时钟芯片DS1302.2.3 显示模块模块设计与论证方案一:采用静态显示方法,静态显示模块地硬件制作较复杂及功耗大,要用到多个移位寄存器,但不占用端口,只需两根串口线输出.方案二:采用动态显示方法,动态显示模块地硬件制作简单,段扫描和位扫描各占用一个端口,总需占用单片机14个端口,采用间断扫描法功耗小、硬件成本低及整个硬件系统体积相对减小.方案三:采用LCD地方法,具有硬件制作简单可直接与单片机接口,显示内容多,功耗小,成本低等优点,LCM1602可显示32个字符,采用LCD地缺点是亮度不够.比较以上三种方案:方案一硬件复杂体积大、功耗大;方案二硬件简单、功耗小;方案三硬件简单,显示内容多,功耗小,成本低等.本系统设计要求达到功耗小、体积小、成本低,显示信息多等要求,权衡三种方案,选择方案三.3.方案实施3.1系统整体框图按照系统设计地要求,初步确定系统由电源模块、复位电路、时钟模块、显示模块、按键模块、温度采集模块和蜂鸣器组成,电路系统构成责整体框图如图3.1所示:图3.1 整体框图3.2原理图设计3.2.1 单片机最小系统模块单片机最小系统设计为如图3.2:图3.2 单片机最小系统本设计中选择了内部时钟方式和按键电平复位电路,来构成单片机地最小电路.复位是单片机地初始化操作,单片机在启动运行时,都需要先复位,其作用是使CPU和系统中其他部件都处于一个确定地初始状态,并从这个状态开始工作.此设计中P0口做为输出口用来驱动LCD显示,而P0口内部又没有上拉电阻,所以加上10K上拉电阻.复位电路本设计中地复位电路集手动复位及上电自动复位于一体.1)上电自动复位通过外部复位电路地电容C3地充电来实现,只要电源VCC地上升时间不超过1ms,就可以实现自动上电复位.2)按键手动复位是通过使复位端经电阻与VCC接通而实现地.时钟振荡电路考虑系统运行速度,采用12MHZ地石英晶振,并使用两个小电容作为微调电容.3.2.2 电源模块3.2.3 时钟芯片DS1302模块时钟芯片电路设计如图3.4:图3.4 时钟芯片电路如图3.4所示,其中Vcc1为后备电源,Vcc2为主电源.VCC1在单电源与电池供电地系统中提供低电源并提供低功率地电池备份.VCC2在双电源系统中提供主电源,在这种运用方式中VCC1连接到备份电源,以便在没有主电源地情况下能保存时间信息以及数据.DS1302由VCC1或VCC2 两者中较大者供电.当VCC2大于VCC1+0.2V时,VCC2给DS1302供电.当VCC2小于VCC1时,DS1302由VCC1供电.DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲;DS1302地控制字地位7必须置1,若为0则不能对DS1302进行读写数据.对于位6,若对时间进行读/写时,CK=0,对程序进行读/写时RAM=1.位1至位5指操作单元地地址.位0是读/写操作位,进行读操作时,该位为1;进行写操作时,该位为0.控制字节总是从最低位开始输入/输出地.DS1302地日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行.“WP”是写保护位,在任何地对时钟和RAM地写操作之前,“WP”必须为0.当“WP”为1时,写保护位防止对任一寄存器地写操作.3.2.4温度采集DS18B20模块温度采集电路设计如图3.5所示:图3.5 温度采集电路如3.5图所示,该系统中采用数字式温度传感器DS18B20,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,用P3.7与DS1802地DQ端口连接,V cc接电源,GND接地.DS18B20地读写时序和测温原理与DS1820相同,只是得到地温度值地位数因分辨率不同而不同,且温度转换时地延时时间由2s减为750ms. DS18B20测温原理如图3.6所示.图中低温度系数晶振地振荡频率受温度影响很小,用于产生固定频率地脉冲信号送给计数器1.高温度系数晶振随温度变化其振荡率明显改变,所产生地信号作为计数器2地脉冲输入.计数器1和温度寄存器被预置在-55℃所对应地一个基数值.计数器1对低温度系数晶振产生地脉冲信号进行减法计数,当计数器1地预置值减到0时,温度寄存器地值将加1,计数器1地预置将重新被装入,计数器1重新开始对低温度系数晶振产生地脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值地累加,此时温度寄存器中地数值即为所测温度.3.2.5 闹钟模块闹钟电路如图3.6所示:3.6 闹钟电路我们采用地有源蜂鸣器,由于单片机地输出电流较小所以我们采用PNP形地三极管作为驱动电路,来驱动蜂鸣器发声,当单片机给低电平时蜂鸣器响.3.2.6 LCD1602显示模块显示电路如图3.7所示:图3.7 显示电路LCD1602是指显示地内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字).第1脚:VSS为电源地.第2脚:VDD接5V电源正极.第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高.第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器.第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作.第6脚:E(或EN)端为使能(enable)端.第7~14脚:D0~D7为8位双向数据端.第15~16脚:空脚或背灯电源.15脚背光正极,16脚背光负极.LCD地D0~D7分别接单片机地地P0口,作为数据线,因为P0口内部没有上拉电阻,所以外部另外加上10K地上拉电阻;P2.4—P2.6分别接LCD地RS、RW、E三个控制管脚.3.2.7 按键模块按键电路设计如图3.8所示:图3.8 按键电路本系统用到了5个按键,其中一个用作系统手动复位,另外4个采用独立按键,该种接法查询简单,程序处理简单,可节省CPU资源,按键电路如图3.18所示,4个独立按键分别与AT89S52地P3.0、P3.1、P3.2、P3.3接口相连.对以上4个按键作简要说明:S2——SET 键,S3——UP键,S4——DOWN键,S5——OUT/STOP键.SET 键:按下SET键进入时间校准状态,按一下进入秒调整,两下分调整,依此类推可进行各年月日,时分秒以及星期地校准;UP键:当SET键按下时,UP进行SET选定项(如:小时)地加操作。
中文摘要本设计万年历以AT89C51为控制中心,与温度传感器DS18B20,时钟芯片DS1302综合应用为一体,不仅能够准确显示时间、日期,闹钟设置,环境温度测量及温度高低温报警等功能。
单片机是一种集CPU、RAM、ROM、I/O接口和中断系统等于一体的器件,只需要外加电源和晶振就可实现对数字信息的处理和控制。
单片机与数字万年历相结合,用于时间显示,温度测试等不仅具有控制方便、组态简单和灵活性大等优点,而且可以大幅度提高被检测数值的技术指标,从而能够大大提高产品的质量和数量。
关键词:单片机,温度传感器,C语言,液晶显示ABSTRACTThis design USES AT89C51 as calendar control center, and the temperature sensor DS18B20, the clock DS1302 chip integrated application as a whole, and not only be able to accurately display the time, date, alarm, the environment temperature measurement and high temperature, low temperature alarm functions. SCM is a collection of CPU, RAM, ROM, I/O interface and interrupt system is one of the devices, only require additional power can be used for vibration and grain is the process of digital information and control. Single-chip microcomputer and digital calendar, combining for time to show, temperature testing has not only control convenient, simple and flexible configuration advantages, and which could increase the technical index of the tested value, which can greatly improve the quality of the products and quantity.Key words:Single-chip microcomputer, Temperature Sensor,C language,Liquid crystal displ目录第一章前言 (4)1.1系统开发背景及现状 (4)1.2 系统开发的目的 (4)第二章总体设计 (5)2.1 本设计实现的功能和要求 (5)2.2 设计的选择方案和论证 (5)2.2.1单片机芯片的选择方案和论证 (5)2.2.2显示模块选择方案和论证 (5)2.2.3 时钟芯片的选择方案和论证 (6)2.3.4 温度传感器的选择方案与论证 (6)2.3总体设计框图 (6)第三章硬件设计 (7)3.1 主要元器件介绍 (7)3.1.1 单片机简介 (7)3.1.2 传感器DS18B20介绍 (8)3.1.3 LCD1602液晶显示介绍 (9)3.2 各模块设计 (10)3.2.1 主控制电路 (10)3.2.2 LCD1602显示模块设计 (11)3.2.3 DS18B20温度传感器模块 (11)3.2.4 键盘输入模块设计 (12)3.2.5 蜂鸣器模块设计 (12)3.2.6 DS1302时钟电路模块 (13)第四章软件设计 (14)第五章安装与调试 (16)5.1 安装制作 (16)5.2 硬件调试 (16)5.2.1布线的原则与焊接 (16)5.2.2 硬件调试与测试 (17)5.3 软件调试 (17)5.3.1 软件测试仪器 (17)5.3.2 软件调试与测试 (17)5.4 联调 (18)5.5测试结果分析与结论 (19)第六章总结 (20)参考文献 (21)附录A (22)附录B (24)致谢 (26)第一章前言1.1系统开发背景及现状当今世界,知识更新的速度越来越快。
基于51单片机的万年历,闹钟,秒表设计有关接线图完整的程序代码#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]={"20 年月日"};uchar code table1[]={" : : "};uchar code table5[]={" QI CHUANG LA"};void LCD_WRITE_COM(uchar com);void LCD_WRITE_DAT(uchar dat);void LCD_CSH();void LCD_GD();void LCD_CLR();void DELAYUS(uchar i);void DELAY(uint t);void DELAY_A(uint n);void DISP_TIME();void DISL1();void DISL3();void DS1302_CSH();void DS1302_WRITE(uchar addr,uchar dat); void WRITE_BTY(uchar dat);void DSweek(uchar num);void DS1820RST();void DS1820WR(uchar dat);void KEYSCAN();void KEYMOVE();void TIME_UP();void TIME_DOWN();uchar DS1820RD();uchar READ_T();uchar DS1302_READ(uchar addr);uchar READ_BTY();sbit IO=P3^5;sbit RST=P1^7;sbit SCLK=P1^6;sbit FMQ=P2^4;sbit DQ=P2^3; //DS18B20输出口sbit RS=P2^5; //寄存器选择信号sbit RW=P2^6; //读写控制信号线sbit LCDEN=P2^7; //使能信号线sbit S1=P1^0;sbit S2=P1^1;sbit S3=P1^2;sbit S4=P1^3;sbit S=P1^4;char BW,SW,GW;uchar t,tflag;uchar m,f,s,x,r,y,n;uchar A,A_m,A_f,A_s,A_x;uchar num1,num2;uchar flag,flag_A,flag_j;uchar shi,ge;uchar M_a,M_b,M_c,M_d,M_e,M_f,temp,ss; long int z=0,m1,m2;//*********延时*********void DELAY(uint t) //延时1MS{int x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}void DELAY_US(uint i) //延时1US {while(i--);}void DELAY_A(uint i){ uint j;char k;for(j=0;j<i;j++){ if(S4==0){DELAY(20);if(S4==0){break;}}for(k=110;k>0;k--){FMQ=1;DELAY(10);FMQ=0;DELAY(10);if(S4==0){DELAY(20); if(S4==0) {break;} }}}}//*********LCD模块*******void LCD_CSH(){ LCD_WRITE_COM(0x38); //设置液晶工作模式 16*2行显示,5*7点阵,8位数据DELAY(1);LCD_WRITE_COM(0x0c); //开显示DELAY(1);LCD_WRITE_COM(0x06); //光标移动DELAY(1);LCD_WRITE_COM(0x01); //清屏DELAY(1);}void LCD_WRITE_COM(uchar com){RW=0; //写RS=0; //寄存器模式选择,写命令P0=com; //写命令LCDEN=0;DELAY(1);LCDEN=1; //使能,0到1DELAY(1);LCDEN=0; //数据送入有效}void LCD_WRITE_DAT(uchar dat){RW=0;RS=1; //寄存器选择,写数据P0=dat; //写数据LCDEN=0;DELAY(1);LCDEN=1; //使能0到1DELAY(1);LCDEN=0; //数据送入有效}void LCD_WORD(unsigned char *p){while(*p>0){ LCD_WRITE_DAT(*p) ;p++;}}//固定显示void LCD_GD(){char i;LCD_WRITE_COM(0x80); //"20 年月日"for(i=0;i<15;i++){LCD_WRITE_DAT(table[i]);DELAY(1);}LCD_WRITE_COM(0x90); //" : : "for(i=0;i<11;i++){LCD_WRITE_DAT(table1[i]);}LCD_WRITE_COM(0x99);LCD_WRITE_DAT(0x03);LCD_WRITE_DAT(0x03);LCD_WRITE_COM(0x9A);LCD_WORD("萍水缘");LCD_WRITE_DAT(0x03);LCD_WRITE_DAT(0x03);}//清屏void LCD_CLR(){LCD_WRITE_COM(0x01);DELAY(2);}//上电欢迎界面void DISL1(){ LCD_WRITE_COM(0x80);LCD_WORD("基于51单片机的万年历,欢迎使用!"); }void DISL3() //闹钟时间到的显示界面{char i;LCD_WRITE_COM(0x80);for(i=0;i<15;i++){LCD_WRITE_DAT(table5[i]);DELAY(1);}LCD_WRITE_COM(0x90);for(i=0;i<15;i++){LCD_WRITE_DAT(table5[i]);DELAY(1);}}//********DS1302模块**********void DS1302_CSH()//(写程序要对照DS1302的各个写地址){RST=0;SCLK=0;DS1302_WRITE(0x8e,0x00);//允许写DS1302_WRITE(0x80,0x00);//初始秒0DS1302_WRITE(0x82,0x00);//初始分0DS1302_WRITE(0x84,0x15);//初始时0DS1302_WRITE(0x8a,0x01);//初始星期6DS1302_WRITE(0x86,0x04);//初始日1DS1302_WRITE(0x88,0x06);//初始月1DS1302_WRITE(0x8c,0x12);//初始年11DS1302_WRITE(0x8e,0x80);//写保护关}uchar DS1302_READ(uchar addr){uchar dat;RST=0; //初始CE为0SCLK=0; //初始时钟线为0RST=1; //传输开始WRITE_BTY(addr); //传送读取时间的地址dat=READ_BTY(); //读取时间SCLK=1; //时钟线拉高RST=0; //传输结束return dat; //返回时间}void DS1302_WRITE(uchar addr,uchar dat) {RST=0; //初始CE为0SCLK=0; //初始时钟线为0RST=1; //传输开始DELAY(1);WRITE_BTY(addr); //传送读取时间的地址WRITE_BTY(dat); //写入修改的时间SCLK=1; //时钟线拉高RST=0; //传输结束}uchar READ_BTY(){uchar i,dat=0;SCLK=0;DELAY(1);for(i=0;i<8;i++){dat=dat>>1;DELAY(1);if(IO==1) //如果读出数据是1(当前数据线为高时,证明该位数据为1)dat|=0x80; //要传输数据的当前位置为1,不是,则为0SCLK=1; //拉高时钟线DELAY(1);SCLK=0; //制造下降沿DELAY(1);}return dat;}void WRITE_BTY(uchar dat){uchar i;SCLK=0; //当前时钟线为0DELAY(1);for(i=0;i<8;i++) //开始传输8为数据{IO=dat&0x01; //取最低位DELAY(1);SCLK=0; //拉低时钟线DELAY(1);SCLK=1; //拉高时钟线dat=dat>>1; //数据右移一位,准备传输下一个数据}}//显示时间void DISP_TIME(){LCD_WRITE_COM(0x81);//显示年,DS1302的读地址8d为年位置,LCD显示在0x81位置shi=DS1302_READ(0x8d)/16;ge=DS1302_READ(0x8d)%16;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x83); //显示月,DS1302的读地址83为年位置shi=DS1302_READ(0x89)/16;ge=DS1302_READ(0x89)%16;LCD_WRITE_DAT(shi+0x30);LCD_WRITE_DAT(ge+0x30);LCD_WRITE_COM(0x85);//显示日shi=DS1302_READ(0x87)/16;ge=DS1302_READ(0x87)%16;LCD_WRITE_DAT(shi+0x30);LCD_WRITE_DAT(ge+0x30);LCD_WRITE_COM(0x90);//显示小时shi=DS1302_READ(0x85)/16;ge=DS1302_READ(0x85)%16;LCD_WRITE_DAT(shi+0x30);LCD_WRITE_DAT(ge+0x30);LCD_WRITE_COM(0x92);//显示分钟shi=DS1302_READ(0x83)/16;ge=DS1302_READ(0x83)%16;LCD_WRITE_DAT(shi+0x30);LCD_WRITE_DAT(ge+0x30);LCD_WRITE_COM(0x94);//显示秒shi=DS1302_READ(0x81)/16;ge=DS1302_READ(0x81)%16;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);DSweek(DS1302_READ(0x8b)); //显示星期if(A==1) //显示闹钟{LCD_WRITE_COM(0x87);LCD_WRITE_DAT(0x20);LCD_WRITE_DAT(0x0e);}if(A!=1){LCD_WRITE_COM(0x87);LCD_WRITE_DAT(' ');}}//显示时间的星期模块void DSweek(uchar num){LCD_WRITE_COM(0x95); //95位置清空,96.97显示周一,二,三,四,五,六,日LCD_WRITE_DAT(0x20);LCD_WRITE_DAT(0x20);LCD_WRITE_COM(0x96);switch(num){case 1:LCD_WRITE_DAT(0xD6);LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xD2);LCD_WRITE_DAT(0xBB);break;case 2:LCD_WRITE_DAT(0xD6);LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xB6);LCD_WRITE_DAT(0xFE);break;case 3:LCD_WRITE_DAT(0xD6); LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xC8);LCD_WRITE_DAT(0xFD);break;case 4:LCD_WRITE_DAT(0xD6); LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xCB);LCD_WRITE_DAT(0xC4);break;case 5:LCD_WRITE_DAT(0xD6); LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xCE);LCD_WRITE_DAT(0xE5);break;case 6:LCD_WRITE_DAT(0xD6); LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xC1);LCD_WRITE_DAT(0xF9);break;case 7:LCD_WRITE_DAT(0xD6); LCD_WRITE_DAT(0xDC);LCD_WRITE_DAT(0xC8);LCD_WRITE_DAT(0xD5);break;}}//**********温度模块*******void DS1820RST() //DS18b20的初始化函数{ uchar x=0;DQ=1; //DQ复位DELAY_US(4); //延时DQ=0; //DQ拉低DELAY_US(100); //精确延时大于480usDQ=1; //拉高DELAY_US(40);x=DQ;}uchar DS1820RD() //读一个字节{uchar i=0,dat=0;for (i=8;i>0;i--){DQ=0; //给脉冲信号 dat=dat>>1;DQ=1; //给脉冲信号if(DQ==1)dat|=0x80;DELAY_US(10);}return dat; //写一个字节}void DS1820WR(uchar dat){char i=0;for (i=8;i>0;i--){DQ=0;DQ=dat&0x01;DELAY_US(10);DQ=1;dat=dat>>1;}}uchar READ_T(){uchar a,b;DS1820RST();DS1820WR(0xcc);//跳过读序列号(固定)DS1820WR(0x44);//启动温度转换DS1820RST();DS1820WR(0xcc);//跳过读序列号DS1820WR(0xbe);//读取温度a=DS1820RD();b=DS1820RD();b<<=4;b+=(a&0xf0)>>4;t=b;return t;}//显示温度void DISP_T(){ uchar R1;R1=READ_T();LCD_WRITE_COM(0xc8);LCD_WRITE_DAT(0xCE);LCD_WRITE_DAT(0xC2);LCD_WRITE_DAT(0xB6);LCD_WRITE_DAT(0xC8);LCD_WRITE_DAT(':');if(R1<0x81){LCD_WRITE_DAT(0x30+R1/100);} else{R1=~(R1)+1;LCD_WRITE_DAT('-');}LCD_WRITE_DAT(0x30+R1%100/10);LCD_WRITE_DAT(0x30+R1%10);LCD_WRITE_DAT(0xA1);LCD_WRITE_DAT(0xE6);}//*******键盘******//读暂停时的时间void TIME(){if(flag==0){m=DS1302_READ(0x81); //分别读出秒,分,时,星期,日,月,年(DS1302的读地址应用)f=DS1302_READ(0x83);s=DS1302_READ(0x85);x=DS1302_READ(0x8b);r=DS1302_READ(0x87);y=DS1302_READ(0x89);n=DS1302_READ(0x8d);}}//时间更新void TIME_UPDATE(){DS1302_WRITE(0x8e,0x00); //写允许DS1302_WRITE(0x80,m); //分别写出秒,分,时,星期,日,月,年(DS1302的写地址应用)DS1302_WRITE(0x82,f);DS1302_WRITE(0x84,s);DS1302_WRITE(0x8a,x);DS1302_WRITE(0x86,r);DS1302_WRITE(0x88,y);DS1302_WRITE(0x8c,n);DS1302_WRITE(0x8e,0x80); //禁止写}//闹钟void ALARM_CLOCK(){LCD_CLR();DELAY(10);DISL3(); //显示起床DELAY_A(100);FMQ=0; //蜂鸣器响flag_A=0;LCD_CLR();LCD_GD(); //固定显示}//闹钟开关显示void ALARM_KG(){if(x!=1){A=0;LCD_WRITE_COM(0x85);LCD_WRITE_DAT(0xb9);LCD_WRITE_DAT(0xd8);x=0;}if(x==1){A=1;LCD_WRITE_COM(0x85);LCD_WRITE_DAT(0xbf);LCD_WRITE_DAT(0xaa);}}//*******秒表******void CSH(){EA=1;ET0=1;TMOD=0x01;TH0=(65535-4900)/256;TL0=(65535-4900)%256;TR0=0;ss=0;M_a=M_b=M_c=M_d=0;}//秒表的键盘扫描void KEYSCAN_M(){ S=0;if(S2==0){DELAY(100);if(S2==0){while(S2==0);ss=~ss;TR0=1;if(ss==0) //S2可以暂停或者继续TR0=0;}}if(S3==0){DELAY(100);if(S3==0){while(S3==0){M_a=M_b=M_c=M_d=0;}}}}void TIME_M() interrupt 1{TH0=(65535-4900)/256;TL0=(65535-4900)%256;temp++;if(temp==2){temp=0;M_c++;if(M_c==10){M_c=0;M_b++;if(M_b==10){M_b=0;M_a++;if(M_a==10){M_a=0;M_d++;if(M_d==6){M_d=0;M_e++;if(M_e==0){M_e=0;M_f++;}}}}}}}//显示秒表,fe:da:bcvoid DISP_M(){ LCD_WRITE_COM(0x83); //显示秒表LCD_WRITE_DAT(0xc3);LCD_WRITE_DAT(0xeb);LCD_WRITE_DAT(0xb1);LCD_WRITE_DAT(0xed);LCD_WRITE_COM(0x91); //显示00:00::00LCD_WRITE_DAT(0x30+M_f);LCD_WRITE_DAT(0x30+M_e);LCD_WRITE_DAT(':');LCD_WRITE_COM(0x93);LCD_WRITE_DAT(0x30+M_d);LCD_WRITE_DAT(0x30+M_a);LCD_WRITE_DAT(':');LCD_WRITE_COM(0x95);LCD_WRITE_DAT(0x30+M_b);LCD_WRITE_DAT(0x30+M_c);}//按键扫描,s1为功能显示,s2为光标移动/秒表暂停(开始),s3为加时间和秒表复位,s4为减时间和停止闹钟void KEYSCAN(){ S=0;if(S1==0){DELAY(100);if(S1==0)while(!S1);{num1++; // 界面切换switch(num1){case 1: num2=0;m=A_m;f=A_f;s=A_s;x=A_x;LCD_CLR();LCD_WRITE_COM(0x80); //显示闹钟设置LCD_WRITE_DAT(0xC4);LCD_WRITE_DAT(0xD6);LCD_WRITE_DAT(0xD6);LCD_WRITE_DAT(0xD3);LCD_WRITE_DAT(0xC9);LCD_WRITE_DAT(0xE8);LCD_WRITE_DAT(0xD6);LCD_WRITE_DAT(0xC3);LCD_WRITE_COM(0x94);LCD_WRITE_DAT(0x30+m/16); LCD_WRITE_DAT(0x30+m%16);LCD_WRITE_COM(0x92);LCD_WRITE_DAT(0x30+f/16); LCD_WRITE_DAT(0x30+f%16); LCD_WRITE_DAT(':');LCD_WRITE_COM(0x90);LCD_WRITE_DAT(0x30+s/16); LCD_WRITE_DAT(0x30+s%16); LCD_WRITE_DAT(':');LCD_WRITE_COM(0x8b);ALARM_KG();break;case 2: LCD_WRITE_COM(0x0c); //开显示LCD_CLR();break;case 3: num2=0;num1=0;A_m=m;A_f=f;A_s=s;A_x=x;LCD_WRITE_COM(0x0c);flag=0; //读暂停的时间标志位LCD_CLR();LCD_GD(); //固定显示break;}}}}//光标移动void KEYMOVE(){ S=0;if(S2==0){ DELAY(100);if(S2==0)while(!S2);{num2++;}}if(num1==0) //调整时间,日期{switch(num2){case 1: //S2按下一次TIME(); //读出暂停的时间flag=1;LCD_WRITE_COM(0x97); //光标在星期位置闪烁LCD_WRITE_COM(0x0f);TIME_UPDATE(); //时间更新,写入设置的时间break;case 2:LCD_WRITE_COM(0x94); //光标在秒位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 3:LCD_WRITE_COM(0x92); //光标在分钟位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 4:LCD_WRITE_COM(0x90); //光标在时位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 5:LCD_WRITE_COM(0x85); //光标在日期位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 6:LCD_WRITE_COM(0x83); //光标在月份位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 7:LCD_WRITE_COM(0x81); //光标在年份位置闪烁TIME_UPDATE(); //时间更新,写入设置的时间break;case 8:LCD_WRITE_COM(0x0c); //开显示flag=0; // 读暂停的时间标志位TIME_UPDATE(); //时间更新,写入设置的时间num2=0; //复位 break;}}if(num1==1) //调整闹钟{switch(num2){case 1:LCD_WRITE_COM(0x85); //是够开闹钟LCD_WRITE_COM(0x0f);break;case 2:LCD_WRITE_COM(0x94); //光标在秒位置闪烁break;case 3:LCD_WRITE_COM(0x92); //光标在分钟位置闪烁break;case 4:LCD_WRITE_COM(0x90); //光标在小时位置闪烁break;case 5:LCD_WRITE_COM(0x0c); //开显示num2=0; //复位 break;}}if(S3==0) //加时间{ DELAY(100);if(S3==0)while(!S3);{TIME_UP();}}if(S4==0) //减时间{ DELAY(100);if(S4==0)while(!S4);{TIME_DOWN();}}}//加时间void TIME_UP(){switch(num2){case 1:x++; //星期加1if(x==0x08) x=1;if(num1==0){ DS1302_WRITE(0x8e,0x00);//写允许DS1302_WRITE(0x8a,x);DS1302_WRITE(0x8e,0x80); //写禁止DSweek(DS1302_READ(0x8b));//显示时间的星期模块}if(num1==1){ ALARM_KG();} //闹钟开关显示 break;case 2: m++; //秒加1if(m%16==10) m=(m&0xf0)+0x10;if(m==0x60) m=0;shi=m>>4;ge=m&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x94);break;case 3:f++; //分钟加1if(f%16==10) f=(f&0xf0)+0x10;if(f==0x60) f=0;shi=f>>4;ge=f&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x92);break;case 4:s++; //小时加1if(s%16==10) s=(s&0xf0)+0x10; if(s==0x24) s=0;shi=s>>4;ge=s&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x90);break;case 5:r++; //日期加1if(r%16==10) r=(r&0xf0)+0x10; if(r==0x32) r=1;shi=r>>4;ge=r&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x85);break;case 6:y++; //月份加1if(y%16==10) y=(y&0xf0)+0x10; if(y==0x13) y=1;shi=y>>4;ge=y&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x83);break;case 7:n++; //年份加1if(n%16==10) n=(n&0xf0)+0x10; if(n==0x99) n=1;shi=n>>4;ge=n&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x81);break;}}//减时间void TIME_DOWN(){switch(num2){case 1:x--; //星期减1if(x==0x00) x=7;if(num1==0){DS1302_WRITE(0x8e,0x00); DS1302_WRITE(0x8a,x);DS1302_WRITE(0x8e,0x80);DSweek(DS1302_READ(0x8b));}if(num1==1){ ALARM_KG();}break;case 2:m--; //秒减1if(m%16==15) m=(m&0xf0)+0x09; if(m==0xf9) m=0x59;shi=m>>4;ge=m&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x94);break;case 3:f--; //分钟减1if(f%16==15) f=(f&0xf0)+0x09; if(f==0xf9) f=0x59;shi=f>>4;ge=f&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x92);break;case 4:s--; //小时减1if(s%16==15) s=(s&0xf0)+0x09; if(s==0xf9) s=0x23;shi=s>>4;ge=s&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x90);break;case 5:r--; //日期减1if(r%16==15) r=(r&0xf0)+0x09; if(r==0xf9) r=0x31;shi=r>>4;ge=r&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x95);break;case 6:y--; //月份减1if(y%16==15) y=(y&0xf0)+0x09; if(y==0xf9) y=0x12;shi=y>>4;ge=y&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x93);break;case 7:n--; //年减1if(n%16==15) n=(n&0xf0)+0x09; if(n==0xf9) n=0x99;shi=n>>4;ge=n&0x0f;LCD_WRITE_DAT(0x30+shi);LCD_WRITE_DAT(0x30+ge);LCD_WRITE_COM(0x91);break;}}void main(){ CSH();LCD_CSH();DELAY(10);DS1302_CSH();DISL1(); //上电欢迎界面DELAY(10000);LCD_CLR(); //清屏LCD_GD(); //固定显示while(1){ KEYSCAN();if(num1==2){while(1){DISP_M();KEYSCAN_M();if(S1==0){DELAY(100);if(S1==0)break;}}}KEYMOVE();if(num1==0&&flag==0){DISP_TIME();DISP_T();if(DS1302_READ(0x83)==A_f&&DS1302_READ(0x85)==A_s&&DS1302_R EAD(0x81)==A_m&&A==1){ALARM_CLOCK();}}}}。
基于51单片机控制的语音报时万年历-----20/11/20XX SDU(WH)一.实验要求运用单片机及相关外设实现以下功能:1)万年历及时钟显示2)时间日期可调3)可对时间进行整点报时和随机报时二.方案分析根据实验要求,选用STC公司的8051系列,STC12C5A16S2增强型51单片机。
此单片机功能强大,具有片内EEPROM、1T分频系数、片内ADC转换器等较为实用功能,故选用此款。
实验中,对日期和时间进行显示,显示的字符数较多,故选用12864LCD屏幕。
该屏幕操作较为便捷,外围电路相对简单,实用性较强。
为了实现要求中的时间日期可调,故按键是不可缺少的,所以使用了较多的按键。
一方面,单片机的I/O口较为充足;另一方面,按键较多,选择的余地较大,方便编程控制。
实验中,并未要求对时间和日期进行保存和掉电续运行,所以并未添加EEPROM和DS12C887-RTC芯片。
实际上,对万年历来说,这是较为重要的,但为了方便实现和编程的简单,此处并未添加,而是使用单片机的定时器控制时间,精度有差别。
且上电默认时间为20XX-01-01 09:00:00 之后需要手动调整为正确时间。
要求中的语音报时功能,这里选用ISD1760芯片的模块来帮助实现。
此模块通过软件模拟SPI协议控制。
先将所需要的声音片段录入芯片的EEPROM区域,之后读出各段声音的地址段,然后在程序中定义出相应地址予以控制播放哪一声音片段。
三.电路硬件设计实际效果图四.程序代码部分Main.h#ifndef _MAIN_H#define _MAIN_H#include "reg52.h"#include "INTRINS.H"#include "math.h"#include "string.h"#include "key.h"#include "led.h"#include "12864.h"#include "main.h"#include "isd1700.h"#include "sound.h"extern unsigned int count;extern unsigned int key_time[8]; extern unsigned char key_new; extern unsigned char key_old; extern unsigned char stop_flag; extern unsigned char key_follow[8]; extern unsigned int key_num[8];sbit BEEP=P3^7;sbit ISD_SS=P0^7;sbit ISD_MISO=P0^4;sbit ISD_MOSI=P0^5;sbit ISD_SCLK=P0^6;extern unsigned char date_show[]; extern unsigned char time_show[]; extern unsigned char sec;extern unsigned char min;extern unsigned char hour;extern unsigned char day;extern unsigned char month; extern unsigned char year_f; extern unsigned char year_l; extern unsigned char leap_year_flag;extern unsigned char update_flag;extern unsigned char adjust_flag;extern unsigned char key;unsigned char report();#endifMain.c#include "main.h"unsigned int count=0;unsigned int key_num[8]=0;unsigned char key_new=0;unsigned char key_old=0;unsigned char stop_flag=0;unsigned char key_follow[8]=0;unsigned char sec=1;unsigned char min=0;unsigned char hour=9;unsigned char day=1;unsigned char month=1;unsigned char year_f=20;unsigned char year_l=14;unsigned char leap_year_flag=0;unsigned char date_show[]="20XX-01-01"; unsigned char time_show[]="09:00:00";unsigned char update_flag=1;unsigned char key=0;unsigned char adjust_flag=0;unsigned char adjust_pos=0;unsigned char report_flag=0;void main(){unsigned char i;P2=0XFF;BEEP=0;init();initinal(); //调用LCD字库初始化程序TMOD=0x01; //使用定时器T0TH0=(65536-1000)/256; //定时器高八位赋初值TL0=(65536-1000)%256; //定时器低八位赋初值*/ EA=1; //开中断总允许ET0=1; //允许T0中断TR0=1; //启动定时器T0while(1){if(update_flag){lcd_pos(1,0);for(i=0;i<10;i++)write_dat(date_show[i]);lcd_pos(2,4);for(i=0;i<8;i++)write_dat(time_show[i]);update_flag=0;}if(key!=keyscan_nor()){key=keyscan_nor();if(key==8&&!adjust_flag)adjust_flag=1;if(key&&adjust_flag){if(key==1){adjust_pos++;if(adjust_pos==14)adjust_pos=0;}else if(key==2){if(!adjust_pos)adjust_pos=13;elseadjust_pos--;}else if(key==6){if(!adjust_pos)sec++;else if(adjust_pos==1)sec=sec+10;else if(adjust_pos==2)min++;else if(adjust_pos==3)min=min+10;else if(adjust_pos==4)hour++;else if(adjust_pos==5)hour=hour+10;else if(adjust_pos==6)day++;else if(adjust_pos==7)day=day+10;else if(adjust_pos==8)month++;else if(adjust_pos==9)month=month+10;else if(adjust_pos==10)year_l++;else if(adjust_pos==11)year_l=year_l+10;else if(adjust_pos==12)year_f++;else if(adjust_pos==13)year_f=year_f+10; }else if(key==7){if(!adjust_pos)sec--;else if(adjust_pos==1)sec=sec-10;else if(adjust_pos==2)min--;else if(adjust_pos==3)min=min-10;else if(adjust_pos==4)hour--;else if(adjust_pos==5)hour=hour-10;else if(adjust_pos==6)day--;else if(adjust_pos==7)day=day-10;else if(adjust_pos==8)month--;else if(adjust_pos==9)month=month-10;else if(adjust_pos==10)year_l--;else if(adjust_pos==11)year_l=year_l-10;else if(adjust_pos==12)year_f--;else if(adjust_pos==13)year_f=year_f-10;}else if(key==3)adjust_flag=0;if(key==6||key==7){if(sec>=80)sec=0;if(min>=80)min=0;if(hour>=40)hour=0;if(month>30)month=1;if(day>50)day=0;if(year_f>=120)year_f=0;if(year_l>=120)year_l=0;}}}if(key==3)report_flag=1;if(report_flag){clrram();Dingwei(2,1);lcd_mesg("REPORTING!!!");report();clrram();}}}void time0() interrupt 1{static unsigned char timer=0;TH0=(65536-50000)/256; //定时器高八位赋初值TL0=(65536-50000)%256; //定时器低八位赋初值timer++;if(timer==20){sec++;time_show[6]=sec/10+48;time_show[7]=sec%10+48;if(sec>=60){sec=0;min++;time_show[6]=sec/10+48;time_show[7]=sec%10+48;time_show[3]=min/10+48;time_show[4]=min%10+48;}if(min>=60){min=0;hour++;time_show[3]=min/10+48;time_show[4]=min%10+48;time_show[0]=hour/10+48;time_show[1]=hour%10+48;}if(hour>=24){hour=0;day++;time_show[0]=hour/10+48;time_show[1]=hour%10+48;date_show[8]=day/10+48;date_show[9]=day%10+48;}if((day>=29&&!leap_year_flag&&month==2)||(day==30&&leap_year_flag&&month==2)||(day==31&&(month==4||month==6||month==9||month==11))||(month==32)){day=1;month++;date_show[8]=day/10+48;date_show[9]=day%10+48;date_show[5]=month/10+48;date_show[6]=month%10+48;}if(month>=13){month=1;year_l++;date_show[5]=month/10+48;date_show[6]=month%10+48;date_show[0]=year_f/10+48;date_show[1]=year_f%10+48;date_show[2]=year_l/10+48;date_show[3]=year_l%10+48;}if(year_l>=100){year_l=0;year_f++;if(((!((year_f*100+year_l)%4))&&((year_f*100+year_l)%100))||(!((year_f*100+year_l)%40 0)))leap_year_flag=1;elseleap_year_flag=0;date_show[0]=year_f/10+48;date_show[1]=year_f%10+48;date_show[2]=year_l/10+48;date_show[3]=year_l%10+48;}timer=0;update_flag=1;if(adjust_flag){time_show[7]=sec%10+48;time_show[6]=sec/10+48;time_show[4]=min%10+48;time_show[3]=min/10+48;time_show[1]=hour%10+48;time_show[0]=hour/10+48;date_show[9]=day%10+48;date_show[8]=day/10+48;date_show[6]=month%10+48;date_show[5]=month/10+48;date_show[3]=year_l%10+48;date_show[2]=year_l/10+48;date_show[1]=year_f%10+48;date_show[0]=year_f/10+48;}}if(adjust_flag&&timer==10){if(!adjust_pos)time_show[7]=' ';else if(adjust_pos==1)time_show[6]=' ';else if(adjust_pos==2)time_show[4]=' ';else if(adjust_pos==3)time_show[3]=' ';else if(adjust_pos==4)time_show[1]=' ';else if(adjust_pos==5)time_show[0]=' ';else if(adjust_pos==6)date_show[9]=' ';else if(adjust_pos==7)date_show[8]=' ';else if(adjust_pos==8)date_show[6]=' ';else if(adjust_pos==9)date_show[5]=' ';else if(adjust_pos==10)date_show[3]=' ';else if(adjust_pos==11)date_show[2]=' ';else if(adjust_pos==12)date_show[1]=' ';else if(adjust_pos==13)date_show[0]=' ';update_flag=1;}if(!min&&!sec&&!adjust_flag)report_flag=1;}unsigned char report(){PlaySoundTick(11);long_delay();if(!min){if(hour<=10){PlaySoundTick(hour);short_delay();PlaySoundTick(12);short_delay();PlaySoundTick(14);short_delay();}else if(hour>10&&hour<20){PlaySoundTick(10);short_delay();PlaySoundTick(hour-10);short_delay();PlaySoundTick(12);short_delay();PlaySoundTick(14);short_delay();}else if(hour==20){PlaySoundTick(2);short_delay();PlaySoundTick(10);short_delay();PlaySoundTick(12);short_delay();PlaySoundTick(14);short_delay();}else{short_delay();PlaySoundTick(10);short_delay();PlaySoundTick(hour-20);short_delay();PlaySoundTick(12);short_delay();PlaySoundTick(14);short_delay();}}else{if(hour<=10){PlaySoundTick(hour);short_delay();PlaySoundTick(12);short_delay();}else if(hour>10&&hour<20){PlaySoundTick(10);short_delay();PlaySoundTick(hour-10);short_delay();PlaySoundTick(12);short_delay();}else if(hour==20){PlaySoundTick(2);short_delay();PlaySoundTick(10);short_delay();PlaySoundTick(12);short_delay();}else{PlaySoundTick(2);short_delay();short_delay();PlaySoundTick(hour-20);short_delay();PlaySoundTick(12);short_delay();}if(min<=10){PlaySoundTick(min);short_delay();PlaySoundTick(13);short_delay();}else if(min>10&&min%10){PlaySoundTick(min/10);short_delay();PlaySoundTick(10);short_delay();PlaySoundTick(min-10*(min/10));short_delay();PlaySoundTick(13);short_delay();}else{PlaySoundTick(min/10);short_delay();PlaySoundTick(10);short_delay();PlaySoundTick(13);short_delay();}}report_flag=0;time_show[7]=sec%10+48;time_show[6]=sec/10+48;time_show[4]=min%10+48;time_show[3]=min/10+48;time_show[1]=hour%10+48;time_show[0]=hour/10+48;date_show[9]=day%10+48;date_show[8]=day/10+48;date_show[6]=month%10+48;date_show[5]=month/10+48;date_show[3]=year_l%10+48;date_show[2]=year_l/10+48;date_show[1]=year_f%10+48;date_show[0]=year_f/10+48;return 0;}Isd1700.h#ifndef _ISD1760_H#define _ISD1760_H#include "main.h"#define ISD1700_PU 0x01#define ISD1700_STOP 0X02 #define ISD1700_REST 0x03 #define ISD1700_CLR_INT 0x04 #define ISD1700_RD_STAUS 0x05 #define ISD1700_RD_PLAY_PTR 0x06 #define ISD1700_PD 0x07#define ISD1700_RD_REC_PTR 0x08 #define ISD1700_DEVID 0x09#define ISD1700_PLAY 0x40 #define ISD1700_REC 0x41 #define ISD1700_ERASE 0x42 #define ISD1700_G_ERASE 0x43 #define ISD1700_RD_APC 0x44 #define ISD1700_WR_APC1 0x45 #define ISD1700_WR_APC2 0x65#define ISD1700_WR_NVCFG 0x46 #define ISD1700_LD_NVCFG 0x47 #define ISD1700_FWD 0x48 #define ISD1700_CHK_MEM 0x49 #define ISD1700_EXTCLK 0x4A #define ISD1700_SET_PLAY 0x80 #define ISD1700_SET_REC 0x81 #define ISD1700_SET_ERASE 0x82 #define NULL 0x00 #define ISD_LED 0x10extern unsigned char data ISD_M_RAM_C[7];extern void init(void);extern void delay_isd(int x);extern void m_sate(void);extern void rest_isd_m_ptr(void);extern unsigned char T_R_m_byte(unsigned char m_data );extern void isd1700_par2_m(unsigned char m_par, unsigned int data_par);extern void isd1700_Npar_m(unsigned char m_par,m_byte_count);extern void isd1700_7byte_m(unsigned char m_par, unsigned int star_addr, unsigned int end_addr);extern void spi_pu (void);extern void spi_stop (void);extern void spi_Rest ( void );extern void spi_CLR_INT(void);extern void spi_RD_STAUS(void);extern void spi_RD_play_ptr(void);extern void spi_pd(void);extern void spi_RD_rec_ptr(void);extern void spi_devid(void);extern void spi_play(void);extern void spi_rec (void);extern void spi_erase (void);extern void spi_G_ERASE (void);extern void spi_rd_apc(void);extern void spi_wr_apc1 (void);extern void spi_wr_apc2 (void);extern void spi_wr_nvcfg (void);extern void spi_ld_nvcfg (void);extern void spi_fwd (void);extern void spi_chk_mem(void);extern void spi_CurrRowAddr(void);extern void seril_back_sate(unsigned char byte_number);extern void spi_set_opt(unsigned char spi_set_m);void init(void);#endifIsd1700.c//#pragma src#include "isd1700.h"#include "sound.h"#define uchar unsigned char#define uint unsigned intsbit DAC_sync=P2^0;sbit DAC_sclk=P2^1;sbit DAC_din =P2^2;bit re_fig;uchar data m_temp;uchar data ISD_M_RAM[7];uchar data ISD_M_RAM_C[7];uchar data *isd_m_ptr;uchar data *back_data_ptr;void init(void);void isd_delay(int x);void m_sate(void);void rest_isd_m_ptr(void);uchar T_R_m_byte( uchar m_data );void isd1700_par2_m(uchar m_par, uint data_par);void isd1700_Npar_m(uchar m_par,m_byte_count); //no parameter m void isd1700_7byte_m(uchar m_par, uint star_addr, uint end_addr);void spi_pu (void);void spi_stop (void);void spi_Rest ( void );void spi_CLR_INT(void);void spi_RD_STAUS(void);void spi_RD_play_ptr(void);void spi_pd(void);void spi_RD_rec_ptr(void);void spi_devid(void);void spi_play(void);void spi_rec (void);void spi_erase (void);void spi_G_ERASE (void);void spi_rd_apc(void);void spi_wr_apc1 (void);void spi_wr_apc2 (void);void spi_wr_nvcfg (void);void spi_ld_nvcfg (void);void spi_fwd (void);void spi_chk_mem(void);void spi_CurrRowAddr(void);void seril_back_sate(uchar byte_number); void spi_set_opt(uchar spi_set_m);void m_sate(void){uchar sate_temp;uint apc_temp;if(RI){ sate_temp=SBUF;if(sate_temp==0x09){ spi_devid();}if(sate_temp==0x44){spi_rd_apc();}if(sate_temp==0x40){spi_play();}if(sate_temp==0x04){spi_CLR_INT();}if(sate_temp==0x05){spi_RD_STAUS();}if(sate_temp==0x43){ spi_G_ERASE();}if(sate_temp==0x01){ spi_pu ();}if(sate_temp==0x02){ spi_stop();}if(sate_temp==0x03){ spi_Rest ();}if(sate_temp==0x06){spi_RD_play_ptr();}if(sate_temp==0x07){spi_pd();}if(sate_temp==0x08){ spi_RD_rec_ptr();}if(sate_temp==0x41){ spi_rec();}if(sate_temp==0x42){ spi_erase();}if(sate_temp==0x45){spi_wr_apc1 ();}if(sate_temp==0x65){ spi_wr_apc2 ();}if(sate_temp==0x46){ spi_wr_nvcfg ();}if(sate_temp==0x47){ spi_ld_nvcfg ();}if(sate_temp==0x48){ spi_fwd ();}if(sate_temp==0x49){ spi_chk_mem();}if(sate_temp==0x60){ spi_CurrRowAddr();}if(sate_temp==0x80){spi_set_opt(ISD1700_SET_PLAY|ISD_LED);//spi_set_opt(ISD1700_SET_PLAY);}if(sate_temp==0x81){spi_set_opt(ISD1700_SET_REC|ISD_LED);//spi_set_opt(ISD1700_SET_REC);ISD_M_RAM_C[0]=ISD1700_SET_REC ;seril_back_sate(1);}if(sate_temp==0x82){spi_set_opt(ISD1700_SET_ERASE|ISD_LED);//spi_set_opt(ISD1700_SET_ERASE);}if(sate_temp==ISD1700_WR_APC2){RI=0;while(!RI);apc_temp=SBUF;apc_temp=apc_temp<<8;RI=0;while(!RI);apc_temp|=SBUF;RI=0;ISD_SS=0;isd1700_par2_m(ISD1700_WR_APC2,apc_temp);ISD_SS=1;}RI=0;}if(re_fig){rest_isd_m_ptr();sate_temp=0;do{SBUF=*back_data_ptr++;while(!TI);TI=0;}while(++sate_temp<=2);re_fig=0;}}void spi_set_opt(uchar spi_set_m){uint start_addr,end_addr;RI=0;while(!RI);start_addr=SBUF;start_addr=start_addr<<8;RI=0;while(!RI);start_addr|=SBUF;RI=0;while(!RI);end_addr=SBUF;end_addr=start_addr<<8;RI=0;while(!RI);end_addr|=SBUF;RI=0;ISD_SS=0;isd1700_7byte_m(spi_set_m, start_addr, end_addr);ISD_SS=1;}void spi_pu (void){ISD_SS=0;isd1700_Npar_m(ISD1700_PU,2);ISD_SS=1;}void spi_stop (void){ISD_SS=0;isd1700_Npar_m(ISD1700_STOP,2);ISD_SS=1;ISD_M_RAM_C[0]=ISD1700_STOP ;seril_back_sate(1);}void spi_Rest (void){ISD_SS=0;isd1700_Npar_m(ISD1700_REST,2);ISD_SS=1;}void spi_CLR_INT(void){ISD_SS=0;isd1700_Npar_m(ISD1700_CLR_INT,2);ISD_SS=1;}void spi_RD_STAUS(void){ uchar i;ISD_SS=0;isd1700_Npar_m(ISD1700_RD_STAUS,3);ISD_SS=1;i=ISD_M_RAM_C[1];//j=ISD_M_RAM_C[2];ISD_M_RAM_C[1]=ISD_M_RAM_C[0];ISD_M_RAM_C[0]=i;seril_back_sate(3);}void spi_CurrRowAddr(void){ uchar i;ISD_SS=0;isd1700_Npar_m(ISD1700_RD_STAUS,3);ISD_SS=1;i=ISD_M_RAM_C[1];ISD_M_RAM_C[1]=ISD_M_RAM_C[0]>>5|ISD_M_RAM_C[1]<<3;ISD_M_RAM_C[0]= i >>5;seril_back_sate(3);}void spi_RD_play_ptr(void){ uchar i;ISD_SS=0;isd1700_Npar_m(ISD1700_RD_PLAY_PTR,4);ISD_SS=1;i=ISD_M_RAM_C[3]&0x03;ISD_M_RAM_C[3]=ISD_M_RAM_C[2];ISD_M_RAM_C[2]=i;seril_back_sate(4);}void spi_pd(void){ISD_SS=0;isd1700_Npar_m(ISD1700_PD,2);ISD_SS=1;}void spi_RD_rec_ptr(void){ uchar i;ISD_SS=0;isd1700_Npar_m(ISD1700_RD_REC_PTR,4);ISD_SS=1;i=ISD_M_RAM_C[3]&0x03;ISD_M_RAM_C[3]=ISD_M_RAM_C[2];ISD_M_RAM_C[2]=i;seril_back_sate(4);}void spi_devid(void){ISD_SS=0;isd1700_Npar_m(ISD1700_DEVID,3);ISD_SS=1;ISD_M_RAM_C[2]=ISD_M_RAM_C[2]&0xf8;seril_back_sate(3);}void spi_play(void){ISD_SS=0;isd1700_Npar_m(ISD1700_PLAY|ISD_LED,2);ISD_SS=1;}void spi_rec (void){ISD_SS=0;isd1700_Npar_m(ISD1700_REC|ISD_LED,2);ISD_SS=1;ISD_M_RAM_C[0]=ISD1700_REC ;seril_back_sate(1);}void spi_erase (void){ISD_SS=0;isd1700_Npar_m(ISD1700_ERASE|ISD_LED,2);ISD_SS=1;}void spi_G_ERASE (void){ISD_SS=0;isd1700_Npar_m(ISD1700_G_ERASE|ISD_LED,2);ISD_SS=1;}void spi_rd_apc(void){ISD_SS=0;isd1700_Npar_m(ISD1700_RD_APC,4);ISD_SS=1;seril_back_sate(4);}void spi_wr_apc1 (void){}void spi_wr_apc2 (void){ISD_SS=0;isd1700_par2_m(ISD1700_WR_APC2, 0x0400);ISD_SS=1;}void spi_wr_nvcfg (void){ISD_SS=0;isd1700_Npar_m(ISD1700_WR_NVCFG,2);ISD_SS=1;}void spi_ld_nvcfg (void){ISD_SS=0;isd1700_Npar_m(ISD1700_LD_NVCFG ,2);ISD_SS=1;}void spi_fwd (void){ISD_SS=0;isd1700_Npar_m(ISD1700_FWD,2);ISD_SS=1;}void spi_chk_mem(void){ISD_SS=0;isd1700_Npar_m(ISD1700_CHK_MEM,2);ISD_SS=1;}void seril_back_sate(uchar byte_number){uchar sate_temp;rest_isd_m_ptr();sate_temp=0;do{SBUF=*back_data_ptr++;while(!TI);TI=0;}while(++sate_temp<byte_number);}void rest_isd_m_ptr(void){isd_m_ptr=ISD_M_RAM;back_data_ptr=ISD_M_RAM_C;}void isd1700_Npar_m (uchar m_par,m_byte_count){uchar i;i=0;ISD_M_RAM[0]=m_par;isd_m_ptr=&ISD_M_RAM[1];do{*isd_m_ptr++=NULL;}while(++i<m_byte_count-1);rest_isd_m_ptr();i=0;do{*back_data_ptr++=T_R_m_byte(*isd_m_ptr++);i++;}while(i<m_byte_count);}void isd1700_par2_m(uchar m_par, uint data_par){uchar i;ISD_M_RAM[0]=m_par;ISD_M_RAM[1]=data_par;ISD_M_RAM[2]=data_par>>8;rest_isd_m_ptr();i=0;do{*back_data_ptr++=T_R_m_byte(*isd_m_ptr++);i++;}while(i<3);}void isd1700_7byte_m(uchar m_par, uint star_addr, uint end_addr) {uchar i;ISD_M_RAM[0]=m_par;ISD_M_RAM[1]=NULL;ISD_M_RAM[2]=star_addr;ISD_M_RAM[3]=star_addr>>8;ISD_M_RAM[4]=end_addr;ISD_M_RAM[5]=end_addr>>8;ISD_M_RAM[6]=NULL;rest_isd_m_ptr();i=0;do{*back_data_ptr++=T_R_m_byte(*isd_m_ptr++);i++;}while(i<=7);}uchar T_R_m_byte( uchar m_data ){uchar bit_nuber;uchar temp;bit_nuber=0;temp=0;do{ISD_SCLK=0;isd_delay(1);if((m_data>>bit_nuber&0x01)!=0){ISD_MOSI=1;}else{ISD_MOSI=0;}if(ISD_MISO){temp=(temp>>1)|0x80;}else{temp=temp>>1;}ISD_SCLK=1;isd_delay(1);}while(++bit_nuber<=7);ISD_MOSI=0;return (temp);}void isd_delay(int x){uchar i;for(; x>=1; x--){for(;i<=20;i++);}}void init(void){TMOD=0x21;SCON=0x50;TL0=0x00; //25msTH0=0x70; //25msTH1=0xE8;TL1=0xE8; //波特率:1200bps(12MHz:0xE6 11.0592MHz:0xE8)ET0=1;EA=1;TR1=1;IT0 = 0;EX0 = 0;spi_pu();spi_devid();}12864.h#ifndef _12864_H#define _12864_H#include "main.h"sbit RS =P3^2;sbit RW=P3^3;sbit EN=P3^4;void buzy();void TransferData(char data1,bit DI);void Dingwei(unsigned char line,unsigned char row);void delayms(unsigned int n);void delay(unsigned int m);void lcd_mesg(unsigned char code *adder1);void displayonechar(unsigned int data2);void initinal(void) ; //LCD字库初始化程序void clrram(void);void lcd_pos(unsigned char ,unsigned char );void write_dat(unsigned char);extern unsigned char time_show[];extern unsigned int aaa;#endif12864.c#include "12864.h"#define DataPort P1void initinal(void) //LCD字库初始化程序{TransferData(0x30,0); //8BIT设置,RE=0: basic instruction setTransferData(0x08,0); //Display on ControlTransferData(0x10,0); //Cursor Display Control光标设置TransferData(0x0C,0); //Display Control,D=1,显示开TransferData(0x01,0); //Display Clear}void buzy(){DataPort=0xff;RW=1;RS=0;EN=1;while(DataPort&0x80);EN=0;}void Dingwei(unsigned char line,unsigned char row) //定位在哪行哪列显示{unsigned int i;switch(line){case 1: i=0x80+row;break;case 2: i=0x90+row;break;case 3: i=0x88+row;break;case 4: i=0x98+row;break;default: i=0x80;break;}TransferData(i,0);delay(1);}void lcd_mesg(unsigned char code *addr) //传送一个字符串{while(*addr>0){TransferData(*addr,1);addr++;}}void TransferData(char data1,bit DI) //传送数据或者命令,当DI=0,传送命令,当DI=1,传送数据.{buzy();RW=0;RS=DI;DataPort=data1;EN=1;EN=0;}void delayms(unsigned int n) //延时10×n毫秒程序{unsigned int i,j;for(i=0;i<3*n;i++)for(j=0;j<2000;j++);}void delay(unsigned int m) //延时程序,微妙级{while(m--){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}}void write_cmd(unsigned char cmd){RS=0;RW=0;EN=0;P1=cmd;delayms(1);EN=1;delayms(1);EN=0;}void write_dat(unsigned char dat)RS=1;RW=0;EN=0;P1=dat;delayms(1);EN=1;delayms(1);EN=0;}void lcd_pos(unsigned char x,unsigned char y){unsigned char pos;if(x==0)x=0x80;else if(x==1)x=0x90;else if(x==2)x=0x88;else if(x==3)x=0x98;pos=x+y;write_cmd(pos);}void clrram(void){write_cmd(0x30);write_cmd(0x01);}Sound.h#ifndef _SOUND_H#define _SOUND_H#include "main.h"//以下为语音信息对应播放起始地址定义,A为开始,B为结束#define sound_0A 0x0012#define sound_0B 0x0017#define sound_1A 0x0019#define sound_1B 0x0025#define sound_2A 0x0027#define sound_2B 0x002e#define sound_3A 0x002f#define sound_3B 0x0039#define sound_4A 0x003b#define sound_4B 0x0048#define sound_5A 0x004a#define sound_5B 0x004f#define sound_6A 0x0052#define sound_6B 0x0159#define sound_7A 0x005c#define sound_7B 0x0062#define sound_8A 0x0065#define sound_8B 0x0131#define sound_9A 0x006f#define sound_9B 0x015F#define sound_10A 0x0079#define sound_10B 0x015E#define sound_11A 0x0082#define sound_11B 0x018A#define sound_12A 0x0091#define sound_12B 0x0100#define sound_13A 0x009f#define sound_13B 0x0100#define sound_14A 0x00ac#define sound_14B 0x0100void GetSound(unsigned char soundtick); void PlaySoundTick(unsigned char number); void delay_isd(unsigned int time);void short_delay();void long_delay();#endifSound.c#include "sound.h"void GetSound(unsigned char soundtick){ISD_SS=0;switch(soundtick){case 0:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_0A, sound_0B); }break;case 1:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_1A, sound_1B); }break;case 2:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_2A, sound_2B); }break;case 3:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_3A, sound_3B); }break;case 4:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_4A, sound_4B); }break;case 5:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_5A, sound_5B); }break;case 6:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_6A, sound_6B); }break;case 7:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_7A, sound_7B); }break;case 8:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_8A, sound_8B); }break;case 9:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_9A, sound_9B); }break;case 10:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_10A, sound_10B); }break;case 11:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_11A, sound_11B); }break;case 12:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_12A, sound_12B); }break;case 13:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_13A, sound_13B); }break;case 14:{ isd1700_7byte_m(ISD1700_SET_PLAY|ISD_LED, sound_14A, sound_14B); }break;default: break;}ISD_SS=1;}void PlaySoundTick(unsigned char number) {spi_stop ();delay_isd(30000);GetSound(number);}void delay_isd(unsigned int time){while(time--!=0);}void short_delay(){delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);delay_isd(30000);}void long_delay(){short_delay();short_delay();short_delay();short_delay();}Key.h#ifndef _KEY_H#define _KEY_H#include "main.h"sbit KEY1=P2^0;sbit KEY2=P2^1;sbit KEY3=P2^2;sbit KEY4=P2^3;sbit KEY5=P2^4;sbit KEY6=P2^5;sbit KEY7=P2^6;sbit KEY8=P2^7;sbit KEY_SURE=P3^6;void key_delay(unsigned char z); unsigned char keyscan_nor();#endifKey.c#include "key.h"unsigned char keyscan_nor() {if(!KEY1){key_delay(20);if(!KEY1){LED1=0;return 1;}}if(!KEY2){key_delay(20);if(!KEY2){LED2=0;return 2;}}if(!KEY3){key_delay(20);if(!KEY3){LED3=0;return 3;}}if(!KEY4){key_delay(20);if(!KEY4){LED4=0;return 4;}}if(!KEY5){key_delay(20);if(!KEY5){LED5=0;return 5;}}if(!KEY6){key_delay(20);if(!KEY6){LED6=0;return 6;}}if(!KEY7){key_delay(20);if(!KEY7){LED7=0;return 7;}}if(!KEY8){key_delay(20);if(!KEY8){LED8=0;return 8;}}return 0;}void key_delay(unsigned char z) {unsigned char x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }五.参与制作人员ZYL。