基于at89s51单片机控制的带有温度显示的电子钟设计_第1页
基于at89s51单片机控制的带有温度显示的电子钟设计_第2页
基于at89s51单片机控制的带有温度显示的电子钟设计_第3页
基于at89s51单片机控制的带有温度显示的电子钟设计_第4页
基于at89s51单片机控制的带有温度显示的电子钟设计_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

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

文档简介

河南工程学院毕业设计PAGEPAGE41基于AT89S51单片机控制的带有温度显示的电子钟设计摘要本文介绍了一款基于AT89S51单片机控制的带有温度显示的电子钟的设计,通过多功能数字钟带有温度的设计思路,详细叙述了系统硬件、软件的具体实现过程。论文重点阐述了数字钟硬件中MCU模块、温度模块、时钟模块、显示模块和相关控制模块等的模块化设计与制作;软件同样采用模块化的设计,包括中断模块、、温度模块、时间调整模块设计,并采用简单流通性强的C语言编写实现。本设计实现了时间的修改功能和年、月、日和星期的显示和温度显示功能。关键词:AT89S51单片机数字钟温度显示

AbstractThispaperintroducedthedesignofdigitalclockbasedonSCMofAT89S51,thespecificprocessofhowthesystemhardwareandsoftwareachievedweredetaileddescriptionthroughthedesignofmultifunctiondigitalclock.Themodulardesignandproduction,whichconsistedofMCUmodule,voicemodule,clockmoduleandtheassociatedcontrolmodule,weremainlyrecounted;Aswellashardwaredesigning,softwaredesignusethesamemethod,consistssuspensionmodule,alarmclockmodule,voicemodule,timeadjustmodule,andthatusetheClanguagetoachievebecauseofitssimpleandstrongnegotiability.Inthisdesignthefunctionsoftimeandalarmclockrunandchange,voicebroadcast,functionsoftheyear,month,dayandweekdisplayhavebeenachieved.Andbycomparingtheactualclock.

Key

words:AT89S51MicrocontrollerDigitalClocktheDisplayofTemperature目

录前言1第一章系统实现功能、设计方案论证及芯片介绍2第一节系统要求实现功能2第二节设计方案论证2第三节芯片介绍4一、DS18B20芯片介绍4二、DS1302芯片介绍9第二章电路硬件设计及分析13第一节时钟电路...13第二节复位电路13第三节DS1302时钟电路14第四节DS18B20温度计电路14第五节键盘电路15第六节显示电路16第七节按键提示电路17第三章软件设计18第一节主函数流程图18第二节18B20温度计流程图18第三节键盘电路流程图20第四节定时器T0中断服务程序流程图21第四章结束语22附录1电路原理图23附录2主程序清单24参考文献36致谢37前言单片微型计算机是随着超大规模集成电路技术的发展而诞生的,由于它具有体积小、功能强、性价比高等特点,所以广泛应用于电子仪表、家用电器、节能装置、军事装置、机器人、工业控制等诸多领域,使产品小型化、智能化,既提高了产品的功能和质量,又降低了成本,简化了设计。本文主要介绍由单片机控制的带有温度显示的电子钟的设计。随着人们生活水平的日益提高,人们对生活的要求越来越高,原有的事物已经不能满足人们的生活需求了,一些带有新功能的事物已经在慢慢的取代旧事物。就像电子钟一样,人们用电子钟不仅仅只是看时间了,人们还需要看温度了。越来越多的新功能更贴近人们的生活了,所以也越来越受人们所喜欢。带有温度的的电子钟可以使人们随时都可以了解温度的变化。

