找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14616|回复: 7
打印 上一主题 下一主题
收起左侧

基于单片机的1602万年历程序设计资料(附带小闹钟)可做单组自动打铃系统

  [复制链接]
跳转到指定楼层
楼主
ID:309367 发表于 2018-6-18 14:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自己做过的设计资料,现在放在51hei论坛上,用得着的朋友可以下去用,功能简单易懂,一些不好的地方可以自己开发或者拓展改进。纯粹学习用

设计主要研究基于单片机的自动打铃系统。设计的系统利用时钟芯片提供走时,并由单片机对其进行监测和控制,然后通过显示模块将时间数据反馈给用户,同时根据用户设定的时刻进行打铃提醒。设计采用的核心控制器是STC89C51单片机,确保对时钟的实时监测;提供时钟信号的芯片是DS1302,可以产生较为精准的时钟;所有的时间数据通过LCD1602显示器反馈给用户,这款显示器具有体积小巧、功耗低的优点;最后根据用户设定时间用蜂鸣器打铃输出。通过对系统的软、硬件进行设计,并进行系统仿真和系统测试,完成对基于单片机的自动打铃系统的设计与实现。



Abstract

The design mainly studies the automatic bell ringing system based on single chip microcomputer. The designed system uses the clock chip to provide travel time, and monitors and controls it by the single chip computer. Then the time data is fed back to the user through the display module, and the bell is remined by the time set by the user. The core controller used in the design is the STC89C51 microcontroller to ensure real-time monitoring of the clock. The chip of the clock signal is DS1302, which can produce a more accurate clock. All the time data are fed back to the user through the LCD1602 display. This display has the advantages of small size and low power consumption; finally, it is based on the user. Set the time to bell the output by the buzzer. Through the design of the hardware and software of the system, and the system simulation and system debugging, the design and implementation of the automatic bell system based on single chip microcomputer is completed.


              目录            

第1章 绪论

1.1 研究的目的和意义

1.2国内外的发展研究状况

1.3研究的基本任务与方案设计

1.3.1 研究任务

1.3.2 方案设计

1.4 文档的内容与结构

第2章 硬件电路的设计与实现

2.1 硬件电路总体设计

2.2 单片机最小系统

2.3 显示电路设计

2.4 按键电路设计

2.5 时间电路设计

2.6 打铃电路的设计

第3章 软件电路的设计与实现

3.1 软件系统设计

3.2 显示子程序

3.3 按键子程序

3.4 时间子程序

3.5 打铃子程序

第4章 开发软件的介绍及系统测试

4.1 开发软件的介绍

4.1.1 Proteus
4.1.2 Keil C

4.2 系统仿真

4.3 系统测试

第5章 结论
参考文献
致谢
附录

附录一:自动打铃系统原理图

附录二:源程序


第1章 绪论
1.1
研究的目的和意义

随着电子计算机技术的高速发展,以及其在信息处理系统中的广泛应用,单片机作为一种采用超大规模集成电路技术、并把具有数据处理能力的中央处理器CPU和随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。其体积小、功能强、成本低、适用范围广,体现出了其很大的使用价值。纵观我们现在生活的各个领域,从导弹的导航装置,到飞机上各种仪表的控制,从计算机的网络通讯与数据传输,到工业自动化过程的实时控制和数据处理,以及我们生活中广泛使用的各种智能IC卡、电子宠物等,这些都离不开单片机。以前没有单片机时,这些东西也能做,但是只能使用复杂的模拟电路,然而这样做出来的产品不仅体积大,而且成本高,并且会因为长期使用,使得元器件不断老化,控制的精度自然也会达不到标准。在单片机产生后,我们就将控制这些东西变得智能化了,我们只需要在单片机外围接一点简单的接口电路,核心部分只是由人为的写入程序来完成。这样产品的体积变小了,成本也降低了,长期使用也不会担心精度达不到的问题。所以,它的魔力不仅是在现在,在将来将会有更多的人来接受它、使用它。据统计,我国的单片机年容量已达到3亿片,且每年以大约30%的速度高速增长。随着开发以及推出单片机的公司越来越多,各种高性能的单片机芯片市场也日趋活跃。新技术的不断加入和纳入使用,使得单片机的性能和种类及其应用范围不断增强和扩大。集成的功能及其展现出的性能得到了逐步的全面和强化,所以单片机会越来越受到广大用户的青睐和使用。

而今,在很多的公共场所,例如学校、机关、工厂、车站等单位,都是用电铃作为作息时间信号的。而最原始的电铃控制方式就是人工打铃,采用逻辑电路进行控制,其原理简单、便于操作,但会导致设备体积过大,不利于临时调整。所以,就引入以单片机为基础控制的自动打铃系统,这样不仅节省了人力,同时也使得设备的集成化大大提高,而且便于设备的调整。为此,设计一种基于单片机的自动打铃系统,采用数字钟和自动打铃系统相结合的方式。该系统一单片机为核心来控制各个功能模块,使用者可以随时对作息时间进行修改,可以很方便地设定作息时间方案。这是一个集数字钟显示、设置、打铃为一体的多功能打铃计时系统。这样,通过简单的设置,就可以满足任何学校、企事业公共场所和单位的需求。而本设计就是理论与实践并重,对于有效地掌握单片机的应用具有很重要的意义。

1.2国内外的发展研究状况

