基于单片机控制实时时钟HT1380的软件设计.doc_第1页
基于单片机控制实时时钟HT1380的软件设计.doc_第2页
基于单片机控制实时时钟HT1380的软件设计.doc_第3页
基于单片机控制实时时钟HT1380的软件设计.doc_第4页
基于单片机控制实时时钟HT1380的软件设计.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

基于单片机控制的实时时钟HT1380的软件设计院 (系): 机电及自动化学院 专 业 : 测控技术与仪器(信息) 目 录摘 要11系统的硬件设计框图与原理概述.21.1 电路设计框图21.2 系统硬件概述21.3 电路原理及说明22 系统的软件设计42.1 程序流程框图43 测试与结果分析63.1 软件测试63.2 测试结果分析63.3 测试结论64 课设总结75致 谢.86 参考文献9附录一:系统程序清单10附录二:系统硬件图.20附录三:硬件实物图21摘 要随着科技的快速发展,时间的流逝,至从观太阳、摆钟到现在电子钟,人类不断研究,不断创新纪录。实时时钟电路HT1380,它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且HT1380的使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒等信息,还具有时间校准等功能。该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用35V电压供电。综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。关键词:时钟电路,HT1380,单片机89S52 1.系统的硬件设计框图与原理概述1.1 电路设计框图LCD液晶显示屏显示模块AT89S52主控制模 块键盘模块 HT1380时钟模块图1系统原理图1.2 系统硬件概述本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由HT1380提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。HT1380内部有一个31*8的用于临时性存放数据的RAM寄存器。可产生年、月、日、周日、时、分、秒,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能;显示部份由LCD液晶显示屏显示。 1.3 电路原理及说明(1) 时钟芯片HT1380的工作原理: HT1380在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图4所示。HT1380的控制字的位7必须置1,若为0则不能把对HT1380进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0,位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。表.2为HT1380的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,HT1380处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。(2) HT1380的控制字节:HT1380控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入HT1380中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出 (3) 数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入HT1380,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出HT1380的数据,读出数据时从低位0位到高位7。(4) HT1380的寄存器HT1380有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。此外,HT1380 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 HT1380与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0HFDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。 2.系统的软件设计主程序2.1 程序流程框图定时器、液晶、时钟芯片初始化While(1)是定时50ms到了吗?否液晶显示扫描刷新按键扫描 是调整按键是否按下?(set_num是否为0)否 关闭时钟芯片计时功能,进入调整模式 读取时间芯片内的时间并显示 图二 主程序流程图调整模式程序读取调整按键按下次数set_num,根据其数值确定调整时间的位数set_num=7set_num=6set_num=5set_num=1set_num=2set_num=4set_num=3调整秒数调整分数调整小时数调整月数调整天数调整年数调整星期数返回正常工作模式(set_num清零)调整秒数子程序递减按键是否按下秒数位显示闪烁 否读取秒数到寄存器是秒数减1递增按键是否按下是时间数据写入时钟芯片并显示否秒数加1返回图三 调试模式主程序及调整秒数子程序框图(注:由于调整秒、分、时、星期、日、月、年的程序基本相同,在此只给出调整秒的子程序框图。)3 测试与结果分析3.1 软件测试电子成年历是多功能的数字型,可以看当前日期,时间。电子成年历功能很多,所以对于它的编程也较为复杂,所以在编写程序和调试时出现了相对较多的问题。最后经过多次的模块子程序的修改,一步一步的完成,最终解决了软件。3.2 测试结果分析 在测试中遇到LCD液晶显示屏为不显示时,首先使用试测仪对电路进行测试,观察是否存在漏焊,虚焊,或者元件损坏,滑动变阻器器没有调好:查看烧写的程序是否正确无误,对程序进行认真修改。测试效果见附录三调试硬件图。3.3 测试结论经过多次的反复测试与分析,可以对电路的原理及功能更加熟悉,同时提高了设计能力与及对电路的分析能力。同时在软件的编程方面得到更到的提高,对编程能力得到加强,同时对所学的知识得到很大的提高与巩固。4 课程总结在整个设计过程中,充分发挥人的主观能动性,自主学习,学到了许多以前没学到的知识,较好的完成了作品,达到了预期的目的,完了最初的设想。在电路焊接时虽然没什么大问题,但从中也知道了焊接在整个作品中的重要性,电路工程量大,不能心急,一个个慢慢来不能急于求成。反而达到事半功倍的效果。对电路的设计、布局要先有一个好的构思,才显得电路板美观、大方。程序编写中,由于思路不清晰,开始时遇到了很多的问题,经过静下心来思考,理清了思路,成功解决了这些难题。在此次设计中,知道了做凡事要有一颗平常的心,不要想着走捷径,一步一脚印。也练就了我们的耐心,做什么事都要有耐心。此次设计中学到了很多很多东西,这是最重要的。总之,此次课程设计使我的能力得到了全方位的提高。5致 谢在做课程设计的日子里得到了老师的指导,在此致以诚挚的谢意。感谢提供相关技术帮助的老师和同学,你们的支持和鼓励使我们对这次的作品完成有了信心和动力,也给了我们很多无私的帮助和支持,是你们的帮助让我们实现了最终硬件的成功,我们在此深表谢意!6参考文献1 刘 勇 编 数字电路 电子工业出版社 20042 陈正振 编 电子电路设计与制作 广西交通职业技术学院信息工程系 20073 杨子文 编 单片机原理及应用 西安电子科技大学出版社 20064 王法能 编 单片机原理及应用 科学出版社 20045 杨光友 编 单片机接口技术 中国水利水电出版社 2007 附录一:系统程序清单1. 程序列表图main.c#include #include Typedef.H#include HT1380.H#include Keypad.h#include key.h#include main.h#include disp.hsbit P20=P20;sbit P21=P21;sbit P22=P22; void delay0(INT8U z) / 延时 staticINT8U i; staticINT8U j; for(i=z;i0;i-) for(j=200;j0;j+);void main() Initial_HT1380();DispInit();DispCls();while(1) DispRef(); delay0(1000); if(set_num=0)/仅在正常模式下执行读取时间命令 HT1380_GetTime(); /获取时钟芯片的时钟数据到自定义的结构型数组 delay0(1000); KEY_num();/键盘扫描及处理命令 HT1380.c#include #include Typedef.H#include HT1380.H#include Disp.h#include key.hunsigned char ReadValue,Year,Month,Day,Hour,Minute,Second,Week;/存放时间数据的寄存器sbit HT1380_CLK = P23; /实时时钟时钟线引脚 sbit HT1380_IO = P24; /实时时钟数据线引脚 sbit HT1380_RST = P25; /实时时钟复位线引脚sbit ACC0 = ACC0; /定义累加器的位sbit ACC7 = ACC7;void HT1380InputByte(unsigned char d) /实时时钟写入一字节(内部函数) unsigned char i; ACC = d; for(i=8; i0; i-) HT1380_IO = ACC0; /相当于汇编中的 RRC HT1380_CLK = 1; HT1380_CLK = 0; ACC = ACC 1; unsigned char HT1380OutputByte(void) /实时时钟读取一字节(内部函数) unsigned char i; for(i=8; i0; i-) ACC = ACC 1; /相当于汇编中的 RRC ACC7 = HT1380_IO; HT1380_CLK = 1; HT1380_CLK = 0; return(ACC); void Write1380(unsigned char ucAddr, unsigned char ucDa)/ucAddr: HT1380地址, ucData: 要写的数据 HT1380_RST = 0; HT1380_CLK = 0; HT1380_RST = 1; HT1380InputByte(ucAddr); / 地址,命令 HT1380InputByte(ucDa); / 写1Byte数据 HT1380_CLK = 1; HT1380_RST = 0; unsigned char Read1380(unsigned char ucAddr)/读取HT1380某地址的数据 unsigned char ucData; HT1380_RST = 0; HT1380_CLK = 0; HT1380_RST = 1; HT1380InputByte(ucAddr|0x01); / 地址,命令 ucData = HT1380OutputByte(); / 读1Byte数据 HT1380_CLK = 1; HT1380_RST = 0; return(ucData);void HT1380_GetTime() /获取时钟芯片的时钟数据到自定义的结构型数组 ReadValue = Read1380(HT1380_YEAR); Year= (ReadValue&0xf0)4)*10 + (ReadValue&0x0F);DispInt(20,0,0,2);DispInt_blink(Year,0,2,2,0);DispChr(-,0,4,0); ReadValue = Read1380(HT1380_MONTH); Month = (ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Month,0,5,2,0); DispChr(-,0,7,0); ReadValue = Read1380(HT1380_DAY);Day = (ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Day,0,8,2,0);ReadValue = Read1380(HT1380_HOUR);Hour = (ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Hour,1,1,2,0); DispChr(:,1,3,0); ReadValue=Read1380(HT1380_MINUTE); Minute=(ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Minute,1,4,2,0); DispChr(:,1,6,0); ReadValue=Read1380(HT1380_SECOND);ReadValue=ReadValue&0x7f; Second=(ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Second,1,7,2,0); ReadValue = Read1380(HT1380_WEEK); Week = /*(ReadValue&0xf0)4)*10 + */(ReadValue&0x0F);/DispInt_blink(Week,0,17,1,0);disp_week();/DispStr(WEEK,0,13,0);DispStr(ZHU-ZHANG,1,11,0); /显示作者姓 void Initial_HT1380(void) /时钟芯片初始化 unsigned char Second=Read1380(HT1380_SECOND);if(Second&0x80) /判断时钟芯片是否关闭 Write1380(0x8e,0x00); /写入允许Write1380(0x8c,0x08); /以下写入初始化时间 日期:08/12/09.星期: 3. 时间: 23:59:55Write1380(0x88,0x12);Write1380(0x86,0x18);Write1380(0x8a,0x04);Write1380(0x84,0x14);Write1380(0x82,0x30);Write1380(0x80,0x00);Write1380(0x8e,0x80); /禁止写入Ht1380.h#ifndef _HT1380_H_#define _HT1380_H_#define AM(X)X#define PM(X)(X+12) / 转成24小时制#define HT1380_SECOND0x80 /时钟芯片的寄存器位置,存放时间#define HT1380_MINUTE0x82#define HT1380_MINUTE10x83#define HT1380_HOUR0x84 #define HT1380_WEEK0x8A#define HT1380_DAY0x86#define HT1380_MONTH0x88#define HT1380_MONTH10x89#define HT1380_YEAR0x8C void HT1380InputByte(unsigned char d);/实时时钟写入一字节(内部函数)unsigned char HT1380OutputByte(void); /实时时钟读取一字节(内部函数)void Write1380(unsigned char ucAddr, unsigned char ucDa);/ucAddr: HT1380地址, ucData: 要写的数据unsigned char Read1380(unsigned char ucAddr);/读取HT1380某地址的数据void HT1380_GetTime(); /获取时钟芯片的时钟数据到自定义的结构型数组void Initial_HT1380(void); /时钟芯片初始化extern unsigned char ReadValue,Year,Month,Day,Hour,Minute,Second,Week;/存放时间数据的寄存器#endifKey.c#include#include#include Typedef.H#include key.h#include main.h#include ht1380.h#include disp.Hsbit P36=P36;int set_num=0,up_num=0,down_num=0,out_num=0;unsigned char b16=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e;unsigned char K=0,Key,fl,ac=0,n;void delay(unsigned char pp) /延迟时间等于k*8ms while(pp-) unsigned char j;for(j = 0;j123;j+);/j进行的内部循环,1次延迟8us,延迟1ms unsigned char Keyscan(void) /按键扫描程序 P1.0-P1.3为行线 P1.4-P1.7为列线 unsigned char rcode, ccode; P1 = 0xF0; / 发全0行扫描码,列线输入 if(P1&0xF0) != 0xF0) / 若有键按下 delay(1);/ 延时去抖动 if(P1&0xF0) != 0xF0) rcode = 0xFE; / 逐行扫描初值 while(rcode&0x10) != 0) P1 = rcode; / 输出行扫描码 if(P1&0xF0) != 0xF0) / 本行有键按下 ccode = (P1&0xF0)|0x0F; /do; while(P1&0xF0) != 0xF0) /等待键释放 P36=0; P36=1; return (rcode) + (ccode); / 返回键编码 else rcode = (rcode0|down_num0) Second=Read1380(HT1380_SECOND) ; if(up_num0) Second=Second+up_num; if(Second&0x0f)0x09) Second=(Second&0xf0)+0x10;/BCD转化成十进制 if(Second&0x70)4)*10 + (Second&0x0F)59) /60秒时清零 Second=0x00; if(down_num0) if(Second=0x80)/由于Second的最高位为1决定了时钟芯片停止工作,所以不是0x00,而是0x80;对应10000000; Second=0x60;if(Second&0x0f)=0x00) Second=Second-0x10+0x09;else Second=Second-down_num; /秒数减1 up_num=0; down_num=0; if(Second=0x39)/当秒加到59秒时归0 Second=0x00; Write1380(0x8e,0x00); /写入允许 Write1380(HT1380_SECOND,Second|0x80); Write1380(0x8e,0x80); /禁止写入 ReadValue=Read1380(HT1380_SECOND); ReadValue=ReadValue&0x7f; Second=(ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Second,1,7,2,TRUE); break;case 2: if(up_num0|down_num0) Minute=Read1380(HT1380_MINUTE1); if(up_num0) Minute=Minute+up_num; /秒数加1 if(Minute&0x0f)0x09) Minute=(Minute&0xf0)+0x10; if(Minute&0xf0)4)*10 + (Minute&0x0F)=60) Minute=0x00; if(down_num0) if(Minute=0x00) Minute=0x60;if(Minute&0x0f)=0x00) Minute=Minute-0x10+0x09;else Minute=Minute-down_num; up_num=0;down_num=0; /加减按键清零Write1380(0x8e,0x00); /写入允许 Write1380(HT1380_MINUTE,Minute); Write1380(0x8e,0x80); /禁止写入 Minute=(Minute&0xf0)4)*10 + (Minute&0x0F); /BCD转化成十进制数值 DispInt_blink(Minute,1,4,2,TRUE); /打开分钟位闪烁 ReadValue=Read1380(HT1380_SECOND); ReadValue=ReadValue&0x7f; Second=(ReadValue&0xf0)4)*10 + (ReadValue&0x0F); DispInt_blink(Second,1,7,2,0); /关闭秒位闪烁 break;case 3:if(up_num0|down_num0) Hour = Read1380(HT1380_HOUR);/读取芯片时间(小时) if(up_num0) Hour=Hour+up_num; if(Hour&0x0f)0x09) Hour=(Hour&0xf0)+0x10; if(Hour&0xf0)4)*10 + (Hour&0x0F)=24) Hour=0x00; if(down_num0) if(Hour=0x00) Hour=0x24;if(Hour&0x0f)=0x00) Hour=Hour-0x10+0x09;else Hour=Hour-down_num; down_num=0; up_num=0;Write1380(0x8e,0x00); /写入允许 Write1380(HT1380_HOUR,Hour); Write1380(0x8e,0x80); /禁止写入 Hour = (Hour&0xf0)4)*10 + (Hour&0x0F); DispInt_blink(Hour,1,1,2,TRUE); /打开小时位闪烁 DispInt_blink(Minute,1,4,2,0); /关闭小时位闪烁 break;case 4:if(up_num0|down_num0) Week=Read1380(HT1380_WEEK);/读取星期数if(up_num0) Week=Week+up_num; if(Week&0x0f)0x09) Week=(Hour&0xf0)+0x10; if(Week&0xf0)4)*10 + (Week&0x0F)=8) Week=0x01; if(down_num0) Week=Week-down_num; if(Week=0x00) Week=0x07; up_num=0; down_num=0;Write1380(0x8e,0x00); /写入允许 Write1380(HT1380_WEEK,Week); Write1380(0x8e,0x80); /禁止写入Week = (Week&0xf0)4)*10 + (Week&0x0F); / DispInt_blink(Week,0,17,1,TRUE); /打开星期位闪烁 disp_week(); DispInt_blink(Hour,1,1,2,0); /关闭小时位闪烁 break;case 5:if(up_num0|down_num0) Day= Read1380(HT1380_DAY);/读天数 if(up_num0) /加有效 Day=Day+up_num; if(Day&0x0f)0x09) Day=(Day&0xf0)+0x10; if(Day&0xf0)4)*10 + (Day&0x0F)=32) Day=0x01; if(down_num0) /减有效 if(Day=0x01)Day=0x32;if(Day&0x0f)=0x00)Day=Day-0x10+0x09;else Day=Day-down_num; up_num=0; down_num=0;Write1380(0x8e,0x00); /写入允许 Write1380(HT1380_DAY,Day); Write1380(HT1380_WEEK,Week); Write1380(0x8e,0x80); /禁止写入 Day = (Day&0xf0)4)*10 + (Day&0x0F); / DispInt_blink(Week,0,17,1,0); /关闭星期闪烁 disp_week(); DispInt_blink(Day,0,8,2,TRUE); /打开天数位闪烁 break;case 6:if(up_num0|down_num0) Month=Read1380(HT1380_MONTH);/读月数 if(up_num0) Month=Month+up_num; if(Month&0x0f)0x09) Month=(Month&0xf0

温馨提示

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

最新文档

评论

0/150

提交评论