收藏 分销(赏)

片单机课程设计led数码管显示电子钟设计.doc

上传人:丰**** 文档编号:4879247 上传时间:2024-10-17 格式:DOC 页数:25 大小:155KB 下载积分:10 金币
下载 相关 举报
片单机课程设计led数码管显示电子钟设计.doc_第1页
第1页 / 共25页
片单机课程设计led数码管显示电子钟设计.doc_第2页
第2页 / 共25页


点击查看更多>>
资源描述
《单片机原理及应用》 课程设计说明书 题目 LED数码管显示电子钟设计 系(部) 专业(班级) 姓名 学号 指导教师 起止日期 课程设计任务书 系(部): 专业: 课题名称 LED数码管显示电子钟设计 设计要求 1、课题内容:设计一种基于 AT89S52 单片机的数码管显示电子时钟,要 求如下: (1)、能正确显示时间,时钟由八位数码管显示,显示格式为:XX小时--XX分--XX秒。 (2)、时间能够由按键调整,误差小于1S。 (3)、 闹钟功能: 时间运行到与闹钟设定时间时, 闹钟响 (持续响3秒) (4)、报时功能:时间运行到正点时间时,闹钟响,几点钟就响几声(每 声持续响2秒,每两声之间时间间隔1秒)。 (5)、通过按键切换,可以显示当前日期,显示格式为:XX 年¾XX 月 ¾XX日,5秒钟后自动返回时间显示模式。 2、要求: 完成该系统的硬件和软件的设计,在 Proteus 软件上仿真通过,并提 交一篇课程设计说明书。 设计工作量 1、汇编或C51语言程序设计; 2、程序调试; 3、在Proteus上进行仿真成功; 4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序 分析、仿真分析、调试过程,参考文献、设计总结等。 工作计划 起止日期 工作内容 第一天 课题介绍,答疑,收集材料,C51介绍 第二天 设计方案论证,练习编写C51程序 第三天~第六天 程序设计 第六天~第八天 程序调试、仿真 第九天~第十天 系统测试并编写设计说明书 教研室 意见 年 月 日 系(部)主 管领导意见 年 月 日 目录 目录 4 一、 摘要 5 二、 设计内容 5 2.1、任务要求 5 2.2、设计程序方案 5 2.3 设计电路仿真图 6 三、 心得体会 9 四、 参考文献 10 一、 摘要 单片机全称为单片机微型计算机(Single Chip Microsoftcomputer)。从应用领域来看,单片机主要用来控制,所以又称为微控制器(Microcontroller Unit)或嵌入式控制器。单片机是将计算机的基本部件微型化并集成在一块芯片上的微型计算机。 单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。单片机体积小、重量轻、抗干扰能力强、环境要求不高、价格低廉、可靠性高、灵活性好、开发较为容易。由于具有上述优点,在我国,单片机已广泛地应用在工业自动化控制、自动检测、智能仪器仪表、家用电器、电力电子、机电一体化设备等各个方面,而51单片机是各单片机中最为典型和最有代表性的一种。 时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。在一个单片机应用系统中,时钟有两方面的含义:一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间,它通常有两种实现方法:一是用软件实现,即用单片机内部的可编程定时/计数器来实现,但误差很大,主要用在对时间精度要求不高的场合;二是用专门的时钟芯片实现,在对时间精度要求很高的情况下,通常采用这种方法,典型的时钟芯片有:DS1302,DS12887,X1203等都可以满足高精度的要求。 二、 设计内容 2.1、任务要求 本次设计时钟电路,使用了ATC89C51单片机芯片控制电路,单片机控制电路简单且省去了很多复杂的线路,使得电路简明易懂,使用键盘键上的按键来调整时钟的年、月、日、时、分、秒,还有设定闹钟,用一扬声器来进行定时提醒,同时使用汇编语言程序来控制整个时钟显示,使得编程变得更容易,这样通过四个模块:键盘、芯片、扬声器、LED显示即可满足设计要求。 2.2、设计程序方案 设计程序思路: 1.实现8位数码管动态扫描显示 void Display_1Code(unsigned char pos,unsigned char code1); void Display_2Num(unsigned char pos,unsigned char num,unsigned char point); 数码管动态扫描就是: 段显 位选 延时显示 消影 因为我们用的是共阳数码管,而段码表用的共阴的,所以对code1取反 共阳数码管高电平点亮,所以P2移位后不用取反,从高位开始是第1个数码管 掩饰显示1ms,P2给全0全部熄灭,消影作用。 2.时间显示 采用实时时钟芯片DS1302,读芯片的datasheet,根据时序等说明编写驱动程序。 1)初始化 void DS1302_Init(void) 2)底层基本读写函数 void DS1302_WriteByte(unsigned char byte) unsigned char DS1302_ReadByte(void) 3)对芯片寄存器的读写函数 void DS1302_WriteData(unsigned char addr,unsigned char mdata) unsigned char DS1302_ReadData(unsigned char addr) 4)修改时间函数 void DS1302_RWriteData(unsigned char addr,unsigned char mdata) 这些函数的实现就看dagasheet了,主要是时序 a.时钟上升沿写入数据 b.时钟下降沿读出数据 c.秒寄存器最高位为1关闭时钟,为0则开启时钟 5)显示时间和日期 void Display_Time(void) 显示时分秒,0x40为显示横,如12-30-00 void Display_Date(void) 显示日期,如20131230,中间没有横杆,但是在年月日上有小数点,通过 Display_2Num最后一个参数控制 void Display(void)根据dis_mode变量选择当前显示的是时间还是日期还是闹钟。 GetDateTime读取时间并与闹钟时间做比较,检测是否到达闹钟时间。 6)扫描方式 动态扫描,定时器0控制扫描周期,10ms扫描一次 void Timer0_OVF(void) interrupt 1 { TH0 = (65536-10000)/256; TL0 = (65536-10000)%256; } 3. 按键调时 void KeyScanf(void) flag_alarm_mode是闹铃模式则按键退出闹铃并返回,一键关闭闹钟 然后对setting_item变量自加,依次表示设置秒、分、时、天、月等等,设置项对应的小数点位点亮。 加键一样的过程,根据setting_item的值加不同的量:秒、分、时。 记住改变时间后要修改DS1302芯片的寄存器才能真正修改时间。 2.3 设计电路仿真图 数码管显示模块: 图1 数码管显示模块 数码管是一种把多个LED显示段集成在一起的显示设备。有两种类型,一种是共阳型,一种是共阴型。共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。共阴型就是把多个LED显示段的阴极接在一起,即为公共商。阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便如设计的,分别为A、B、C、D、E、F、G、DP,其中DP 是小数点位段。系统采用动态显示方式,用P0口来控制LED数码管的段控线,而用P2口来控制其位控线。动态显示通常都是采用动态扫描的方法进行显示,即循环点亮每一个数码管,这样虽然在任何时刻都只有一位数码管被点亮,但由于人眼存在视觉残留效应,只要每位数码管间隔时间足够短,就可以给人以同时显示的感觉。 本设计采用共阳极数码管。 晶振电路模块: 在AT89S51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。而在芯片内部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器。时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。 图2 晶振电路 按键模块: 时间计数电路由秒个位和秒十位计数器、分个位和分十位计数器、时个位和时十位计数器及星期计数器电路构成,其中秒个位和秒十位计数器、分个位和分十位计数器为60进制计数器,时个位和时十位计数器为24进制计数器。 图3 按键模块 时钟芯片电路: X1 X2 : 32.768晶振管脚 GND :地 RST : 复位脚 I/O : 数据输入/输出引脚 SCLK : 串行时钟 VCC1,VCC2 :电源供电管脚 图4 时钟芯片电路 电路总体设计仿真图: 图5 总体仿真图 按菜单/显示时间键会出现一个小光标点,再按菜单/显示时间键,光标点会左移,按加速或者减速键会加减数值。继续按菜单/显示时间键跳到显示日期、闹钟时,也可以用加速或者减速键调整时间。按减速/显示闹钟键会显示闹钟。按加速/显示日期键会显示日期。5s后会自动恢复到显示时间。操作方便简洁。 图6 日期显示 图7 闹钟显示 三、 心得体会 单片机作为我们主要的专业课程之一,我觉得单片机课程设计很有必要,而且很有意义。在这次课程设计中,运用到了很多以前的专业知识,虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的一大收获。站在库的位置上想问题。另外,要做好一个课程设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常的,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。虽然有些程序不是那么清楚理解,自己好好查阅资料,不懂还可以请教老师、同学。当我有什么不明白的地方去向其他同学请教时,即使他们正在忙于思考,也会停下来帮助我.当我有什么想法告诉他们的时候,他们不会因为我得无知而不耐心听我讲,反而会指出我的不足,一起提高。学到了共同探讨、共同前进的精神,也让我明白谦虚好学的真谛设计过程,常有一些不如意,但毕竟这是第一次做,难免会遇到各种各样的问题。在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,不能灵活运用。在以后的学习过程中我会努力的。 四、 参考文献 [1] 谢自美.电子线路设计·实验·测试[M].武汉:华中理工大学出版社,1992. [2] 何立民.单片机应用系统设计[M].北京:北京航空航天大学出版社,1993. [3] 楼然笛.单片机开发[M].北京:人民邮电出版社,1994. [4] 付家才.单片机控制工程实践技术[M].北京:化学工业出版社 2004.3. [5] 李光才.单片机课程设计实例指导[M].北京:北京航空航天大学出版社 2004. [6] 刘湘涛.江世明.单片机原理与应用[M]. 北京:电子工业出版社 2006. 程序: /*************************************************************** * 程序功能: 数码管+DS1302的可调时钟(含一个闹钟功能) * * CPU 型号: AT89C51 * * 晶振频率: 12.0000MHz * * 时 间: 2013-12-29 * * 作 者: 唐蜜珠 * * 学 号: 20110261xx * * 班 级: 11电子1班 * * 说 明: 单片机课程设计 * ***************************************************************/ #include <reg52.h> /* 设置项序号宏定义 */ #define SETTING_NONE 0 #define SETTING_SECOND 1 #define SETTING_MINUTE 2 #define SETTING_HOUR 3 #define SETTING_DAY 4 #define SETTING_MONTH 5 #define SETTING_YEAR 6 #define SETTING_ALARM_SECOND 7 #define SETTING_ALARM_MINUTE 8 #define SETTING_ALARM_HOUR 9 /* 显示状态宏定义 */ #define DIS_MODE_TIME 1 /* 显示时间 */ #define DIS_MODE_DATE 2 /* 显示日期 */ #define DIS_MODE_ALARM 4 /* 显示闹钟 */ /* 闹钟响/停控制宏定义 */ #define ALARM_ON 1 /* 闹钟响 */ #define ALARM_OFF 0 /* 闹钟停 */ #define ALARM_MODE_NONE 0 #define ALARM_MODE_ALARM 1 #define ALARM_MODE_POINT 2 #define ALARM_MODE_DELAY 3 /* DS1302时钟芯片引脚定义 */ sbit DS1302_DATA = P1^0; sbit DS1302_SCLK = P1^1; sbit DS1302_CE = P1^2; /* 按键引脚定义 */ sbit KeyMenu = P3^5; sbit KeyAdd = P3^6; sbit KeyDec = P3^7; /* 闹钟蜂鸣器引脚定义 */ sbit Beep = P1^7; /* 共阴数码管段码表 */ unsigned char code codeSeg7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,}; /* 时间/日期相关变量 */ unsigned char century = 21,year,month,day,hour,minute,second; /* 闹钟变量 */ unsigned char alarm_hour,alarm_minute,alarm_second; /* 当前设置项序号变量, 初始化为SETTING_NONE表示非设置模式 */ unsigned char setting_item = SETTING_NONE; /* 显示状态变量, 初始化为DIS_MODE_TIME显示时间 */ unsigned char dis_mode = DIS_MODE_TIME; /* 闹钟响标志:0-闹钟没响 1-闹钟响 */ unsigned char flag_alarm_mode = 0; /* 闹钟响延时时间控制变量, 16位 */ unsigned int alarm_delay; unsigned char point_count; /********************************/ /* 函数功能:约xms毫秒延时 */ /* 入口参数:xms-延时xms毫秒 */ /* 出口参数:无 */ /********************************/ void DelayMs(unsigned int xms) { unsigned int i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } /*****************************************************************************************************/ /* 函数功能:定时器延时控制 */ /* 入口参数:mode-闹钟、整点报时、5s回显时间模式控制 alarmonoff-闹钟响(1) 不响(0) delay-延时时间(秒)*/ /* 出口参数:无 */ /*****************************************************************************************************/ void Alarm(unsigned char mode,unsigned char alarmonoff,unsigned char delay) { flag_alarm_mode = mode; /* 保存显示模式设置 */ Beep = !alarmonoff; /* 操作蜂鸣器, 硬件电路为0响 */ alarm_delay = delay * 100;/* alarm_delay为定时器0溢出中断计数, 10ms时基, 乘以100为1s */ } /********************************/ /* 函数功能:DS1302写字节 */ /* 入口参数:byte-写入字节 */ /* 出口参数:无 */ /********************************/ void DS1302_WriteByte(unsigned char byte) { unsigned char i; for(i=0;i<8;i++) { DS1302_SCLK = 0; byte >>= 1; /* BIT0数据移到CY寄存器 */ DS1302_DATA = CY; /* 将CY寄存器的值写到DS1302数据引脚 */ DS1302_SCLK = 1; /* 在时钟上升沿写入 */ } } /********************************/ /* 函数功能:DS1302读字节 */ /* 入口参数:无 */ /* 出口参数:返回读取的字节数据 */ /********************************/ unsigned char DS1302_ReadByte(void) { unsigned char i,byte = 0; DS1302_SCLK = 1; for(i=0;i<8;i++) //读数据 { byte >>= 1; DS1302_SCLK = 0; /* 时钟下降沿读取 */ if(DS1302_DATA) /* 读取引脚状态 */ byte |= 0x80; /* 保存 */ DS1302_SCLK = 1; } return (byte); } /******************************************/ /*函数功能:写DS1302 */ /*入口参数:addr-写目标地址, mdata-待写数据*/ /*出口参数:无 */ /******************************************/ void DS1302_WriteData(unsigned char addr,unsigned char mdata) //向DS1302写数据 { DS1302_CE = 0; DS1302_SCLK = 0; DS1302_CE = 1; /* 使能DS1302 */ DS1302_WriteByte(addr); /* 写入地址 */ DS1302_WriteByte(mdata);/* 写入数据 */ DS1302_CE = 0; } /********************************/ /*函数功能:读DS1302 */ /*入口参数:addr-读目标地址 */ /*出口参数:返回读到的数据 */ /********************************/ unsigned char DS1302_ReadData(unsigned char addr) //向DS1302读数据 { unsigned char mdata,mdatah,mdatal; DS1302_CE = 0; DS1302_SCLK = 0; DS1302_CE = 1; DS1302_WriteByte(addr); /* 写入地址 */ mdata = DS1302_ReadByte(); /* 读出数据 */ DS1302_CE = 0; mdatal = mdata & 0x0F; mdatah = (mdata>>4) & 0x0F; mdata = mdatal + mdatah * 10;/* 十六进制转化为十进制 */ return (mdata); } /**********************************************/ /*函数功能:修改DS1302的时间值 */ /*入口参数:addr-写目标地址, mdata-修改值 */ /*出口参数:无 */ /**********************************************/ void DS1302_RWriteData(unsigned char addr,unsigned char mdata) { unsigned char mdatah,mdatal; mdatal = mdata % 10; mdatah = mdata /10; mdata = mdatal + (mdatah<<4); /* 十进制转化为十六进制 */ DS1302_WriteData(0x8e,0x00); /* 关闭写保护 */ DS1302_WriteData(addr,mdata); /* 写入修改数据 */ DS1302_WriteData(0x8e,0x80); /* 写保护使能 */ } /********************************/ /*函数功能:初始化DS1302 */ /*入口参数:无 */ /*出口参数:无 */ /********************************/ void DS1302_Init(void) { unsigned char mdata; DS1302_CE = 0; DS1302_SCLK = 0; DS1302_CE = 1; DS1302_WriteByte(0x81); mdata = DS1302_ReadByte(); /* 读秒寄存器 */ if(mdata & 0x80) /* 秒寄存器最高位为时钟关闭位, 1-关闭 0-开启 */ { DS1302_RWriteData(0x80,0x00);/* 清除秒寄存器, 开启DS1302, 开始走时间 */ } DS1302_CE = 0; } /*********************************************************/ /*函数功能:判断当前设置项是否为参数所指 */ /*入口参数:item-待比较的设置项编号 */ /*出口参数:1-当前设置项为item所指 0-当前设置项非item所指*/ /*********************************************************/ unsigned char IsSettingItem(unsigned char item) { return (setting_item == item); } /***************************************/ /*函数功能:点亮1位数码管 */ /*入口参数:pos-显示位置 code1-显示段码*/ /*出口参数:无 */ /***************************************/ void Display_1Code(unsigned char pos,unsigned char code1) { P0 = ~code1; /* 设计采用共阳数码管, 共阴段码取反 */ P2 = (0x80 >> pos); /* 选择显示位置 */ DelayMs(1); /* 延时显示1ms */ P2 = 0x00; /* 关闭所有数码管, 消除重影 */ } /**********************************************************************/ /*函数功能:显示两位数字 */ /*入口参数:pos-显示的位置 num-待显示的数字 point-是(1)否(0)显示小数点*/ /*出口参数:无 */ /**********************************************************************/ void Display_2Num(unsigned char pos,unsigned char num,unsigned char point) { Display_1Code(pos,codeSeg7[num / 10]); /* 显示十位数 */ Display_1Code(pos + 1,point?codeSeg7[num % 10] | 0x80 : codeSeg7[num % 10]);/* 显示个位数, 如果point为真, 则最高位置1显示小数点 */ } /********************************/ /*函数功能:显示实时时间 */ /*入口参数:无 */ /*出口参数: */ /********************************/ void Display_Time(void) { Display_2Num(0,hour,IsSettingItem(SETTING_HOUR)); /* 位置0显示小时, 第三个参数表示是否显示小数点, 设置小时的时候显示, 下同 */ Display_1Code(2,0x40); /* 显示横杆 */ Display_2Num(3,minute,IsSettingItem(SETTING_MINUTE)); Display_1Code(5,0x40); Display_2Num(6,second,IsSettingItem(SETTING_SECOND)); } /********************************/ /*函数功能:显示当前日期 */ /*入口参数: */ /*出口参数: */ /********************************/ void Display_Date(void) { Display_2Num(0,century - 1,0); Display_2Num(2,year,IsSettingItem(0) || IsSettingItem(SETTING_YEAR)); /* IsSettingItem(0)表示非设置状态也显示小数点 */ Display_2Num(4,month,IsSettingItem(0) || IsSettingItem(SETTING_MONTH)); Display_2Num(6,day,IsSettingItem(0) || IsSettingItem(SETTING_DAY)); } /********************************/ /*函数功能:显示闹钟当前设置值 */ /*入口参数:无 */ /*出口参数:无 */ /********************************/ void Display_Alarm(void) { Display_2Num(0,alarm_hour,IsSettingItem(SETTING_ALARM_HOUR)); Display_1Code(2,0x40); Display_2Num(3,alarm_minute,IsSettingItem(SETTING_ALARM_MINUTE)); Display_1Code(5,0x40); Display_2Num(6,alarm_second,IsSettingItem(SETTING_ALARM_SECOND)); } /********************************/ /*函数功能:显示管理 */ /*入口参数:无 */ /*出口参数:无 */ /********************************/ void Display(void) { if(dis_mode == DIS_MODE_TIME) /* 时间显示模式 */ Display_Time(); /* 调用显示时间函数 */ else if(dis_mode == DIS_MODE_DATE)/* 日期显示模式 */ Display_Date(); else if(dis_mode == DIS_MODE_ALARM)/* 闹钟显示模式 */ Display_Alarm(); } /********************************/ /*函数功能:获取实时时间和日期 */ /*入口参数:无 */ /*出口参数:无 */ /********************************/ void GetDateTime(void) { hour = DS1302_ReadData(0x85); minute = DS1302_ReadData(0x83); second = DS1302_ReadData(0x81); year = DS1302_ReadData(0x8D); month = DS13
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服