自1986年德国诞生了世界上第一款商用电子时钟后,电子钟的发展趋势在全球逐步蔓延开来。继德国之后,日本也普及了电子钟,英国、美国以及大多数欧洲国家也都在将消费者的热点转移到了电子钟表上面,逐步提高了市场占有率。中国是继德、日、英、美以后,第五个拥有电子钟制造技术的国家。中国科学院国家授时中心与西安高华科技有限公司,在河南建立了电子钟研发基地,用于开发多功能的电子钟表和数字电子钟等产品,极大地推动了电子钟行业的发展。中国第一款数字电子时钟已经推出针对中国市场接受中国国家授时中心信号的多功能电子钟表,走时精确,在信号覆盖区域外日累计误差小于0.5秒,质量可靠,价格仅为国外同期同类竞品的1/8。从区域格局来看,全国已形成以广州、深圳为龙头的珠三角地区、福建、浙江、江苏、山东、天津等6大多功能时钟主产区;从产量来看,我国已成为世界多功能时钟生产大国,多功能时钟产量稳居世界第一。监测数据显示,2011年,我国多功能时钟的产量达到2.89亿只。我国多功能时钟行业发展虽然取得长足的进步,但国内多功能时钟企业及其品牌在国际市场上的信誉度和影响力还微不足道,产量占比虽然已经达到80%以上。可见,其发展趋势迅猛。而随着技术的进步,各种新的的功能也负之而上,使得电子钟的精度大大提高。例如,在国外企业中,日本RICOH公司推出的时钟芯片甚至已经出现时基软件调校功能(TTF)及振荡器停振自动检测功能而且芯片的价格极为低廉。目前,这些芯片已被客户大量使用中。最新一代时钟芯片产品中,除了包含第二代产品所具有的全部功能,更加入了复合功能,如低电压检测,主备用电池切换功能,抗印制板漏电功能,且本身封装更小(高度 0.85mm,面积仅2mm*2mm),如RICOH公司的代表产品R2051。而如今,使用范围较广的多功能电子时钟一般由振荡器,分频器,译码器,显示器等部分组成,这些都是数字电路中最基本的,应用最广的电路。当前市场上已有现成的数字钟集成电路芯片出售,价格较便宜。由于数字集成电路技术的发展,使数字电子钟具有走时准确,性能稳定,携带方便等特点,是目前人们生活和工作补课或缺的报时用品。国内厂家的产品拥有时间、日期、温度、夜光、贪睡功能、倒计时、顺计时、省电模式、多组闹钟、可循环显示、多档亮度调节、12/24时制转换、调节亮度、遥控操作等功能。比如美国的INTEL公司在上世纪80年代推出的AT89C51芯片与HD7279芯片构成的键盘控制电路,通过程序的编写控制I/O口的输出进而控制显示定时数据及打铃电路。当然也有部分采用德州仪器公司产的8255芯片为核心部件的打铃系统,原理都大同小异。现今在一些特殊的对定时精确度要求高的领域。比如,微电子方面,体育竞技项目等行业,单片机技术显然会有一定的误差,于是随之出现了部分通过计算机控的打铃系统,或者是结合其他影像技术设计而成的打铃系统。随着技术的不断发展,自动打铃系统不断地走向体积小、模块化的集成电路的形式,在一些大型的电子设备或机械仪器中充当不可或缺的一部分,基于单片机为基础的打铃系统不仅有较成熟的技术而且成本低廉、体积小,根据功能需求可以很容易的设计多元的定时器,未来的自动打铃系统将会朝着多元化的趋势行进,比如定时与记忆保护功能的实现,基于单片机为基础的自动打铃系统适合于低成本的大量生产,多元化发展的道路上具有很大的发展前景。

1.3研究的基本任务与方案设计
1.3.1 研究任务

研究基于单片机的自动打铃系统设计,掌握基于单片机自动打铃系统工作原理与设计思想,并设计具体电路,达到一定的设计要求,熟悉基本电路原理及模拟技术,掌握基于单片机的自动打铃系统的结构及原理,具体电路设计和功能等。

1.3.2 方案设计

方案的确立与论证

根据设计要求,进行方案设计,形成以数字逻辑电路为基础的方案一、以单片机位控制核心的方案二。对这两种方案说明如下:

方案一:采用数字逻辑电路(即与或非等门电路)设计的自动打铃系统。利用函数信号发生器来进行脉冲信号输出,利用74160N来设置十进制和六进制的进位输出。利用数码显示器来显示时间,利用或门、与门、非门、与非门、等电路元件进行组合实现打铃的控制。

方案二:采用以51单片机为基础而设计的自动打铃系统。单片机内部存储器设三个字节分别存放时钟的时、分、秒信息。利用定时器与软件结合实现1秒定时中断,每产生一次中断,存储器内相应的秒字节值加1;若秒字节值达到60,则将其清零,并将相应的分字节值加1;若分值达到60,则清零分字节,并将时字节值加1;若时值达到24,则将时字节清零。建立完一个实时时钟后,接下来进行定时分析处理和打铃输出,当主程序检测到有分进位标志时,便开始比较当前时间与用户设定的定时时间是否相同,若相同,则执行打铃提醒功能;不相同,则返回主程序。

通过对比以上两种方案,可以看出:方案一的设计只能事先设定打铃时间而不能完全自动打铃,且在修改打铃时间上存在一定的困难,操作过程繁琐。而方案二中的设计就能完全实现自动化,并且控制精确、操作简易、方便,也诠释了本设计的最终要求和目的。所以,我选择方案二进行设计。

根据所选定的设计方案,具体的设计主要分为硬件和软件两大部分,现规划如下:

硬件部分其中包括电路原理图、合理选择元器件、绘制线路图,然后对硬件进行调试、测试,达到设计要求。硬件电路采用结构化系统设计方法,该方法保证设计电路的标准化、模块化。硬件电路的设计最重要的选择用于控制的单片机,并确定与之配套的外围芯片,使设计的系统既经济又高性能。硬件电路设计包括输入射出接口设计,画出详细电路图,标出芯片的信号、器件参数值,根据电路图在仿真机上进行调试,修改,最终达到设计要求。

软件部分:首先在总体设计中完成软件系统流程规划和各模块的功能设计,然后进行具体设计,包括各模块的流程图,软件程序编写等;最后对软件进行调试、测试,达到所需的功能要求。

1.4 文档的内容与结构

在自动打铃系统的基础上可以实现多种功能,设计主要研究时间内容的显示与时间数据的分析并响应两大部分。文档共有五章。第一章对自动打铃系统的概况进行简单的介绍,包括自动打铃系统的研究意义和当前的发展状况。第二章介绍本设计的硬件电路方案,包括单片机系统、LCD显示部分、按键部分、时钟部分、打铃部分等。第三章则详细地介绍软件系统的设计流程和各项子程序的设计流程。第四章介绍本设计用到的开发软件,以及对硬件的测试与调试。第五章结论里对本设计进行了总结。


第2章 硬件电路的设计与实现

2.1 硬件电路总体设计

系统的总硬件原理图和实物图分别为图2-1与图2-2,本系统主要由主控电路,时钟电路,显示电路,按键电路等4 部分构成。通过内部定时产生中断,从而使驱动电铃打铃。设定51 单片机工作在定时器0工作方式1 ,每100ms产生一次中断,利用软件将基准100ms 单元进行累加,当定时器产生10 次中断就产生lS 信号,这是秒单元加1 。同理,对分单元和时单元计数从而产生秒,分,时的值。由于动态显示法需要数据所存等硬件,接口较复杂,考虑显示的位数和系统没有其他浮躁的处理程序,所以采用LCD1602进行显示。本系统采用四个按键,当时钟时间和设置时间一致时,CPU控制蜂鸣器进行打铃。系统设计的实物图如图2-2所示。

