单片机数字钟课程设计报告.docx
《单片机数字钟课程设计报告.docx》由会员分享,可在线阅读,更多相关《单片机数字钟课程设计报告.docx(28页珍藏版)》请在冰点文库上搜索。
![单片机数字钟课程设计报告.docx](https://file1.bingdoc.com/fileroot1/2023-7/12/e31ed877-896b-4ee4-bf3e-d5ed12351cbe/e31ed877-896b-4ee4-bf3e-d5ed12351cbe1.gif)
单片机数字钟课程设计报告
湖南工业大学
课程设计
资料袋
电气与信息工程学院3学年第1学期
课程名称单片机课程设计指导教师凌云职称教授
学生姓名专业班级学号
题目数字钟
成绩起止日期2013年12月23日~2014年1月10日
目录清单
序号
材料名称
资料数量
备注
1
课程设计任务书
2
课程设计说明书
3
课程设计图纸
张
4
心得体会
5
6
湖南工业大学
课程设计任务书
2013—2014学年第1学期
电气与信息工程学院电气自动化专业112班
课程名称:
单片机系统课程设计
设计题目:
数字钟
完成期限:
自2013年12月23日至2014年1月10日共3周
内
容
及
任
务
1.1单片机硬件显示装置制作(基本要求)
1.1.12人一组自行购买元器件,在焊接板上焊接一个单片机硬件显示装置,显示器至少能够显示2位数字。
1.1.2编写程序,在自己焊接的单片机硬件显示装置上,至少显示自己学号的最后2位。
程序可以用汇编语言或者是C51语言编写。
1.2数字钟设计(发挥要求)
在自己焊接的单片机硬件显示装置上,采用单片机内部的定时器设计24小时制数字钟,数字钟有6位数子显示,要求采用2个按键实现对钟校时。
单片机外接晶体振荡器频率准确稳定时,要求保证数字钟没有计时误差。
程序可以用汇编语言或者是C51语言编写。
1.3独立撰写完成课程设计说明书(课程设计报告)
进
度
安
排
起止日期
工作内容
2013.12.23~2013.12.29
焊接单片机硬件显示装置,编写程序
2013.12.30~2014.01.04
完成系统调试,课程设计软件、硬件验收
2014.01.05~2014.01.10
撰写课程设计报告
主
要
参
考
资
料
[1]欧伟明,何静,凌云.单片机原理与应用系统设计.电子工业出版社,2009年
[2]凌云等.单片机原理与技能训练.电子工业出版社,2012年
[3]刘苗生,潘宗预.单片机测控系统设计.中国物质出版社,2006年
单片机系统课程设计说明书
数字钟
起止日期:
2013年12月23日至2014年1月10日
学生姓名
班级
学号
成绩
湖南工业大学电气与信息工程学院
2014年1月10日
摘要
单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。
单片机体积小、重量轻、抗干扰能力强、环境要求不高、价格低廉、可靠性高、灵活性好、开发较为容易。
由于具有上述优点,在我国,单片机已广泛地应用在工业自动化控制、自动检测、智能仪器仪表、家用电器、电力电子、机电一体化设备等各个方面,而51单片机是各单片机中最为典型和最有代表性的一种。
这次课程设计通过对它的学习、应用,以AT89S5芯片为核心,辅以必要的电路,设计了一个简易的电子时钟,它由5V直流电源供电,通过数码管能够准确显示时间,调整时间,从而到达学习、设计、开发软、硬件的能力。
为实现定时控制以及对外界事件进行计数,在单片机应用系统中,常需要用到实时时钟和计数器。
51系列的单片机内部都具有两种功能,有的型号还具有捕获和监视定时的功能。
51系列的单片机内部都设有两个16位的可编程定时/计数器,可简称为定时器0(T0)和定时器1(T1)。
可编程是指其功能如工作方式、定时时间、量程、启动方式等均可由指令来确定和改变。
该电子时钟由89C51、按键、七段数码管等构成,采用晶振电路作为驱动电路,由定时器产生的一秒定时,达到时分秒的计时,六十秒为一分钟,六十分钟为一小时。
对于8051单片机的I/O口仅有32个,本实验采用若使单片机直接控制数码管,仅能实现4位显示。
为了充分利用单片机的I/O口,我们可以使用动态显示6位数码管,通过较高频率的动态扫描使数码管依次点亮,利用人类的视觉暂留效应实现6位显示。
关键词:
单片机、定时器、数字钟、动态显示、静态显示
第1章单片机与数字钟概述
1.1单片机
单片机发展史已经有几十年了。
1976年,Intel公司研制出MCS-48系列单片机。
该系列单片机具有以下特点:
CPU为4位或8位,ROM有1KB或2KB,RAM有64B或128B,具有并行接口,无串行接口,有1个8位的定时/计数器,有2个中断源,这是单片机问世的标志。
1.1.1单片机的组成及分类
单片机的核心部分是中央处理器CPU,它是单片机的大脑,由它统一指挥和协调各部分的工作。
时钟电路用于给单片机提供工作时所需要的时钟信号。
程序存储器和数据存储器分别用于存放单片机工作的用户软件和临时数据。
中断系统用于处理系统工作时出现的突发事件。
定时/计数器用于对时间定时或对外部事件计数。
它通过内部总线把计算机的各主要部件连接为一体,其内部总线包括地址总线、数据总线和控制总线。
其中,地址总线的作用是为数据交换时提供地址,CPU通过它们将地址输出到存储器或I/O接口;数据总线用于在CPU与存储器或I/O接口之间,或I/O接口与外设之间交换数据;控制总线包括CPU发出的控制信号线和外部送入CPU的应答信号线等。
输入输出接口(I/O接口)是计算机与输入输出设备之间的接口。
输入输出设备(I/O设备)是计算机与人或其他设备交换信息的装置,如显示器、键盘和打印机等。
单片机大致可以分为通用型/专用型、总线型/非总线型及工控型/家电型。
(1)通用型/专用型
这是按单片机适用范围来区分的。
例如,80C51是通用型单片机,它不是为某种专用途设计的;专用型单片机是针对一类产品甚至某一个产品设计生产的,例如为了满足电子体温计的要求,在片内集成ADC接口等功能的温度测量控制电路。
(2)总线型/非总线型
这是按单片机是否提供并行总线来区分的。
总线型单片机普遍设置有并行地址总线、数据总线、控制总线,这些引脚用以扩展并行外围器件都可通过串行口与单片机连接,另外,许多单片机已把所需要的外围器件及外设接口集成一片内,因此在许多情况下可以不要并行扩展总线,大大减省封装成本和芯片体积,这类单片机称为非总线型单片机。
(3)工控型/家电型
这是按照单片机大致应用的领域进行区分的。
一般而言,工控型寻址范围大,运算能力强;用于家电的单片机多为专用型,通常是小封装、低价格,外围器件和外设接口集成度高。
显然,上述分类并不是惟一的和严格的。
例如,80C51类单片机既是通用型又是总线型,还可以作工控用。
1.1.2AT89S51单片机
(1)AT89S51的主要特点
☉与MCS-51产品指令系统完全兼容;
☉4KB可编程Flash存储器;
☉寿命:
1000写/擦循环;
☉全静态工作:
0至33MHz;
☉数据保留时间:
10年;
☉三级程序存储器锁定;
☉256B片内RAM(128B用户RAM,128BSFR);
☉32个可编程I/O口;
☉两个16位定时/计数器;
☉5个中断源;
☉全双工可编程串行通道;
☉低功耗的空闲模式和掉电模式;
☉片内震荡器和时钟电路;
☉ISP在线编程功能;
☉一个内部看门狗。
(2)AT89S51的引脚说明
P0口:
P0口是一个8位漏极开路的双向I/O口。
作为输出口,每位能驱动8个TTL逻辑电平。
对P0端口写“1”时,引脚用作高阻抗输入。
当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。
在这种模式下,P0不具有内部上拉电阻。
在flash编程时,P0口也用来接收指令字节;在程序校验时,输出指令字节。
程序校验时,需要外部上拉电阻。
P1口:
P1口是一个具有内部上拉电阻的8位双向I/O口,P1输出缓冲器能驱动4个TTL逻辑电平。
此外,P1.0和P1.1分别作定时器/计数器2的外部计数输入(P1.0/T2)和定时器/计数器2的触发输入(P1.1/T2EX)。
在flash编程和校验时,P1口接收低8位地址字节。
P2口:
P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动AT89S52引脚图PLCC封装4个TTL逻辑电平。
对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOVX@DPTR)时,P2口送出高八位地址。
在这种应用中,P2口使用很强的内部上拉发送1。
在使用8位地址(如MOVX@RI)访问外部数据存储器时,P2口输出P2锁存器的内容。
在flash编程和校验时,P2口也接收高8位地址字节和一些控制信号。
P3口:
P3口是一个具有内部上拉电阻的8位双向I/O口,P3输出缓冲器能驱动4个TTL逻辑电平。
P3口亦作为AT89S52特殊功能(第二功能)使用,如下表所示。
在flash编程和校验时,P3口也接收一些控制信号。
ALE/PROG:
当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。
要注意的是:
每当访问外部数据存储器时将跳过一个ALE脉冲。
对FLASH存储器编程期间,该引脚还用于输入编程脉冲(PROG)。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。
该位置后,只有一条MOVX和MOVC指令才能将ALE激活。
此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。
PSEN:
程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲,在此期间,当访问外部数据存储器,将跳过两次PSEN信号。
EA/VPP:
外部访问允许,欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。
需注意的是:
如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接Vcc端),CPU则执行内部程序存储器的指令。
FLASH存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。
XTAL1:
振荡器反相放大器和内部时钟发生电路的输入端。
XTAL2:
振荡器反相放大器的输出端。
1.2数字钟
数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,已得到广泛的使用。
第2章系统硬件设计
2.1总体方案设计原则
☉在性价比满足应用系统要求的情况下,选择更可靠,更熟悉的单片机缩短研制周期。
☉尽可能选择自己较为熟悉的应用电路,以提高系统的可靠性。
☉单片机内部的资源与外部的扩展资源应在满足系统设计的基础上留有余地,为进一步的升级和扩展提供方便。
☉应充分的结合软件方案考虑硬件的结构,通常硬件功能较完善,其相应的软件程序就简单,但硬件的成本较高,而功能较低,其相应的软件就复杂,其实际常用软件代替硬件来降低成本。
☉整个系统相关的器件尽可能的做到性能相匹配。
☉充分的考虑系统的抗干扰性,如具有抗干扰的单片机并充分的帅选芯片与器件,在电路中采取隔离或屏蔽的措施等。
2.2数码管
数码管由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。
数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。
这些段分别由字母a,b,c,d,e,f,g,dp来表示。
按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。
本设计采用3个2位共阳极数码管显示时、分、秒。
(1)共阳极数码管
共阳极数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳极数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。
(2)共阴极数码管
共阴极数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴极数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。
2.3显示电路
用3个2位共阳极数码管显示时、分、秒,4个发光二极管代表时与分、分与秒之间的两点,和6个9012型三极管控制数码管的位选。
将数码管的段选端接到单片机的P0口,数码管的位选端通过三极管接到单片机的P2口。
2.3按键电路
这里使用三个按键调整数字钟的时间,按键每按一下蜂鸣器就叫一下。
2.4声音电路
用9012型三极管来驱动蜂鸣器。
2.5晶振电路
利用单片机芯片内部的振荡器,并在单片机外部引脚XTAL1、XTAL2两端跨接晶体振荡器和电容,就构成了稳定的自激振荡器,产生的脉冲信号直接送入内部时钟电路。
外接晶振时,C1和C2的值选择为22pF左右,C1和C2对时钟频率有微调作用,晶振的频率选择12MHz。
为了减小寄生电容,更好地保证震荡器稳定、可靠地工作,晶振和电容应尽可能地安装得与单片机引脚XTAL1和XTAL2靠近。
2.6复位电路
89S51的复位输入引脚RST提供了初始化的手段,在时钟电路工作之后,只要在RST引脚上出现2个机器周期以上的高电平,就能确保单片机可靠复位。
当89S51的RST引脚变为低电平后,退出复位状态,单片机从初始状态开始工作。
第3章系统软件设计
3.1软件程序内容
本设计的软件程序包括主程序、中断子程序、打铃子程序、时钟显示子程序、按键程序和延时子程序等等。
另外由于电路中有三个个按键,还另外设计了防抖动程序来防止干扰。
3.2软件流程图
3.2.1系统软件设计流程图
主程序是先开始,然后启动定时器,定时器启动后在进行按键检测,检测完后,就可以显示时间。
3.2.2系统按键检测流程图
按键处理是先检测功能键是否按下,如果按下,就判断是按了几次,如果是按了一次,秒就加一;如果是按了两次,分就加一;如果是按了三次,时就加一;如果没有按下,就把时间显示出来。
3.2.3系统定时中断流程图
定时器中断时是先检测1秒是否到,1秒如果到,秒单元就加1;如果没到,就检测1分钟是否到,1分钟如果到,分单元就加1;如果没到,就检测1小时是否到,1小时如果到,时单元就加1,如果没到,就显示时间。
3.3定时程序设计
单片机的定时功能也是通过计数器的计数来实现的,此时的计数脉冲来自单片机的内部,即每个机器周期产生一个计数脉冲,也就是每经过1个机器周期的时间,计数器加1。
如果MCS-52采用的12MHz晶体,则计数频率为1MHz,即每过1us的时间计数器加1。
这样可以根据计数值计算出定时时间,也可以根据定时时间的要求计算出计数器的初值。
MCS-51单片机的定时器/计数器具有4种工作方式,其控制字均在相应的特殊功能寄存器中,通过对特殊功能寄存器的编程,可以方便的选择定时器/计数器两种工作模式和4种工作方式。
定时器/计数器工作在方式0时,为13位的计数器,由TLX(X=0、1)的低5位和THX的高8位所构成。
TLX低5位溢出则向THX进位,THX计数溢出则置位TCON中的溢出标志位TFX.
当定时器/计数器工作于方式1,为16位的计数器。
本设计师单片机多功能定时器,所以MCS-51内部的定时器/计数器被选定为定时器工作模式,计数输入信号是内部时钟脉冲,每个机器周期产生一个脉冲使计数器增1。
3.3.1实时时钟实现的基本方法
时钟的最小计时单位是秒,但使用定时器的方式1,最大的定时时间也只能达到131ms。
我们可把定时器的定时时间定为50ms。
这样,计数溢出20次即可得到时钟的最小计时单位:
秒。
而计数20次可以用软件实现。
秒计时是采用中断方式进行溢出次数的累积,计满20次,即得到秒计时。
从秒到分,从分到时是通过软件累加并进行比较的方法来实现的。
要求每满1秒,则“秒”单元中的内容加1;“秒”单元满60,则“分”单元中的内容加1;“分”单元满60,则“时”单元中的内容加1;“时”单元满24,则将时、分、秒的内容全部清零。
3.3.2实时时钟设计步骤
(1)选择工作方式,计算初值;
(2)采用中断方式进行溢出次数累计;
(3)从秒——分——时的计时是通过累加和数值比较实现的;
(4)时钟显示缓冲区:
时钟时间在方位数码管上进行显示,为此在内部
RAM中要设置显示缓冲区,共6个地址单元。
显示缓冲区从左到右依次存放时、分、秒数值;
(5)主程序:
主要进行定时器/计数器的初始化编程,然后反复调用显示
子程序的方法等待中断的到来。
(6)中断服务程序:
进行计时操作
(7)加1子程序:
用于完成对时、分、秒的加操作,中断服务程序在秒、的最小计时单位是秒,但使用定时器的方式1,最大的定时时间也只能达到131ms。
我们可把定时器的定时时间定为50ms。
这样,计数溢出20次即可分、时加1。
3.4源程序
#include//51系列单片机头文件
#defineucharunsignedchar
#defineuintunsignedint
sbitSMG1=P2^7;//定义时的十位
sbitSMG2=P2^6;//定义时的个位
sbitLED1=P2^5;
sbitSMG3=P2^4;//定义分的十位
sbitSMG4=P2^3;//定义分的个位
sbitLED2=P2^2;
sbitSMG5=P2^1;//定义秒的十位
sbitSMG6=P2^0;//定义秒的个位
sbitkey1=P1^0;//定义调整按键
sbitkey2=P1^1;//定义加按键
sbitkey3=P1^2;//定义确认按键
sbitfeng=P3^7;//定义蜂鸣器
chartable[10]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f};
uintnumber,num;
uchartemp;
uchart_hr=16,t_min=15,t_sec=12;
uchart_hr1,t_hr2;
uchart_min1,t_min2;
uchart_sec1,t_sec2;
voiddelay(uintk)//延时子程序
{
while(k--);
}
voidspeak(uchartimer)//蜂鸣器发声程序
{
uinti=0;
ucharj=0;
for(i=400;i>0;i--)
{
feng=~feng;
for(j=timer;j>0;j--);
}
feng=1;
}
voidinterrutp_init()//中断定时初始化程序
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TR0=1;
}
voiddisplay()//数码管显示程序
{
t_hr1=t_hr/10;
t_hr2=t_hr%10;
t_min1=t_min/10;
t_min2=t_min%10;
t_sec1=t_sec/10;
t_sec2=t_sec%10;
SMG1=0;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=table[t_hr1];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
SMG1=1;SMG2=0;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=table[t_hr2];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
SMG1=1;SMG2=1;SMG3=0;SMG4=1;SMG5=1;SMG6=1;
P0=table[t_min1];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=0;SMG5=1;SMG6=1;
P0=table[t_min2];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=0;SMG6=1;
P0=table[t_sec1];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=0;
P0=table[t_sec2];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;
P0=0xff;
delay(100);
}
voidmain()//主程序
{
interrutp_init();
while
(1)
{
if(key1==0)
{
if(key1==0)
{
speak(80);
}
temp++;
if(temp>3)
temp=1;
}
switch(temp)
{
case0:
display();break;
case1:
TR0=0;
if(key2==0)
{
if(key2==0)
{
speak(80);
}
t_sec++;
if(t_sec>=60)
t_sec=0;
}
t_sec1=t_sec/10;
t_sec2=t_sec%10;
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=0;SMG6=1;
P0=table[t_sec1];
delay(100);
SMG1=1;SMG2=1;SMG3=1;SMG4=1;SMG5=1;SMG6=1;