资源描述
单片机原理与应用
课程设计
【设计题目】 数字钟设计与实现
【指导教师】 ***
【班级】 自动化103班
【姓名】 ***
【学号】 ***8
【日期】 2012年11月04日
电子信息技术专业单片机综合实践任务书
设计
题目
数字钟的设计与实现
导师姓名
主要内容及目标
①通过单片机内定时器控制走时,准确持续走时,调时不影响走时。
②在八个数码管上显示时、分、秒及两个小数点。
③含有闹钟功能,可以选择闹钟开关,可以设定闹铃时间。
④到达闹钟时刻蜂鸣器警报,可以关掉警报。
具有的设计条件
1. PC机一台;
2. AT89S51单片机最小系统版一片;
3. Keil C调试环境、Proteus仿真软件。
计划设计进程
(1)明确课题对程序功能,运算精度等方面的要求及硬件条件
(2)把复杂问题分解为若干模块,确定各模块处理方法,画出流程图。
(3)编制程序,根据流程图精心选择合适的指令和寻址方式来编制源程序
(4)对程序进行汇编,调试和修改,直到程序运行结果正确为止。
(5)购买器材,连接、制作硬件;
(6)将软件功能在硬件上得到实现,做出数字钟实物。
参考文献
[1]张毅刚、彭喜元 《单片机原理与应用设计》 电子工业出版社
[2]李玉梅 《基于MCS-51系列单片机原理的应用设计》 国防工业出版社
[3]顾栤、赵伟军、王泰 《单片机计算机原理开发应用》 高等教育出版社
[4]张洪润、蓝清华 《单片机应用技术教程》 清华大学出版社
1、设计目的
(1)通过对课题设计方案的分析、选择、比较、熟悉单片机用系统开发、研制的过程,软硬件设计的方法、内容及步骤。
(2)培养针对课题需要,选择和查阅有关手册、图表及文献资料的自学能力,提高组成系统、编程、调试的动手能力;
(3)提高综合及灵活运用所学知识解决工业控制的能力,培养动手能力和实际应用能力。
2、设计内容
2.1任务及要求
①通过单片机内定时器控制走时,准确持续走时,调时不影响走时。
②在八个数码管上显示时、分、秒及两个小数点。
③含有闹钟功能,可以选择闹钟开关,可以设定闹铃时间。
④到达闹钟时刻蜂鸣器警报,可以关掉警报。
2.2系统功能说明
电子钟的格式为:XX.XX.XX ,由左向右分别为:时、分、秒。完成显示由秒01一直加1至59,再恢复为00;分加1,由00至01,一直加1至59,再恢复00;时加1,时由00加至23之后秒、分、时全部清清零。该钟使用T0作250us的定时中断。
走时调整:走时过程中直接调整且不影响走时准确性,按下h键对“时”显示进行调整(每按一次加1);按下m键对“分”显示进行调整(每按一次加1);按下s键“秒”显示进行调整(每按一次加1)。
闹时调整:按下BUT键进入闹时调整,但不影响走时准确性,按下h键对“时”显示进行调整(每按一次加1);按下m键对“分”显示进行调整(每按一次加1)。
闹铃启/停设定:通过模式设定键cancel选择为闹铃启/停设定,cancel键断开闹时功能启动;按下cancel键闹铃功能关闭,也可在闹铃响起后终止闹铃。
2.3软件研制方面
1. 采用模块化程序结构设计软件,首先将整个软件分成若干功能模块;
2. 根据流程图,编写源程序;
3. 上机调试各模块程序;
4. 与硬件一起联调,最后完成全部调试工作。
2.4硬件研制方面
1. 将整个硬件系统划分为若干功能单元电路,绘出整个系统逻辑电路图,注明各交单元电路间接口信号 ;
2. 完成各单元电路设计,包括选择合适的各类元器件和电路板设计(元件布局和走线)。
2.5源程序流程图
初始化
清数码管显示
时钟芯片赋初值
是
定闹钟程序
取时钟
否
送显示
BUT键按下
3、仿真实现(电路连接图)
3.1引脚连接
8位高亮共阴型数码管,单片机P1.0~P1.7接数码管a~dp脚,P3.0~P3.7接数码管1~4脚, P2.0~P2.2接s、m、h控制键,P2.3接BUT键,P2.4接蜂鸣器,P2.5接cancel键,RST用单片机自带。
3.2仿真结果(电路原理图)
(备注:为效果直观,仿真时用LED代替的蜂鸣器。)
4、总结
通过这次课程设计我们最大的收获是对单片机的定时中断方式有了直观的认识,设计数字钟我们用单片机内部定时\计数器,通过设置定时器产生精确的定时中断,达到计时的目的。
用定时器可以产生250us的精确定时,然后,4000次中断后就得到了精确的1s的定时。60个1s,即产生了1分钟等等……用延时也可以做电子钟,但产生的定时一般是近似值,走得时间久了,定时会产生较大的偏差,而用定时器中断做的电子钟就不会有这个问题,很准确。
两星期前,我们对单片机知之甚少,我们首先从任务要求出发,分析如何实现功能,然后将其分为若干模块,将每个模块设计好以后,再进行总体设计,最后是将硬件电路焊好,并进行电路连接。现在我们熟悉了51单片机的指令系统,熟悉了定时器/计数器和中断系统的使用,了解了串行接口的基本使用方法,基本掌握了单片机程序设计的方法。
由于对单片机我们还只是接触了皮毛,所以先做一个功能相对简单电子钟暂且练习对定时器/计数器的用法,还有就是系统简单好调试,以保证按时完成设计任务。在以后的学习中,我们打算逐渐增加它的功能,比如说加温度控制,加秒表等功能来完善这个电子钟。在实验中用8个数码管本计划加入日期显示,最终未能实现,待以后用更多时间改正。
通过答辩,我们意识到了原来没有注意的地方,比如点阵LED一般采用扫描式显示,实际运用分为三种方式:点扫描;行扫描;列扫描。若使用点扫描,其扫描频率必须大于16×64=1024Hz,即周期小于1ms。若使用第二和第三种方式,则频率必须大于16×8=128Hz,周期小于7.8ms即可符合视觉暂留要求。此外一次驱动一列或一行(8颗LED)时需外加驱动电路(三极管)提高电流,否则LED亮度会不足,且有时出现数字显示不明显的状况。
最后,在这里我们要感谢指导老师储忠、胡学友,感谢储老师和胡老师在设计及改正中给予的宝贵指导;另外,还要特别感谢郭登五、张悦龙等悉心给予帮助的同学。
5、参考文献
[1]张毅刚、彭喜元 《单片机原理与应用设计》 电子工业出版社
[2]李玉梅 《基于MCS-51系列单片机原理的应用设计》 国防工业出版社
[3]顾栤、赵伟军、王泰 《单片机计算机原理开发应用》 高等教育出版社
[4]张洪润、蓝清华 《单片机应用技术教程》 清华大学出版社
附录
/**********************************************************************
* 程序名; 时钟实验2
* 功 能: 数码管通过动态扫描显示时间,时间可设定,调整时间时时钟照常走.
* 编程者: ZPZ
* 编程时间:2009/8/9
**********************************************************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit _led=P2^7;
sbit key1=P2^0;
sbit key2=P2^1;
sbit key3=P2^2;
uchar num=0,temp=0,count=0;
uchar aa;
uchar hour,min,sec;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void delay(uint z);
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar aa);
void read_key();
//void led();
/****************** 主函数 *******************/
void main()
{
P2=0xff;
hour=12;
min=0;
sec=0;
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
while(1)
{
read_key();
if(temp>=20)
{
temp=0;
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)
{
hour=0;
}
}
}
}
if(count<=15)
display(table[hour/10],table[hour%10],table[min/10],
table[min%10],table[sec/10],table[sec%10],0xff);
if(count>15)
display(table[hour/10],table[hour%10],table[min/10],
table[min%10],table[sec/10],table[sec%10],0x00);
}
}
/****************** 显示函数 *******************/
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar aa)
{
if(num==1){P1=0x01&aa;P0=a;delay(2);}else{P1=0x01;P0=a;delay(2);} //hour
if(num==1){P1=0x02&aa;P0=b;delay(2);}else{P1=0x02;P0=b;delay(2);} //hour
if(num==2){P1=0x04&aa;P0=c;delay(2);}else{P1=0x04;P0=c;delay(2);} //min
if(num==2){P1=0x08&aa;P0=d;delay(2);}else{P1=0x08;P0=d;delay(2);} //min
if(num==3){P1=0x10&aa;P0=e;delay(2);}else{P1=0x10;P0=e;delay(2);} //sec
if(num==3){P1=0x20&aa;P0=f;delay(2);}else{P1=0x20;P0=f;delay(2);} //sec
}
/************** 定时器0中断函数 ***************/
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
temp++;
}
/************** 定时器1中断函数 ***************/
void timer1() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
count++;
if(count>=20)
count=0;
}
/****************** 延时子函数 *******************/
void delay(uint z)
{
uint j,k;
for(j=z;j>0;j--)
for(k=120;k>0;k--);
}
/****************** 读按键函数 *******************/
void read_key()
{
if(key1==0)
{
_led=0;
delay(50);
if(key1==0)
{
num++;
if(num>3){num=0;}
}
while(!key1);
delay(10);
while(!key1);
_led=1;
}
if(key2==0)
{
_led=0;
delay(90);
if(key2==0)
{
if(num==1){hour++;if(hour==24)hour=0;}
if(num==2){min++;if(min==60)min=0;}
if(num==3){sec++;if(sec==60)sec=0;}
}
while(!key1);
delay(10);
while(!key1);
_led=1;
}
if(key3==0)
{
_led=0;
delay(90);
if(key3==0)
{
if(num==1){hour--;if(hour==0)hour=23;}
if(num==2){min--;if(min==0)min=59;}
if(num==3){sec--;if(sec==59)sec=59;}
}
while(!key1);
delay(10);
while(!key1);
_led=1;
}
}
展开阅读全文