图2-1总硬件电路原理图

图2-2总硬件电路实物图

2.2 单片机最小系统

单片机的最小系统是指单片机工作时所需的最少元件,即:单片机、晶振电路、复位电路。本设计主要采用的STC89C51单片机最小系统如图2-3所示。

图2-3单片机最小系统

STC89C51单片机

本设计采用STC89C51单片机,如图2-4所示。STC89C51是一款高性能、低功耗的8位CMOS微处理芯片其具备4K的FLASH程序存储器,256字节的内部RAM、6个不同的中断源、4和中断优先级、4个8位I/O口、2个16位的定时计数器、全双工的串口通信。

图2-4 STC89C51单片机引脚图

各引脚的用途如下所示:

  • VCC(40):接电源+5V,用于电路供电。
  • GND(20):接地,用于保护电路。
  • XTAL1(19)和XTAL2(18):当时钟脉冲式输入状态时,用外部振荡电路,如果有1个外接电容,就用时钟电路。当外部时钟脉冲来临时,用来接输入的脉冲信号。由于石英晶体和外部电容的作用,故该口也有反向放大的作用。
  • P0(39-32):双向I/O口,不拓展的情况下,可用作普通的输入输出使用。也可用作地址数据总线口使用、
  • P1(1-8):准双向通用I/O口,可输出推动4个肖特基TTL负载,一般加一个上拉电阻以便外部接收器不被损坏,此时它就是输入端口。
  • P2(21-28):不拓展时,用作一般的双向I/O口,当它为 8 位双向 I/O 口时,P2 缓冲器可以接受输出的 4个晶体管-晶体管逻辑电路门限电流。当 P2口收到的信号为“1”时候,说明外加的电压大于单片机的电压,单片机内部将管脚电压升高,让该管脚作为输入端口。
  • P3(10-17):多用途端口。P3口管脚是由8个内部上拉电阻组成的双向I/O 口,可接收输出4个TTL门电流。当P3口收到“1”,单片机机内部的电阻开始作用,对此口加上高电平,使得这个管脚有输入作用
  • RST(9):复位信号输入端口,收到高电位时,便开始工作,要完成复位作用就需要无外部的时钟脉冲进行作用。此时会出现多个振荡周期的高电平信号,它们加在复位端口,完成复位用。
  • EA(31):内部和外部程序存储器的选择线,该引脚为低电平EA=0时,读取外部ROM 0000H-FFFFH,当该引脚为高电位时,地址0000H-0FFFH访问ROM, 000H-FFFFH访问外部ROM。
  • PSEN(29):即片选程序存储器选通信号,当低电平信号到来时,它会自动访问单片机尾部的程序存储器。但此时需要两个连续低电平信号持续访问才有效。
  • ALE/PROG(30):ALE为高电平信号,同时也是外部地址锁存器的锁存信号。在没有特殊要求的情况下,FALE=1/6FOSC,因此它可以用作其他芯片的时钟源或用于定时作用。
2.3 显示电路设计

显示器是属于I/O设备,即输入输出设备。它是一种将一定的电子文件通过特定的传输设备显示到屏幕上再反射到人眼的显示工具。而本设计的显示部分采用的是LCD1602液晶显示器。其电路图和实物图如图2-5与图2-6所示。这是一款工业字符型液晶,显示质量极高,能够同时显示16x02即32个字符。其显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,即可以显示出图形。不过,由于单片机P0口不能输出高电平,所以必须在LCD1602 上加上拉电阻从而使其能输出高电平。

图2-5 LCD1602液晶显示器电路图

图2-6 LCD1602液晶显示器实物图

LCD1602引脚功能说明如下:

第1引脚:GND为电源地

第2引脚:VCC接5V电源正极

第3引脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高

第4引脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。

第5引脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。

第6引脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。

第7~14引脚:D0~D7为8位双向数据端。第15~16脚:空脚或背灯电源。第15引脚背光正极,第16引脚背光负极。

2.4 按键电路设计

按键在电路中的作用就是通过触点的接触与断开来控制电路的通断。而本设计由于键盘只有四个,采用独立式按钮,通过查询完成读取键盘功能分别为K1,K2,K3,K4。其中,K1用以加和查看农历,K2应以减,K3用以切换设置选项、K4用以进入设置界面和返回时钟走时主界面。控制时、分、秒的调节以及设定时间模式的开关和返回正常走时模式的功能。按键电路的电路图和实物图如图2-7和2-8所示。

图2-7按键电路图

图2-8按键实物图

2.5 时间电路设计

本设计采用的时钟是DS1302。DS1302是一种高性能、低功耗、带RAM的实时时钟芯片,它可以对年、月、日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。其与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:1.RSE复位,2.I/O数据线,3.SCLK 串行时钟。时钟/RAM 的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低。提供秒、分、时、日、月、年的信息,每月的天数和闰年的天数可自动调整时钟,操作可通过AM/PM指示决定采用24或12小时格式。其电路图和实物图如图2-9和2-10所示。

图2-9 DS1302电路图


图2-10 DS1302实物图

DS1302引脚功能说明如下:

XI XZ 32.768KHz 晶振管脚。

GND 接地。

RST 复位脚。

I/O 数据输入/输出引脚。

SCLK 串行时钟。

VCC1、VCC2 电源供电管脚。

DS1302 串行时钟芯片8脚 DPI。

DS1302S 串行时钟芯片8脚 SOIC 200mil。

DS1302Z 串行时钟芯片8脚 SOIC 150mil。

2.6 打铃电路的设计

打铃是为了在用户需要的时刻起到必要的提醒作用,本设计针对用户设定的时间进行响应,将实时对比设定时间和系统走时,二者相一致时,打铃电路就会开始工作。打铃电路的电路图与实物图如图2-11和2-12所示。蜂鸣器两端分别接电源和89C51的P3.7接口,接收来自单片机的信号,从而实现打铃功能。

图2-11打铃电路电路图

图2-12打铃电路实物图(蜂鸣器)










第3章 软件电路的设计与实现3.1 软件系统设计

根据硬件电路设计,软件设计的总流程图如图3-1所示。外部电源供电后,系统完成初始化,之后就读取时间、显示时间。然后判断用户是否要对时间进行调整,若需要,则调整时间,反之则不调整。之后判断是否需要设置时间进行打铃提示,若需要,则设置,否则不不设置。最后判断当前时间是否为设定的打铃时间,是则打铃,反之不打铃并返回读取时间显示处,重复进行。

图3-1软件设计总流程图

3.2 显示子程序