第一章系统实现功能、设计方案论证及芯片介绍第一节系统要求实现功能(1)万年历(2)温度显示(3)三键调时(设置键,上调键,下调键)(4)按键蜂鸣器提示第二节设计方案论证方案一用主芯片为AT89C51的单片机控制实现,使用单片机内部的定时计数器实现时间的设定,使用按键进行时间的调整和定时,按键有蜂鸣器提示,温度传感器使用DALLAS公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、抗干扰能力强、易配处理器等优点,特别适用于构成多点温度测控系统,可直接将温度转化成串行数字信号(提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多个传感器芯片。显示时间和温度使用数码管显示。方案1系统结构框图如图1-1所示。图1-1方案1系统结构框图方案二用主芯片为AT89C51的单片机控制实现,为了满足单片机系统的实时控制的需求,采用实时钟芯片DS1302,使用按键进行时间的调整和定时,按键蜂鸣器提示,温度传感器使用普通的温度传感器,由于温度传感器采集的数据为模拟量,又因为单片机AT89C51内部没有集成模数转换器,需要在控制系统的外部使用A/D转换装置,另外系统还应该把采集来的数据进行信号处理,显示温度和时间使用LCD1602显示。方案2系统结构框图如图1-2所示。图1-2方案2系统结构框图方案三用主芯片为AT89C51的单片机控制实现,为了满足单片机系统的实时控制的需求,采用实时钟芯片DS1302,使用按键进行时间的调整和定时,按键有蜂鸣器提示,温度传感器使用DALLAS公司生产的单总线式数字温度传感器。显示时间和温度使用LCD1602显示。方案3系统结构框图如图1-3所示。图1-3方案3系统结构框图方案选择方案一直接使用单片机内集成的定时器,产生定时节拍,编制软件计数器,进行节拍技术,理论上讲,不但能够完成秒表设计,还能够实现分钟、刻钟、小时的实时计时功能,在此基础上,如果加上足够精确的误差时间补偿处理,甚至可以实现日、星期、月、年等日历功能。但使用片内定时器有以下几个问题:1、时间补偿片内定时器采用中断方式提供计时节拍,中断的实质是随机程序切换,那么,中断响应时间是不可精确预测的。这样,必然会导致计时节拍的时间误差,在计时时间较短的情况下,比如1~99s计时,可以采用一些软件措施进行误差补偿,但当系统所需要的计时时间较长时,比如进行年、月、日的日历计时,定时中断误差扥积累就会很大,无法满足时间精度的要求。因此,在需要日历、时钟的场合,片内定时器的作用有限。片内定时器只适合于单片机短时间计时的要求。2、时钟维持使用片内定时器进行计时的时候,单片机始终要处于工作状态。才能维持计时时间,一旦停机或进入待机状态,开机后,计时时间就需要重新设定。在单片机系统中,有时,需要维持一个时钟,对控制工作进行时间标定。不管单片机系统开机、关机还是待机,系统时钟要始终维持。为了满足单片机系统的实时钟需求,最可靠的方法是采用实时钟芯片DS1302。温度的数据采集如果是一般的温度传感器,需要对信号进行处理,另外还需要模数转换装置,如果采用的是数字温度传感器18B20,可以直接将采集的信号转化为数字信息供单片机控制,这样不仅节约了成本,还提高了系统的可靠性和稳定性。所以本设计采用的是方案三。第三节芯片介绍一、DS18B20芯片介绍DS18B20是DALLAS公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、搞干扰能力强、易配处理器等优点,特别适用于构成多点温度测控系统,可直接将温度转化成串行数字信号(提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多个传感器芯片。它具有3引脚TO-92小体积封装形式,温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达1、DS18B20外形及引脚说明DS18B20外形及引脚如图1-4所示。图1-4DS18B20外形及引脚图在TO-92和SO-8的封装中引脚有所不同,具体差别请查阅PDF手册,在TO-92封装中引脚分配如下:(1)GND:地;(2)DQ:单线运用的数据输入输出引脚;(3)VDD:可选的电源引脚。2、DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。初始时,计数器1预置的是与-55℃相对应的一个预置值。以后计数器1每一个循环的预置数都由斜率累加器提供。为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±1/2LSB,即0.25℃。温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。DS18B20测量温度时使用特有的温度测量技术。DS18B20内部的低温度系数振荡器能产生稳定的频率信号;同样的,高温度系数振荡器则将被测温度转换成频率信号。当计数门打开时,DS18B20进行计数,计数门开通时间由高温度系数振荡器决定。芯片内部还有斜率累加器,可对频率的非线性度加以补偿。测量结果存入温度寄存器中。一般情况下的温度值应该为9位,但因符号位扩展成高8位,所以最后以16位补码形式读出。DS18B20工作过程一般遵循以下协议:初始化——ROM操作命令——存储器操作命令——处理数据。(1)初始化单总线上的所有处理均从初始化序列开始。初始化序列包括总线主机发出一复位脉冲,接着由从属器件送出存在脉冲。存在脉冲让总线控制器知道DS1820在总线上且已准备好操作。(2)ROM操作命令一旦总线主机检测到从属器件的存在,它便可以发出器件ROM操作命令之一。所有ROM操作命令均为8位长。这些命令介绍如下:ReadROM(读ROM)[33h]此命令允许总线主机读DS18B20的8位产品系列编码,唯一的48位序列号,以及8位的CRC。此命令只能在总线上仅有一个DS18B20的情况下可以使用。如果总线上存在多于一个的从属器件,那么当所有从片企图同时发送时将发生数据冲突的现象(漏极开路会产生线与的结果)。MatchROM(符合ROM)[55h]此命令后继以64位的ROM数据序列,允许总线主机对多点总线上特定的DS18B20寻址。只有与64位ROM序列严格相符的DS18B20才能对后继的存贮器操作命令作出响应。所有与64位ROM序列不符的从片将等待复位脉冲。此命令在总线上有单个或多个器件的情况下均可使用。SkipROM(跳过ROM)[CCh]在单点总线系统中,此命令通过允许总线主机不提供64位ROM编码而访问存储器操作来节省时间。如果在总线上存在多于一个的从属器件而且在SkipROM命令之后发出读命令,那么由于多个从片同时发送数据,会在总线上发生数据冲突(漏极开路下拉会产生线与的效果)。SearchROM(搜索ROM)[F0h]当系统开始工作时,总线主机可能不知道单线总线上的器件个数或者不知道其64位ROM编码。搜索ROM命令允许总线控制器用排除法识别总线上的所有从机的64位编码。AlarmSearch(告警搜索)[ECh]此命令的流程与搜索ROM命令相同。但是,仅在最近一次温度测量出现告警的情况下,DS18B20才对此命令作出响应。告警的条件定义为温度高于TH或低于TL。只要DS18B20一上电,告警条件就保持在设置状态,直到另一次温度测量显示出非告警值或者改变TH或TL的设置,使得测量值再一次位于允许的范围之内。贮存在EEPROM内的触发器值用于告警。(3)存储器操作命令WriteScratchpad(写暂存存储器)[4Eh]这个命令向DS18B20的暂存器中写入数据,开始位置在地址2。接下来写入的两个字节将被存到暂存器中的地址位置2和3。可以在任何时刻发出复位命令来中止写入。ReadScratchpad(读暂存存储器)[BEh]这个命令读取暂存器的内容。读取将从字节0开始,一直进行下去,直到第9(字节8,CRC)字节读完。如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。CopyScratchpad(复制暂存存储器)[48h]这条命令把暂存器的内容拷贝到DS18B20的E2存储器里,即把温度报警触发字节存入非易失性存储器里。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又正在忙于把暂存器拷贝到E2存储器,DS18B20就会输出一个“0”,如果拷贝结束的话,DS18B20则输出“1”。如果使用寄生电源,总线控制器必须在这条命令发出后立即起动强上拉并最少保持ConvertT(温度变换)[44h]这条命令启动一次温度转换而无需其他数据。温度转换命令被执行,而后DS18B20保持等待状态。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又忙于做时间转换的话,DS18B20将在总线上输出“0”,若温度转换完成,则输出“1RecallE2(重新调整E2)[B8h]这条命令把贮存在E2中温度触发器的值重新调至暂存存储器。这种重新调出的操作在对DS18B20上电时也自动发生,因此只要器件一上电,暂存存储器内就有了有效的数据。在这条命令发出之后,对于所发出的第一个读数据时间片,器件会输出温度转换忙的标识:“0”=忙,“1”ReadPowerSupply(读电源)[B4h]对于在此命令发送至DS18B20之后所发出的第一读数据的时间片,器件都会给出其电源方式的信号:“0”=寄生电源供电,“1(4)处理数据DS18B20的高速暂存存储器由9个字节组成,其分配如图1-5所示。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后。图1-5高速暂存存储器分配图表1-1是DS18B20温度采集转化后得到的12位数据,存储在DS18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于或等于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。温度转换计算方法举例:例如,当DS18B20采集到+125℃实际温度=07D0H╳0.0625=2021╳0.0625=1250C。例如当DS18B20采集到-55℃实际温度=370H╳0.0625=880╳0.0625=550C表1-1DS18B20温度数据表温度/0C二进制表示十六进制表示符号位(5位)数据位(11位)+125000001111101000007D0H+25.062500000001100100010191H+10.125000000001010001000A2H+0.500000000000010000008H000000000000000000000H-0.51111111111111000FFF8H-10.1251111111101011110FF5EH-25.6251111111001101111FE6FH-551111110010010000FC90H二、DS1302芯片介绍DS1302是DALLAS公司推出的涓流充电时钟芯片,内含一个实时时钟/日历和31字节静态RAM,可以通过串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、星期、月、年的信息,每个月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM标志位决定采用24或12小时时间格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需三根I/O线:复位(RST)、I/O数据线、串行时钟(SCLK)。时钟/RAM的读/写数据以一字节或多达31字节的字符组方式通信。DS1302工作时功耗很低,保持数据和时钟信息时,功耗小于1mW。1、DS1302的内部结构DS1302的外部引脚功能说明如图1-6所示。DS1302封装图X1,X232.768kHz晶振引脚GND地RST复位I/O数据输入/输出SCLK串行时钟VCC1电池引脚VCC2主电源引脚图1-6DS1302的外部引脚功能说明图

DS1302的内部结构如图1-7所示,主要组成部分为:移位寄存器、控制逻辑、振荡器、实时时钟以及RAM。虽然数据分成两种,但是对单片机的程序而言,其实是一样的,就是对特定的地址进行读写操作。图1-7DS1302的内部结构图DS1302含充电电路,可以对作为后备电源的可充电电池充电,并可选择充电使能和串入的二极管数目,以调节电池充电电压。不过对我们目前而言,最需要熟悉的是和时钟相关部分的功能,对于其它参数请参阅数据手册。2、DS1302的工作原理DS1302工作时为了对任何数据传送进行初始化,需要将复位脚(RST)置为高电平且将8位地址和命令信息装入移位寄存器。数据在时钟(SCLK)的上升沿串行输入,前8位指定访问地址,命令字装入移位寄存器后,在之后的时钟周期,读操作时输出数据,写操作时输出数据。时钟脉冲的个数在单字节方式下为8+8(8位地址+8位数据),在多字节方式下为8加最多可达248的数据。3、DS1302的寄存器和控制命令对DS1302的操作就是对其内部寄存器的操作,DS1302内部共有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器以外的寄存器。日历、时间寄存器及控制字如表1-2所示。表1-2日历、时钟寄存器与控制字对照表寄存器名称765432101RAM/CKA4A3A2A1A0RD/W秒寄存器1000000分寄存器1000001小时寄存器1000010日寄存器1000011月寄存器1000100星期寄存器1000101年寄存器1000110写保护寄存器1000111慢充电寄存器1001000时钟突发寄存器1011111最后一位RD/W为“0”时表示进行写操作,为“1”时表示读操作。DS1302内部寄存器列表如表1-3所示。表1-3DS14302内部主要寄存器分布表寄存器名称命令字取值范围各位内容写读76543210秒寄存器80H81H00-59CH10SECSEC分寄存器82H83H00-59010MINMIN小时寄存器84H85H01-12或00-2312/240AHRHR日期寄存器86H87H01-28,29,30,310010DATEDATE月份寄存器88H89H01-1200010MMONTH周寄存器8AH8BH01-0700000DAY年份寄存器8CH8DH00-9910YEARYEAR

DS1302内部的RAM分为两类,一类是单个RAM单元,共31个,每个单元为一个8位的字节,其命令控制字为COH~FDH,其中奇数为读操作,偶数为写操作;再一类为突发方式下的RAM,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。

我们现在已经知道了控制寄存器和RAM的逻辑地址,接着就需要知道如何通过外部接口来访问这些资源。单片机是通过简单的同步串行通讯与DS1302通讯的,每次通讯都必须由单片机发起,无论是读还是写操作,单片机都必须先向DS1302写入一个命令帧,这个帧的格式如表1所示,最高位BIT7固定为1,BIT6决定操作是针对RAM还是时钟寄存器,接着的5个BIT是RAM或时钟寄存器在DS1302的内部地址,最后一个BIT表示这次操作是读操作抑或是写操作。物理上,DS1302的通讯接口由3个口线组成,即RST,SCLK,I/O。其中RST从低电平变成高电平启动一次数据传输过程,SCLK是时钟线,I/O是数据线。具体的读写时序如图1-8,但是请注意,无论是哪种同步通讯类型的串行接口,都是对时钟信号敏感的,而且一般数据写入有效是在上升沿,读出有效是在下降沿(DS1302正是如此的,但是在芯片手册里没有明确说明),如果不是特别确定,则把程序设计成这样:平时SCLK保持低电平,在时钟变动前设置数据,在时钟变动后读取数据,即数据操作总是在SCLK保持为低电平的时候,相邻的操作之间间隔有一个上升沿和一个下降沿。图1-8DS1302的命令字结构第二章电路硬件设计及分析第一节时钟电路系统的时钟电路设计是采用的内部方式,即利用芯片内部的振荡电路。51单片机内部有一个用于构成振荡器的高增益反相放大器。引脚XTAL1和XTAL2分别是此放大器的输入端和输出端。这个放大器与作为反馈元件的片外晶体谐振器一起构成一个自激振荡器。外接晶体谐振器以及电容C1和C2构成并联谐振电路,接在放大器的反馈回路中。对外接电容的值虽然没有严格的要求,但电容的大小会影响震荡器频率的高低、震荡器的稳定性、起振的快速性和温度的稳定性。因此,此系统电路的晶体振荡器的值为12MHz,电容应尽可能的选择陶瓷电容,电容值约为22μF。在焊接刷电路板时,晶体振荡器和电容应尽可能安装得与单片机芯片靠近,以减少寄生电容,更好地保证震荡器稳定和可靠地工作。时钟电路如图2-1所示。图2-1时钟电路图第二节复位电路复位是由外部的复位电路来实现的。片内复位电路是复位引脚RST通常采用上电自动复位和按键手动复位两种方式,此电路系统采用的是按键手动复位电路,高电平时复位,如图所示。当时钟频率选用12MHz时,C取22μF,R约为1K。复位电路如图2-2所示图2-2复位电路图第三节DS1302时钟电路DS1302内含一个实时时钟/日历和31字节静态RAM,可以通过串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、星期、月、年的信息,每个月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM标志位决定采用24或12小时时间格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需三根I/O线:复位(RST)、I/O数据线、串行时钟(SCLK)。DS1302时钟电路如图2-3所示。图2-3DS1302时钟电路图第四节DS18B20温度计电路DS18B20它具有3引脚TO-92小体积封装形式,温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与多个DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。以上特点使DS18B20非常适用于远距离多点温度检测系统。电路图如图图2-4DS18B20温度计电路键盘电路键盘接口是单片机应用系统中最常用的接口之一,键盘的类型很多,常用的有独立式键盘和矩阵式键盘,因为本设计需要的键盘比较少,所以采用独立式键盘。在键盘的应用中,需要解决键盘消抖的问题,一般使用的是软件消抖的方法。键盘的电路图如图2-5所示。图2-5键盘电路图第六节显示电路显示器是单片机常用的功能单元之一,显示器的主要功能是为单片机系统使用者提供必要的单片机工作信息,或者提供工作状态的提示信息,显示器的工作是由单片机通过显示接口驱动的。本设计采用的是LCD1602显示电路图如图2-6所示。图2-6LCD1602显示电路图第七节按键提示电路本设计具有按键蜂鸣器响的功能,使得按键可靠工作。按键提示电路如图2-7所示。图2-7按键提示电路如图第三章软件设计第一节主函数流程图主函数流程图如图3-1所示。图3-1主函数流程图第二节DS18B20温度计程序流程图DS1820温度计程序流程图如图3-2所示。图3-2DS1820温度计程序流程图第三节按键程序流程图按键程序流程图如图3-3所示。图3-3按键程序流程图第四节定时器T0中断服务程序流程图定时器T0中断服务程序流程图如图3-4所示。图3-4定时器T0中断服务程序流程图第四章结束语带时钟显示的温度计Proteus仿真效果图如图4-1所示。图4-1带时钟显示的温度计Proteus仿真效果图附录1电路图附录2主程序清单#include<reg51.h>#include"DS18B20_3.H"#defineuintunsignedint#defineucharunsignedcharuchara,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp;#defineyh0x80//LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)#defineer0x80+0x40//LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)sbitrs=P2^0;sbiten=P2^2;sbitrw=P2^1;//如果硬件上rw接地,就不用写这句和后面的rw=0了sbitled=P2^6;//LCD背光开关sbitIO=P1^1;sbitSCLK=P1^0;sbitRST=P1^2;sbitACC0=ACC^0;sbitACC7=ACC^7;sbitkey1=P1^5;//设置键sbitkey2=P1^6;//加键sbitkey3=P1^7;//减键sbitbuzzer=P1^3;//蜂鸣器,通过三极管9012驱动,端口低电平响ucharcodetab1[]={"20--"};//年显示的固定字符ucharcodetab2[]={"::"};//时间显示的固定字符voiddelay(uintxms)//延时函数,有参函数{ uintx,y; for(x=xms;x>0;x--) for(y=110;y>0;y--);}write_1602com(ucharcom)//****液晶写入指令函数****{ rs=0;//数据/指令选择置为指令 rw=0;//读写选择置为写 P0=com;//送入数据 delay(1); en=1;//拉高使能端,为制造有效的下降沿做准备 delay(1); en=0;//en由高变低,产生下降沿,液晶执行命令}write_1602dat(uchardat)//***液晶写入数据函数****{ rs=1;//数据/指令选择置为数据 rw=0;//读写选择置为写 P0=dat;//送入数据 delay(1); en=1;//en置高电平,为制造下降沿做准备 delay(1); en=0;//en由高变低,产生下降沿,液晶执行命令}lcd_init()//***液晶初始化函数****{ write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据 write_1602com(0x0c);//开显示不显示光标 write_1602com(0x06);//整屏不移动,光标自动右移 write_1602com(0x01);//清显示 write_1602com(yh+1);//日历显示固定符号从第一行第1个位置之后开始显示 for(a=0;a<14;a++) { write_1602dat(tab1[a]);//向液晶屏写日历显示的固定符号部分 //delay(3); } write_1602com(er+2);//时间显示固定符号写入位置,从第2个位置后开始显示 for(a=0;a<8;a++) { write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号 //delay(3); }}voidwrite_byte(uchardat)//写一个字节{ ACC=dat; RST=1; for(a=8;a>0;a--) { IO=ACC0; SCLK=0; SCLK=1; ACC=ACC>>1; }}ucharread_byte()//读一个字节{ RST=1; for(a=8;a>0;a--) { ACC7=IO; SCLK=1; SCLK=0; ACC=ACC>>1;} return(ACC);}voidwrite_1302(ucharadd,uchardat)//向1302芯片写函数,指定写入地址,数据{RST=0; SCLK=0; RST=1; write_byte(add); write_byte(dat); SCLK=1; RST=0;}ucharread_1302(ucharadd)//从1302读数据函数,指定读取数据来源地址{ uchartemp; RST=0; SCLK=0; RST=1; write_byte(add); temp=read_byte(); SCLK=1; RST=0; return(temp);}ucharBCD_Decimal(ucharbcd)//BCD码转十进制函数,输入BCD,返回十进制{ucharDecimal;Decimal=bcd>>4;return(Decimal=Decimal*10+(bcd&=0x0F));}voidds1302_init()//1302芯片初始化子函数(2021-01-07,12:00:00,week4){RST=0;SCLK=0;write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x8e,0x80);//打开写保护}voidwrite_temp(ucharadd,uchardat)//向LCD写温度数据,并指定显示位置{ uchargw,sw; gw=dat%10;//取得个位数字 sw=dat/10;//取得十位数字 write_1602com(er+add);//er是头文件规定的值0x80+0x40 write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码write_1602dat(0xdf);//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码 write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码 }voidwrite_sfm(ucharadd,uchardat)//向LCD写时分秒,有显示位置加、现示数据,两个参数{ uchargw,sw; gw=dat%10;//取得个位数字 sw=dat/10;//取得十位数字 write_1602com(er+add);//er是头文件规定的值0x80+0x40 write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码 }voidwrite_nyr(ucharadd,uchardat)//向LCD写年月日,有显示位置加数、显示数据,两个参数{ uchargw,sw; gw=dat%10;//取得个位数字 sw=dat/10;//取得十位数字 write_1602com(yh+add);//设定显示位置为第一个位置+add write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码 }voidwrite_week(ucharweek)//写星期函数{ write_1602com(yh+0x0c);//星期字符的显示位置 switch(week) { case1:write_1602dat('M');//星期数为1时,显示 write_1602dat('O'); write_1602dat('N'); break; case2:write_1602dat('T');//星期数据为2时显示 write_1602dat('U'); write_1602dat('E'); break; case3:write_1602dat('W');//星期数据为3时显示 write_1602dat('E'); write_1602dat('D'); break; case4:write_1602dat('T');//星期数据为4是显示 write_1602dat('H'); write_1602dat('U'); break; case5:write_1602dat('F');//星期数据为5时显示 write_1602dat('R'); write_1602dat('I'); break; case6:write_1602dat('S');//星期数据为6时显示 write_1602dat('T'); write_1602dat('A'); break; case7:write_1602dat('S');//星期数据为7时显示 write_1602dat('U'); write_1602dat('N'); break;}}//****************键盘扫描有关函数**********************voidkeyscan(){ if(key1==0)//key1为功能键(设置键) { delay(9);//延时,用于消抖动 if(key1==0)//延时后再次确认按键按下 {buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1; while(!key1); key1n++; if(key1n==9) key1n=1;//设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环 switch(key1n) { case1:TR0=0;//关闭定时器 //TR1=0; write_1602com(er+0x09);//设置按键按动一次,秒位置显示光标 write_1602com(0x0f);//设置光标为闪烁 temp=(miao)/10*16+(miao)%10;//秒数据写入DS1302 write_1302(0x8e,0x00); write_1302(0x80,0x80|temp);//miao write_1302(0x8e,0x80); break; case2:write_1602com(er+6);//按2次fen位置显示光标 //write_1602com(0x0f); break; case3:write_1602com(er+3);//按动3次,shi //write_1602com(0x0f); break; case4:write_1602com(yh+0x0e);//按动4次,week //write_1602com(0x0f); break; case5:write_1602com(yh+0x0a);//按动5次,ri //write_1602com(0x0f); break; case6:write_1602com(yh+0x07);//按动6次,yue //write_1602com(0x0f); break; case7:write_1602com(yh+0x04);//按动7次,nian //write_1602com(0x0f); break; case8: write_1602com(0x0c);//按动到第8次,设置光标不闪烁 TR0=1;//打开定时器temp=(miao)/10*16+(miao)%10; write_1302(0x8e,0x00); write_1302(0x80,0x00|temp);//miao数据写入DS1302 write_1302(0x8e,0x80);break; } }} if(key1n!=0)//当key1按下以下。再按以下键才有效(按键次数不等于零) {if(key2==0)//上调键 { delay(10); if(key2==0) {buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1; while(!key2); switch(key1n) { case1:miao++;//设置键按动1次,调秒 if(miao==60) miao=0;//秒超过59,再加1,就归零 write_sfm(0x08,miao);//令LCD在正确位置显示"加"设定好的秒数 temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x80,temp);//向DS1302内写秒寄存器80H写入调整后的秒数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回 //write_1602com(0x0b); break; case2:fen++; if(fen==60) fen=0; write_sfm(0x05,fen);//令LCD在正确位置显示"加"设定好的分数据 temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 break; case3:shi++; if(shi==24) shi=0; write_sfm(2,shi);//令LCD在正确的位置显示"加"设定好的小时数据 temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x84,temp);//DS1302内写小时寄存器84H写入调整后的小时数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+3);//设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case4:week++; if(week==8) week=1;write_1602com(yh+0x0C);//指定'加'后的周数据显示位置 write_week(week);//指定周数据显示内容temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case5:ri++; if(ri==32) ri=1; write_nyr(9,ri);//令LCD在正确的位置显示"加"设定好的日期数据 temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case6:yue++; if(yue==13) yue=1; write_nyr(6,yue);//令LCD在正确的位置显示"加"设定好的月份数据 temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case7:nian++; if(nian==100) nian=0; write_nyr(3,nian);//令LCD在正确的位置显示"加"设定好的年份数据temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; }}} if(key3==0) { delay(10);//调延时,消抖动 if(key3==0) {buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1; while(!key3); switch(key1n) { case1:miao--; if(miao==-1) miao=59;//秒数据减到-1时自动变成59 write_sfm(0x08,miao);//在LCD的正确位置显示改变后新的秒数temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x80,temp);//向DS1302内写秒寄存器80H写入调整后的秒数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 //write_1602com(0x0b); break; case2:fen--; if(fen==-1) fen=59; write_sfm(5,fen); temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 break;case3:shi--; if(shi==-1) shi=23; write_sfm(2,shi); temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case4:week--; if(week==0) week=7; write_1602com(yh+0x0C);//指定'加'后的周数据显示位置 write_week(week);//指定周数据显示内容 temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case5:ri--; if(ri==0) ri=31; write_nyr(9,ri); temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case6:yue--; if(yue==0) yue=12; write_nyr(6,yue); temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; case7:nian--; if(nian==-1) nian=99; write_nyr(3,nian);temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码 write_1302(0x8e,0x80);//打开写保护 write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break; }}}}voidinit()//定时器、计数器设置函数{ TMOD=0x11;//指定定时/计数器的工作方式为3 TH0=0;//定时器T0的高四位=0 TL0=0;//定时器T0的低四位=0 EA=1;//系统允许有开放的中断 ET0=1;//允许T0中断 TR0=1;//开启中断,启动定时器}voidmain(){ lcd_init();//调用液晶屏初始化子函数 ds1302_init();//调用DS1302时钟的初始化子函数 init();//调用定时计数器的设置子函数 led=0;//打开LCD的背光电源buzzer=0;//蜂鸣器长响一次delay(80);buzzer=1; while(1)//无限循环下面的语句: { keyscan();//调用键盘扫描子函数 }}voidtimer0()interrupt1//取得并显示日历和时间{ miao=BCD_Decimal(read_1302(0x81)); fen=BCD_Decimal(read_1302(0x83)); shi=BCD_Decimal(read_1302(0x85)); ri=BCD_Decimal(read_1302(0x87)); yue=BCD_Decimal(read_1302(0x89)); nian=BCD_Decimal(read_1302(0x8d)); week=BCD_Decimal(read_1302(0x8b)); //显示温度、秒、时、分数据:write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数) write_sfm(5,fen);//分,从第二行第5个字符后开始显示 write_sfm(2,shi);//小时,从第二行第2个字符后开始显示 //显示日、月、年数据: write_nyr(9,ri);//日期,从第二行第9个字符后开始显示write_nyr(6,yue);//月份,从第二行第6个字符后开始显示 write_nyr(3,nian);//年,从第二行第3个字符后开始显示 write_week(week);}参考文献[1]万光毅.严义.单片机实验与实践教程(一)[M],北京航空航天大学出版社;[2]夏继强.沈德金.单片机实验与实践教程(二)[M],北京航空航天大学出版社;[3]李广弟.朱月秀.王秀山.单片机基础(修订本)[M],北京航空航天大学出版社;[4]徐爱钧.彭秀华.单片机高级语言C51应用程序设计[M],2021年版;[5]马家辰.MCS-51单片机原理及其接口技术[M],哈尔滨工业大学出版社,2021年版;[6]瓮嘉民.单片机应用开发技术—基于PROTEUS仿真和C语言编程[M],中国电力出版社,2021年版;[7]李强.51系列单片机应用软件编程技术[M],北京航空航天大学出版社,2021年版。致谢在本次论文设计过程中,瓮嘉民老师对该论文从选题,构思到最后定稿的各个环节给予细心指引与教导,使我得以最终完成毕业论文设计。在学习中,老师严谨的治学态度、丰富渊博的知识、敏锐的学术思维、精益求精的工作态度以及侮人不倦的师者风范是我终生学习的楷模,老师们的高深精湛的造诣与严谨求实的治学精神,将永远激励着我。这三年中还得到众多老师的关心支持和帮助。在此,谨向老师们致以衷心的感谢和崇高的敬意!最后,我要向百忙之中抽时间对本文进行审阅,评议和参与本人论文答辩的各位老师表示感谢。ganemploymenttribunalclaimEmploymenttribunalssortoutdisagreementsbetweenemployersandemployees.Youmayneedtomakeaclaimtoanemploymenttribunalif:youdon'tagreewiththedisciplinaryactionyouremployerhastakenagainstyouyouremployerdismissesyouandyouthinkthatyouhavebeendismissedunfairly.Formoreinformationaboutdismissalandunfairdismissal,see

Dismissal.Youcanmakeaclaimtoanemploymenttribunal,evenifyouhaven't

appealed

againstthedisciplinaryactionyouremployerhastakenagainstyou.However,ifyouwinyourcase,thetribunalmayreduceanycompensationawardedtoyouasaresultofyourfailuretoappeal.Rememberthatinmostcasesyoumustmakeanapplicationtoanemploymenttribunalwithinthreemonthsofthedatewhentheeventyouarecomplainingabouthappened.Ifyourapplicationisreceivedafterthistimelimit,thetribunalwillnotusuallyacceptit.Ifyouareworriedabouthowthetimelimitsapplytoyou,takeadvicefromoneoftheorganisationslistedunder

Furtherhelp.Em

社会实践报告系别:班级:学号:姓名:作为祖国未来的事业的继承人,我们这些大学生应该及早树立自己的历史责任感,提高自己的社会适应能力。假期的社会实践就是很好的锻炼自己的机会。当下,挣钱早已不是打工的唯一目的,更多的人将其视为参加社会实践、提高自身能力的机会。许多学校也积极鼓励大学生多接触社会、了解社会,一方面可以把学到的理论知识应用到实践中去,提高各方面的能力;另一方面可以积累工作经验对日后的就业大有裨益。进行社会实践,最理想的就是找到与本专业对口单位进行实习,从而提高自己的实战水平,同时可以将课本知识在实践中得到运用,从而更好的指导自己今后的学习。但是作为一名尚未毕业的大学生,由于本身具备的专业知识还十分的有限,所以我选择了打散工作为第一次社会实践的方式。目的在于熟悉社会。就职业本身而言,并无高低贵贱之分,存在即为合理。通过短短几天的打工经历可以让长期处于校园的我们对社会有一种更直观的认识。实践过程:自从走进了大学,就业问题就似乎总是围绕在我们的身边,成了说不完的话题。在现今社会,招聘会上的大字报都总写着“有经验者优先”,可还在校园里面的我们这班学子社会经验又会拥有多少呢?为了拓展自身的知识面,扩大与社会的接触面,增加个人在社会竞争中的经验,锻炼和提高自己的能力,以便在以后毕业后能真正真正走入社会,能够适应国内外的经济形势的变化,并且能够在生活和工作中很好地处理各方面的问题,我开始了

温馨提示

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

最新文档

评论

0/150

提交评论