显示电路流程图如图3-2所示。起初,LCD1602初始化显示。当RS为高电平、RW为低电平时,写入数据,液晶屏显示预设值。经过10us的延时后清屏,设置数据为8位,然后,显示器待机等待数据,数据到来时,显示在屏幕上。此时,判断是否显示完毕,若已显示完毕,就结束;反之,就继续接受数据显示,直至显示完毕。

图3-3显示电路流程图
3.3 按键子程序

按键电路流程图如图3-4所示。本设计采用了4个独立按键,因工作方式相同,故流程相同。首先判断按键是否闭合,若是,则延时10ms。然后再次判断按键是否,若仍是,则对其进行处理,反之则返回重复执行。

图3-4按键电路流程图

3.4 时间子程序

时间电路流程图如图3-5所示。首先读取系统默认的时间,再根据用户需要是否做出调整,若需要,则调整;不需要,则结束。

图3-5时间电路流程图

3.5 铃子程序

打铃电路流程图如图3-6所示。首先,进行初始化,然后读取当前时间数据,随后判断读取时间与用户设定的打铃时间是否一致,是,则打铃;反之则结束程序。

图3-6打铃电路流程图


第4 开发软件的介绍及系统测试4.1 开发软件的介绍4.1.1 Proteus

本系统的硬件设计首先是在Proteus软件环境中仿真实现的。Proteus软件是来自英国Labcenter electronics公司的EDA工具软件,Proteus软件有十多年的历史,在全球广泛使用,除了具有和其它EDA工具一样的原理布图、PCB自动或人工布线及电路仿真的功能外,其革命性的功能是,它的电路仿真是互动的。针对微处理器的应用,还可以直接在基于原理图的虚拟原型上编程,并实现软件源码级的实时调试。如果有显示及输出,配合系统配置的虚拟仪器如示波器、逻辑分析仪等,还能看到运行后输入输出的效果。Proteus建立了完备的电子设计开发环境,尤其重要的是Proteus Lite可以完全免费,也可以花微不足道的费用注册达到更好的效果[2]。

Proteus是目前最好的模拟单片机外围器件的工具。可以仿真51系列、AVR、PIC等常用的MCU及其外围电路(如LCD,RAM,ROM,键盘,马达,LED,AD/DA,部分SPI器件,部分IIC器件...)。其实Proteus 与 multisim比较类似,只不过它可以仿真MCU,当然,软件仿真精度有限,而且不可能所有的器件都找得到相应的仿真模型,用开发板和仿真器当然是最好选择,可是初学者拥有它们的可能性比较小。当然,硬件实践还是必不可少的。在没有硬件的情况下,Proteus能像pspice 仿真模拟/数字电路那样仿真MCU及外围电路。另外,即使有硬件,在程序编写早期用软件仿真一下也是很有必要的。Proteus软件主要具有以下几个方面的特点:

1、设计和仿真软件Proteus 是一个很有用的工具,它可以帮助学生和专业人士提高他们的模拟和数字电路的设计能力。

2、它允许对电路设计采用图形环境,在这种环境中,可以使用一个特定符号来代替元器件,并完成不会对真实电路造成任何损害的电路仿真操作。

3、它可以仿真仪表以及可描述在仿真过程中所获得的信号的图表。

4、它可以仿真目前流行的单片机,如PICS, ATMEL-AVR, MOTOROLA, 8051 等。

5、在设计综合性方案中,还可以利用ARES开发印制电路板。

4.1.2 Keil C

Keil C是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。用过汇编语言后再使用C来开发,体会更加深刻。KeilC51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

4.2 系统仿真

通过以上硬件设计和软件设计过程,设计工作已基本完成。接下来的工作就是对已设计好的系统进行仿真和调试。通过仿真,可以体现出系统所具备的功能;通过调试,可以检查出系统出现的错误,从而进行进一步的改正。

本系统设计在Proteus中的仿真图如图4-1所示:

图4-1 系统仿真图

接通电源后,系统默认上次设定时间,显示模块灯亮并显示时间内容。通过按键可以设置打铃时刻及阴阳历查看。

4.3 系统测试

电路测试

硬件电路的最终测试是本次设计的核心。为了硬件电路能正常运行,要对每一个电路部分进行测试并调整。图4-2为测试图。现分部测试说明如下:

(1)显示部分:如图4-2液晶显示屏测试,通电后,LCD1602显示器亮,说明显示部分没问题。

(2)按键部分:如图4-2按键测试,按下按键K1,LCD1602显示的是农历时间;按下K4,可以进入时间设置界面,说明按键部分也没问题。

(3)打铃部分:调节打铃时刻,使当前时间和打铃所设定的时刻相吻合,蜂鸣器响,说明蜂鸣器也能正常工作。

图4-2 系统硬件测试图

系统整体测试

(1)系统测试一如图4-3所示,系统通电,按下启动开关。此时,显示器显示时钟芯片默认的时间并正常走时。

图4-3系统测试一

(2)系统测试二分别为图4-4和4-5,按下K4按键,进入设置主界面。再通过按K3L按键来切换设置选项,进入到设置打铃界面。通过按下K1、K2来设定一个打铃时间,然后再按下K4,返回时间显示主界面。

图4-4 设置主界面

图4-5 设置打铃界面

(3)系统测试三如图4-6所示,当系统时间和设定的打铃时间吻合时,显示器显示提示,蜂鸣器响。此时按下任意键,蜂鸣器停止响动,系统继续走时。

图4-6 系统测试三












第5章  

综上所述,整个硬件电路由STC89C51单片机、DS1302时钟、LCD1602液晶显示器、按键电路、打铃电路等组成。本设计能够很好地完成对时间的实时显示和时刻打铃的任务,设计从STC89C51单片机最基本的硬件系统入手,拓展到其他所需要的硬件。通过时钟芯片和LCD显示器与单片机系统的配合,有效地完成了时间的显示和时刻的打铃。本设计采用的是以单片机和时钟芯片控制的自动化系统,使用起来更加简单、更加方便。总的来说,完成本设计任务,设计的系统具有很不错的实用价值。


参考文献

[1] 谭浩强.C语言程序设计. 第五版[M].北京:清华大学出版社,2017

[2] 马秀丽、周越、王红. 单片机原理与应用系统设计.第二版[M].北京:清华大学出版社,2017

[3] 朱晓青、凌云、袁川来. 传感器与检测技术[M]. 北京:清华大学出版社,2014

[4] 马建明. 数据采集与处理技术上册、下册.第三版[M]. 西安:西安交通大学出版社,2012

[5] 刘少强、张靖. 现代传感器技术——面向物联网应用.第二版[M] . 北京:电子工业出版社,2016

[6] 廖建尚. 物联网&云平台高级应用开发[M]. 北京:电子工业出版社,2017

[7] 朱清慧,张凤蕊,翟天嵩等. Proteus教程—电子线路设计、制版与仿真.第三版[M]. 北京:清华大学出版社,2016

[8] 王渊峰,戴旭辉. Altium Designer 10电路设计标准教程[M]. 北京:科学出版社,2012

[9]马忠梅,籍顺心等.单片机的C语言应用程序设计[M].北京航空航天大学出版社, 2001年

[10]新编单片机原理与应用.第二版[M].西安电子科技大学出版社,2007.2

[11]张萌.单片机应用系统开发综合实例[M]. 北京:清华大学出版社,2007.7

[12]楼然苗.单片机设计指导[M]. 北京:北京航空航天大学出版社,2007.7

[13]李广弟. 单片机原理及应用[M].北京航空航天大学出版社,2004年




致谢

时光转瞬即逝!在即将进行文档之际,首先要感谢我的指导老师——老师。在他的帮助下,我掌握了参阅查询资料和筛选有用文献的方法。从设计之初,老师就全程参与,经常利于课余时间给我们讲解,这让我非常感动,老师严谨的指导态度和温和而耐心的性情让我终身受益。还有感谢我的同行朋友同学们,在整个设计与学习的过程中给予我很多的帮助。在这样温暖的环境中,我们形成了良好的学习风气,互帮互助,攻克了学习道路上的一道道难关,他们在我低谷的时候不仅没有嘲笑我,而且还帮助我解决了很多问题,突破了很多难点,带我走出困境。其次,感谢我的同行同学们,是他们在设计中尽量的帮助我,才让这次设计进行的如此顺利,他们的设计理念、见解给了我很大的启发,在遇到想不通的问题的时候, 他们给我提供多种方案,带我走出思维的困境,让我在实际操作更加顺利。同时,在交流和学习中,我也更加深刻的认识到团队精神的重要性。同学们对在硬件的设计和软件的编写上给了我很大的帮助,给我讲解如何看懂程序、如何分析内容、如何根据要执行的功能进行正确的编程,以及指出软硬件中出现的问题。希望今后多多交流,毕竟友谊地久天长!最后,再次向给予我帮助的指导老师和同行同学们致以最衷心的感谢!



附录附录一:自动打铃系统原理图
附录二:源程序
  1. #include <reg51.h>                       //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义              变量范围0~255
  3. #define uint  unsigned int              //无符号整型 宏定义              变量范围0~65535
  4. #include "eeprom52.h"
  5. #include "nongli.h"
  6. bit flag_200ms ;
  7. bit flag_100ms ;
  8. sbit beep = P3^7;                //蜂鸣器定义
  9. bit flag_beep_en;
  10. uint clock_value;     //用作闹钟用的
  11. sbit dq   = P3^1;                //18b20 IO口的定义
  12. uint temperature ;    //温度变量
  13. uchar flag_nl;        //农历 阳历显示标志位
  14. uchar menu_1,menu_2;
  15. uchar key_time,flag_value;      //用做连加的中间变量
  16. bit key_500ms  ;
  17. uchar n_nian,n_yue,n_ri;                            //农历显示的函数
  18. #include "ds1302.h"
  19. #include "lcd1602.h"
  20. /******************把数据保存到单片机内部eeprom中******************/
  21. void write_eeprom()
  22. {
  23.               SectorErase(0x2000);
  24.               byte_write(0x2000, fen1);
  25.               byte_write(0x2001, shi1);
  26.               byte_write(0x2002, open1);
  27.               byte_write(0x2058, a_a);            
  28. }

  29. /******************把数据从单片机内部eeprom中读出来*****************/
  30. void read_eeprom()
  31. {
  32.               fen1  = byte_read(0x2000);
  33.               shi1  = byte_read(0x2001);
  34.               open1  = byte_read(0x2002);
  35.               a_a      = byte_read(0x2058);
  36. }
  37. /**************开机自检eeprom初始化*****************/
  38. void init_eeprom()
  39. {
  40.               read_eeprom();                            //先读
  41.               if(a_a != 1)                            //新的单片机初始单片机内问eeprom
  42.               {
  43.                             fen1  = 3;
  44.                             shi1  = 8;
  45.                             open1  = 1;
  46.                             a_a = 1;
  47.                             write_eeprom();                 //保存数据
  48.               }            
  49. }
  50. /***********************18b20初始化函数*****************************/
  51. void init_18b20()
  52. {
  53.               bit q;
  54.               dq = 1;                                                        //把总线拿高
  55.               delay_uint(1);                  //15us
  56.               dq = 0;                                                        //给复位脉冲
  57.               delay_uint(80);                            //750us
  58.               dq = 1;                                                        //把总线拿高 等待
  59.               delay_uint(10);                            //110us
  60.               q = dq;                                                        //读取18b20初始化信号
  61.               delay_uint(20);                            //200us
  62.               dq = 1;                                                        //把总线拿高 释放总线
  63. }

  64. /*************写18b20内的数据***************/
  65. void write_18b20(uchar dat)
  66. {
  67.               uchar i;
  68.               for(i=0;i<8;i++)
  69.               {                                                                      //写数据是低位开始
  70.                             dq = 0;                                          //把总线拿低写时间隙开始
  71.                             dq = dat & 0x01; //向18b20总线写数据了
  72.                             delay_uint(5);              // 60us
  73.                             dq = 1;                                          //释放总线
  74.                             dat >>= 1;
  75.               }            
  76. }

  77. /*************读取18b20内的数据***************/
  78. uchar read_18b20()
  79. {
  80.               uchar i,value;
  81.               for(i=0;i<8;i++)
  82.               {
  83.                             dq = 0;                                          //把总线拿低读时间隙开始
  84.                             value >>= 1;              //读数据是低位开始
  85.                             dq = 1;                                          //释放总线
  86.                             if(dq == 1)                            //开始读写数据
  87.                                           value |= 0x80;
  88.                             delay_uint(5);              //60us              读一个时间隙最少要保持60us的时间
  89.               }
  90.               return value;                            //返回数据
  91. }
  92. /*************读取温度的值 读出来的是小数***************/
  93. uint read_temp()
  94. {
  95.               uint value;
  96.               uchar low;                                             //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
  97.               init_18b20();                               //初始化18b20
  98.               write_18b20(0xcc);                 //跳过64位ROM
  99.               write_18b20(0x44);                 //启动一次温度转换命令
  100.               delay_uint(50);                               //500us
  101.               init_18b20();                               //初始化18b20
  102.               write_18b20(0xcc);                 //跳过64位ROM
  103.               write_18b20(0xbe);                 //发出读取暂存器命令
  104.               EA = 0;
  105.               low = read_18b20();                 //读温度低字节
  106.               value = read_18b20();  //读温度高字节
  107.               EA = 1;
  108.               value <<= 8;                               //把温度的高位左移8位
  109.               value |= low;                               //把读出的温度低位放到value的低八位中
  110.               value *= 0.625;                     //转换到温度值 小数
  111.               return value;                               //返回读出的温度 带小数
  112. }



  113. /******************1ms 延时函数*******************/
  114. void delay_1ms(uint q)
  115. {
  116.               uint i,j;
  117.               for(i=0;i<q;i++)
  118.                             for(j=0;j<120;j++);
  119. }

  120. /******************写星期函数*******************/
  121. void write_week(uchar hang,uchar add,uchar week)//写星期函数
  122. {
  123.               if(hang==1)  
  124.                             write_com(0x80+add);
  125.               else
  126.                             write_com(0x80+0x40+add);               
  127.               switch(week)
  128.               {
  129.                             case 1:write_data('M');//星期数为1时,显示
  130.                                              write_data('O');
  131.                                              write_data('N');
  132.                                              break;
  133.                
  134.                             case 2:write_data('T');//星期数据为2时显示
  135.                                              write_data('U');
  136.                                              write_data('E');
  137.                                              break;
  138.                            
  139.                             case 3:write_data('W');//星期数据为3时显示
  140.                                              write_data('E');
  141.                                              write_data('D');
  142.                                              break;
  143.                             case 4:write_data('T');//星期数据为4是显示
  144.                                              write_data('H');
  145.                                              write_data('U');
  146.                                              break;
  147.                             case 5:write_data('F');//星期数据为5时显示
  148.                                              write_data('R');
  149.                                              write_data('I');
  150.                                              break;
  151.                             case 6:write_data('S');//星期数据为6时显示
  152.                                              write_data('T');
  153.                                              write_data('A');
  154.                                              break;
  155.                             case 0:write_data('S');//星期数据为7时显示
  156.                                              write_data('U');
  157.                                              write_data('N');
  158.                                              break;
  159.               }
  160. }
  161. /*************时钟显示***************/
  162. void init_1602_ds1302()
  163. {
  164.               write_sfm2_ds1302(1,1,shi);                               //显示时
  165.               write_sfm2_ds1302(1,4,fen);                               //显示分
  166.               write_sfm2_ds1302(1,7,miao);                 //显示秒
  167.               write_week(2,12,week);
  168. //              write_sfm1(1,14,week);                                             //显示星期
  169.               write_sfm3_18B20(1,11,temperature);                 //显示温度
  170.               if(flag_nl == 0)  //显示阳历
  171.               {
  172.                             write_sfm2_ds1302(2,2,nian);   //显示年
  173.                             write_sfm2_ds1302(2,5,yue);                 //显示月            
  174.                             write_sfm2_ds1302(2,8,ri);                 //显示日              
  175.               }
  176.               else                                           //显示农历
  177.               {
  178.                             write_sfm2_ds1302(2,2,n_nian);              //显示年
  179.                             write_sfm2_ds1302(2,5,n_yue);              //显示月            
  180.                             write_sfm2_ds1302(2,8,n_ri);              //显示日
  181.                            
  182.               }
  183. }                                                                                                                                
  184. /*************定时器0初始化程序***************/
  185. void init_time0()               
  186. {
  187.               EA   = 1;                              //开总中断
  188.               TMOD = 0X01;                //定时器0、工作方式1
  189.               ET0  = 1;                              //开定时器0中断
  190.               TR0  = 1;                              //允许定时器0定时
  191. }

  192. /*************闹钟报警函数***************/
  193. void menu_dis()
  194. {
  195.               static uchar mm,value;
  196.               if(flag_100ms == 1)                              //100ms执行一次
  197.               {
  198.                             flag_100ms = 0;
  199.                             if(open1 == 1)              //如果闹钟打开
  200.                             {
  201.                                           if((miao == 0) && (fen == fen1) && (shi == shi1))
  202.                                           {                           
  203.                                                         flag_beep_en = 1;              //有报警 打开蜂鸣器响的标志位                                         
  204.                                           }                           
  205.                                           if(flag_beep_en == 1)              //闹钟以被打开
  206.                                           {
  207.                                                         clock_value++;
  208.                                                         if(clock_value <= 30)            
  209.                                                                       beep = ~beep;                 //蜂鸣器叫3秒
  210.                                                         else if(clock_value > 30)
  211.                                                         {
  212.                                                                       beep = 1;                                //蜂鸣器停1秒
  213.                                                                       if(clock_value > 40)
  214.                                                                       {
  215.                                                                                     clock_value = 0;
  216.                                                                       }
  217.                                                         }
  218.                                                         //  1 分钟后自动关闭闹钟
  219.                                                         value ++;
  220.                                                         if(value >= 10)
  221.                                                         {
  222.                                                                       value = 0;
  223.                                                                       mm++;
  224.                                                                       if(mm >= 60)
  225.                                                                       {
  226.                                                                                     mm = 0;
  227.                                                                                     flag_beep_en = 0;
  228.                                                                                     beep = 1;            
  229.                                                                       }
  230.                                                         }                                                                     
  231.                                           }
  232.                             }            
  233.               }
  234. }
  235. /********************独立按键程序*****************/
  236. uchar key_can;              //按键值
  237. void key()              //独立按键程序
  238. {
  239.               static uchar key_new;
  240.               key_can = 20;                   //按键值还原
  241.               P3 |= 0x78;                     //对应的按键IO口输出为1
  242.               if((P3 & 0x78) != 0x78)                            //按键按下
  243.               {
  244.                             delay_1ms(1);                                 //按键消抖动
  245.                             if(((P3 & 0x78) != 0x78) && (key_new == 1))
  246.                             {                                                                                    //确认是按键按下
  247.                                           key_new = 0;
  248.                                           switch(P3 & 0x78)
  249.                                           {
  250.                                                         case 0x70:  key_can = 4;  break;              //得到按键值
  251.                                                         case 0x68:  key_can = 3;  break;              //得到按键值
  252.                                                         case 0x58:  key_can = 2;  break;              //得到按键值
  253.                                                         case 0x38:  key_can = 1;  break;              //得到按键值
  254.                                           }
  255. //                                          write_sfm2(1,0,key_can);                                                        //显示按键值
  256.                             }                                         
  257.               }
  258.               else
  259.                             key_new = 1;            
  260. }
  261. /**********************设置函数************************/
  262. void key_with()
  263. {
  264.               if(key_can == 1)              //设置键
  265.               {
  266.                             menu_1++;
  267.                             if(menu_1 == 1)                //设置时间
  268.                             {
  269.                                           menu_2 = 1;
  270.                                           write_string(1,0,"    :  :    W:  ");                                         
  271.                                           write_string(2,0," 20  -  -       ");            
  272.                             }
  273.                             if(menu_1 == 2)                //设置闹钟
  274.                             {
  275.                                           menu_2 = 1;
  276.                                           write_string(1,0,"   set clock    ");                                         
  277.                                           write_string(2,0,"    Y  00:00      ");            
  278.                             }
  279.                             if(menu_1 > 2)    //回到正常显示
  280.                             {
  281.                                           menu_1 = 0;
  282.                                           write_guanbiao(1,2,0);              //关闭光标
  283.                                           init_1602_dis_csf();      //初始化液晶显示                           
  284.                             }
  285.               }
  286.               if(key_can == 2)              //选择键
  287.               {
  288.                             flag_200ms = 1;
  289.                             if(menu_1 == 1)                              //设置时间
  290.                             {
  291.                                           menu_2 ++;
  292.                                           if(menu_2 > 7)
  293.                                                         menu_2 = 1;
  294.                             }
  295.                             if(menu_1 == 2)                            //设置闹钟
  296.                             {
  297.                                           menu_2 ++;
  298.                                           if(menu_2 > 3)
  299.                                                         menu_2 = 1;                                                      
  300.                             }
  301.               }
  302.               if(menu_1 == 1)
  303.               {
  304.                             if(menu_2 == 1)                              //设置时
  305.                             {
  306.                                           if(key_can == 3)              //加
  307.                                           {
  308.                                                         shi+=0x01;
  309.                                                         if((shi & 0x0f) >= 0x0a)
  310.                                                                       shi = (shi & 0xf0) + 0x10;
  311.                                                         if(shi >= 0x24)
  312.                                                                       shi = 0;
  313.                                           }                           
  314.                                           if(key_can == 4)              //减
  315.                                           {
  316.                                                         if(shi == 0x00)
  317.                                                                       shi = 0x24;
  318.                                                         if((shi & 0x0f) == 0x00)
  319.                                                                       shi = (shi | 0x0a) - 0x10;
  320.                                                         shi -- ;
  321.                                           }                                                                       
  322.                             }
  323.                             if(menu_2 == 2)                              //设置分
  324.                             {
  325.                                           if(key_can == 3)              //加
  326.                                           {
  327.                                                         fen+=0x01;
  328.                                                         if((fen & 0x0f) >= 0x0a)
  329.                                                                       fen = (fen & 0xf0) + 0x10;
  330.                                                         if(fen >= 0x60)
  331.                                                                       fen = 0;
  332.                                           }                           
  333.                                           if(key_can == 4)              //减               
  334.                                           {
  335.                                                         if(fen == 0x00)
  336.                                                                       fen = 0x5a;
  337.                                                         if((fen & 0x0f) == 0x00)
  338.                                                                       fen = (fen | 0x0a) - 0x10;
  339.                                                         fen -- ;
  340.                                           }            
  341.                             }
  342.                             if(menu_2 == 3)                              //设置秒
  343.                             {
  344.                                           if(key_can == 3)              //加
  345.                                           {
  346.                                                         miao+=0x01;
  347.                                                         if((miao & 0x0f) >= 0x0a)
  348.                                                                       miao = (miao & 0xf0) + 0x10;
  349.                                                         if(miao >= 0x60)
  350.                                                                       miao = 0;
  351.                                           }            
  352.                                           if(key_can == 4)              //减               
  353.                                           {
  354.                                                         if(miao == 0x00)
  355.                                                                       miao = 0x5a;
  356.                                                         if((miao & 0x0f) == 0x00)
  357.                                                                       miao = (miao | 0x0a) - 0x10;
  358.                                                         miao -- ;                                         
  359.                                           }
  360.                             }
  361.                             if(menu_2 == 4)                              //设置星期
  362.                             {
  363.                                           if(key_can == 3)              //加
  364.                                           {
  365.                                               week+=0x01;
  366.                                                         if((week & 0x0f) >= 0x0a)
  367.                                                                       week = (week & 0xf0) + 0x10;
  368.                                                         if(week >= 0x08)
  369.                                                                       week = 1;
  370.                                           }                           
  371.                                           if(key_can == 4)              //减               
  372.                                           {
  373.                                                         if(week == 0x01)
  374.                                                                       week = 0x08;
  375.                                                         if((week & 0x0f) == 0x00)
  376.                                                                       week = (week | 0x0a) - 0x10;
  377.                                                         week -- ;
  378.                                           }            
  379.                             }
  380.                             if(menu_2 == 5)                              //设置年
  381.                             {
  382.                                           if(key_can == 3)              //加
  383.                                           {
  384.                                               nian+=0x01;
  385.                                                         if((nian & 0x0f) >= 0x0a)
  386.                                                                       nian = (nian & 0xf0) + 0x10;
  387.                                                         if(nian >= 0x9a)
  388.                                                                       nian = 1;
  389.                                           }                           
  390.                                           if(key_can == 4)              //减               
  391.                                           {
  392.                                                         if(nian == 0x01)
  393.                                                                       nian = 0x9a;
  394.                                                         if((nian & 0x0f) == 0x00)
  395.                                                                       nian = (nian | 0x0a) - 0x10;
  396.                                                         nian -- ;                           
  397.                                           }            
  398.                             }
  399.                             if(menu_2 == 6)                              //设置月
  400.                             {
  401.                                           if(key_can == 3)              //加
  402.                                           {
  403.                                               yue+=0x01;
  404.                                                         if((yue & 0x0f) >= 0x0a)
  405.                                                                       yue = (yue & 0xf0) + 0x10;
  406.                                                         if(yue >= 0x13)
  407.                                                                       yue = 1;
  408.                                           }                           
  409.                                           if(key_can == 4)              //减               
  410.                                           {
  411.                                                         if(yue == 0x01)
  412.                                                                       yue = 0x13;
  413.                                                         if((yue & 0x0f) == 0x00)
  414.                                                                       yue = (yue | 0x0a) - 0x10;
  415.                                                         yue -- ;                                                                     
  416.                                           }            
  417.                             }
  418.                             if(menu_2 == 7)                              //设置日
  419.                             {
  420.                                           if(key_can == 3)              //加
  421.                                           {
  422.                                 ri+=0x01;
  423.                                           if((ri & 0x0f) >= 0x0a)
  424.                                                         ri = (ri & 0xf0) + 0x10;
  425.                                           if(ri >= 0x32)
  426.                                                         ri = 0;                                         
  427.                                           }                           
  428.                                           if(key_can == 4)              //减               
  429.                                           {
  430.                                                         if(ri == 0x01)
  431.                                                                       ri = 0x32;
  432.                                                         if((ri & 0x0f) == 0x00)
  433.                                                                       ri = (ri | 0x0a) - 0x10;
  434.                                                         ri -- ;                                         
  435.                                           }            
  436.                             }
  437.                             write_sfm2_ds1302(1,2,shi);                 //显示时
  438.                             write_sfm2_ds1302(1,5,fen);                 //显示分
  439.                             write_sfm2_ds1302(1,8,miao);                 //显示秒
  440.                             write_sfm1(1,14,week);                 //显示星期                                                                     
  441.                             write_sfm2_ds1302(2,3,nian);                 //显示年
  442.                             write_sfm2_ds1302(2,6,yue);                 //显示月
  443.                             write_sfm2_ds1302(2,9,ri);                 //显示日
  444.                             switch(menu_2)                 // 光标显示
  445.                             {
  446.                                           case 1:  write_guanbiao(1,2,1);  break;
  447.                                           case 2:  write_guanbiao(1,5,1);  break;
  448.                                           case 3:  write_guanbiao(1,8,1);  break;
  449.                                           case 4:  write_guanbiao(1,14,1);  break;
  450.                                           case 5:  write_guanbiao(2,3,1);  break;
  451.                                           case 6:  write_guanbiao(2,6,1);  break;
  452.                                           case 7:  write_guanbiao(2,9,1);  break;
  453.                             }
  454.                             write_time();                 //把时间写进去
  455.               }            
  456. /***************设置闹钟*********************/
  457.               if(menu_1 == 2)
  458.               {
  459.                             if(menu_2 == 1)                              //设置闹钟开关
  460.                             {
  461.                                           if(key_can == 3)            
  462.                                           {
  463.                                                         open1 = 1;                //闹钟开
  464.                                           }                           
  465.                                           if(key_can == 4)            
  466.                                           {
  467.                                                         open1 = 0;                //闹钟关
  468.                                           }                                                                       
  469.                             }
  470.                             if(menu_2 == 2)                              //设置闹钟时
  471.                             {
  472.                                           if(key_can == 3)              //加
  473.                                           {
  474.                                               shi1+=0x01;
  475.                                                         if((shi1 & 0x0f) >= 0x0a)
  476.                                                                       shi1 = (shi1 & 0xf0) + 0x10;
  477.                                                         if(shi1 >= 0x24)
  478.                                                                       shi1 = 0;
  479.                                           }                           
  480.                                           if(key_can == 4)              //减               
  481.                                           {
  482.                                                         if(shi1 == 0x00)
  483.                                                                       shi1 = 0x5a;
  484.                                                         if((shi1 & 0x0f) == 0x00)
  485.                                                                       shi1 = (shi1 | 0x0a) - 0x10;
  486.                                                         shi1 -- ;
  487.                                           }            
  488.                             }
  489.                             if(menu_2 == 3)                              //设置秒
  490.                             {
  491.                                           if(key_can == 3)              //加
  492.                                           {
  493.                                               fen1+=0x01;
  494.                                                         if((fen1 & 0x0f) >= 0x0a)
  495.                                                                       fen1 = (fen1 & 0xf0) + 0x10;
  496.                                                         if(fen1 >= 0x60)
  497.                                                                       fen1 = 0;
  498.                                           }            
  499.                                           if(key_can == 4)              //减               
  500.                                           {
  501.                                                         if(fen1 == 0x00)
  502.                                                                       fen1 = 0x5a;
  503.                                                         if((fen1 & 0x0f) == 0x00)
  504.                                                                       fen1 = (fen1 | 0x0a) - 0x10;
  505.                                                         fen1 -- ;                                         
  506.                                           }
  507.                             }
  508.                             if(open1 == 1)
  509.                                           write_string(2,4,"Y");            
  510.                             else
  511.                                           write_string(2,4,"N");            
  512.                             write_sfm2_ds1302(2,7,shi1);                 //显示闹钟时
  513.                             write_sfm2_ds1302(2,10,fen1);                 //显示闹钟分
  514.                             switch(menu_2)                 // 光标显示
  515.                             {
  516.                                           case 1:  write_guanbiao(2,4,1);  break;
  517.                                           case 2:  write_guanbiao(2,7,1);  break;
  518.                                           case 3:  write_guanbiao(2,10,1);  break;
  519.                             }            
  520.                             write_eeprom();     //保存闹钟时间
  521.               }                                         
  522. }
  523. /*****************主函数********************/
  524. void main()
  525. {            
  526.               beep = 0;                                            //开机叫一声  
  527.               delay_1ms(150);
  528.               P0 = P1 = P2 = P3 = 0xff;                            //单片机IO口初始化为1
  529.               init_time0();                            //初始化定时器
  530. ……………………

  531. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


1602万年历程序与仿真下载::

资料.7z (4.84 MB, 下载次数: 265)

word文档.docx (2.29 MB, 下载次数: 182)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏12 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:652643 发表于 2019-11-29 20:56 | 只看该作者
楼主你好,请问主函数里是怎么调用的呀,黑币不够下载不了附件
回复

使用道具 举报

板凳
ID:712687 发表于 2020-4-3 17:26 | 只看该作者
非常感谢
回复

使用道具 举报

地板
ID:735425 发表于 2020-4-22 17:59 | 只看该作者
很感谢,但是主函数这样就是写完了吗?
回复

使用道具 举报

5#
ID:737567 发表于 2020-4-25 16:50 | 只看该作者
请问一下,可以设置成多个不同时段自动打铃吗
回复

使用道具 举报

6#
ID:767375 发表于 2020-6-3 15:49 | 只看该作者
显示程序有问题打不开啊
回复

使用道具 举报

7#
ID:743050 发表于 2020-6-13 16:54 | 只看该作者
谢谢,优秀
回复

使用道具 举报

8#
ID:979060 发表于 2021-11-8 18:51 | 只看该作者
你好,你是星期计算是有问题的吧?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表