数字电子钟课程设计报告

摘 要………………………………………………………………………………3

关键词………………………………………………………………………………3

一、设计任务与要求………………………………………………………………4

二、方案设计与论证………………………………………………………………4

方案一…………………………………………………………………………4

方案二…………………………………………………………………………5

三、硬件单元电路设计与参数计算………………………………………………5

1. 电源电路………………………………………………………………5

2. 按键电路………………………………………………………………5

3. 时钟电路…………………………………………………………………5

4. 驱动电路…………………………………………………………………5

5. LED显示电路………………………………………………………………5

6. 单片机电路………………………………………………………………6

四、软件设计与流程图……………………………………………………………10

五、总原电路及元器件清单………………………………………………………10

1.总原理图……………………………………………………………………10

2.PCB制板图…………………………………………………………………11

3.整体电路仿真图……………………………………………………………12

4.元件清单……………………………………………………………………12

六、安装与调试……………………………………………………………………13

1. 电路安装……………………………………………………………………13

2. 电路调试……………………………………………………………………13

3. 软件调试……………………………………………………………………13

七、性能测试与分析………………………………………………………………14

八、结论与心得……………………………………………………………………14

九、参考文献………………………………………………………………………15

十、致谢……………………………………………………………………………15

十一、程序清单……………………………………………………………………15

摘要:本论文基于单片机原理技术介绍了一款于AT89C52芯片作为核心控制器的单片机数字电子钟的设计与制作,包括硬件电路原理的实现方案设计、软件程序编辑的实现、数字电子钟正常工作的流程、原理图仿真实现、硬件实物的安装制作与硬件实物的调试过程。该单片机数字电子钟采用LED 数码管能够准确显示时间(显示格式为:时时,分分,秒秒),可随时进行时间调整,时间可采用12 小时制显示或24 小时制显示,采用12 小时显示时可在标志位数码管上显示A(表示上午)或B(表示下午),可暂停时间的变动,暂停时一位数码管上显示字母H,可按自己的要求设置扩展的小键盘个数。

关键词:单片机 ;数字电子钟 ;数码管 ;AT89C52

一、 设计任务与要求

1、设计任务

用单片机设计一个数字电子钟,采用LED 数码管来显示时间。

2、设计要求

(1)显示格式为:XX:XX:XX, 即:时:分:秒。

(2)时间可采用12 小时制显示或24 小时制显示,采用12 小时显示时必须

在另外一个数码管上显示A(表示上午)或B(表示下午)。

(3)设置一个按键用于时间显示方式的切换。

(4)系统上电后从上电时初始化显示: 12-00-00开始计时。

(5)能进行时间的调整,可暂停时间的变动,暂停时一位数码管上显示字母H

可按自己的要求设置扩展的小键盘个数。

二、 方案设计与论证

https://upload.fanwen118.com/wk-img/img100/3997401_1.jpghttps://upload.fanwen118.com/wk-img/img100/3997401_2.jpghttps://upload.fanwen118.com/wk-img/img100/3997401_3.jpg

图1 系统整体框图

整个系统用单片机作为中央控制器,由单片机执行采集芯片内部时钟信号,时钟信号通过单片机I/O口传给单片机,单片机模块控制驱动模块驱动显示模块,通过显示模块来实现信号的输出、LED的显示及相关的控制功能。系统设有按键模块用于对时间进行调整及扩展多个小键盘,系统整体框图如图1所示。

1、 单片机芯片选择方案

方案一:AT89S52是一个低功耗,高性能CMOS 8位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器。主要性能有:与MCS-51单片机产品兼容、全静态操作:0Hz~33Hz、 三级加密程序存储器、32个可编程I/O口线、三个16位定时器/计数器、八个中断源、全双工UART串行通道、掉电后中断可唤醒、看门狗定时器、双数据指针、掉电标识符、易编程。

方案二:AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM)。主要性能有:兼容MCS51指令系统、32个双向I/O口、256x8bit内部RAM、3个16位可编程定时/计数器中断、时钟频率0-24MHz、2个串行中断、可编程UART串行通道、2个外部中断源、6个中断源、2个读写中断口线、3级加密位、低功耗空闲和掉电模式、软件设置睡眠和唤醒功能。

从单片机芯片主要性能角度出发,本数字电子钟单片机芯片选择设计采用方案一。

2、数码管显示选择方案

方案一:静态显示。静态显示,即当显示器显示某一字符时,相应的发光二极管恒定导通或截止。该方式每一位都需要一个8 位输出口控制。静态显示时较小电流能获得较高的亮度,且字符不闪烁。但因当所需显示的位数较多时,静态显示所需的I/O口数较大,造成资源的浪费。

方案二:动态显示。动态显示,即各位数码管轮流点亮,对于显示器各位数码管,每隔一段延时时间循环点亮一次。利用人的视觉暂留功能可以看到整个显示,但须保证扫描速度足够快,人的视觉暂留功能才可察觉不到字符闪烁。显示器的亮度与导通电流、点亮时间及间隔时间的比例有关。调整参数可以实现较高稳定度的显示。动态显示节省了I/O口,降低了能耗。

从节省单片机芯片I/O口和降低能耗角度出发,本数字电子钟数码管显示选择设计采用方案二。

3、 数码管驱动选择方案

方案一:上拉电阻驱动方式。数码管段码与接有上拉电阻的单片机芯片I/O口相连,通过编程,单片机芯片即控制段码电平的高低。该方式经费低,但实物制作较复杂。

方案二:74LS245芯片驱动方式。数码管段码与74LS245芯片B口相连,74LS245芯片A口与单片机芯片I/O口,通过编程,单片机芯片即可控制段码电平的高低。该方式实物制作简单,增强驱动数码管段码能力。

从实物制作简易程度与驱动数码管段码能力角度出发,本数字电子钟数码管驱动选择设计采用方案二。

三、 硬件单元电路设计与参数计算

1、电源电路

本数字电子钟设计所需电源电压为直流、电压值大小5V的电压源 。从硬件实物设计简易程度与经费方面考虑,用两节电压值大小2.5V干电池与电路电压源引脚相连接即可达到硬件设计要求。即本数字电子钟设计用两节电压值大小2.5V干电池做硬件电路电压源。

2、按键电路

本数字电子钟设计所需按键用于进行显示时间的调整与设置扩展的小键盘。

单片机芯片4个I/O口可与按键直接相连,通过编程,单片机芯片即可控制按键接口电平的高低,即按键的开与关,以达到用按键进行显示时间的调整与设置扩展的小键盘的设计要求。

3、时钟电路

单片机芯片可使用内部时钟电路和外部时钟电路两种方式产生电路所需的时钟脉冲,内部时钟电路实现可用石英晶体和微调电容外接即可达到,外部时钟电路实现需要一个外部脉冲源引入脉冲信号以保证个单片机之间时钟信号的同步。从硬件实现难易角度考虑,内部时钟电路的实现比外部时钟电路的实现更简易。既本数字电子钟设计所需的时钟源采用内部时钟电路实现。所用定时方式为工作方式1,石英晶振为12M,即最小定时时间为1us,最大定时时间约为65.5ms,其电路图如下图2所示。

https://upload.fanwen118.com/wk-img/img100/3997401_4.jpg

图2 时钟电路图

4、 驱动电路

从实物制作简易程度与驱动数码管段码能力角度出发,本数字电子钟设计采用数码管段码与74LS245芯片B口相连,74LS245芯片A口与单片机芯片I/O口,通过编程,单片机芯片即可控制段码电平的高低的方式实现数码管段码控制,74LS245芯片图如下图3所示。

https://upload.fanwen118.com/wk-img/img100/3997401_5.jpg

图3 74LS245芯片图

5、 LED显示电路

数字电子钟设计的显示模块用8个一位数码管实现,也可用两个四位一体数码管实现。两种实现方式实现效果一样。从实物制作的难易程度出,本数字电子钟设计采用两个四位一体数码管实现。即数码管引脚与单片机芯片和74LS245对应引脚相连接。

单片机电路

本数字电子钟设计采用AT89S52单片机芯片作为中央控制器,实现信号的输出、LED的显示及相关的控制功能。

四、 软件设计与流程图

1、数字电子时钟主程序流程图

主程序流程图如下图图4所示。

https://upload.fanwen118.com/wk-img/img100/3997401_6.jpg

图4 数字电子时钟主程序流程图

2、中断服务程序流程图

中断服务程序流程图如下图图5所示。

数字电子钟课程设计报告

图5 中断服务程序流程图

3、显示子程序流程图

显示子程序流程图如下图图6所示。

https://upload.fanwen118.com/wk-img/img100/3997401_7.jpg

图6 显示子程序流程图

五、总原电路及元器件清单

1.总原理图

最小系统控制原理图如下图图7所示, 数码管原理图如下图图8所示。

https://upload.fanwen118.com/wk-img/img100/3997401_8.jpg

图7 最小系统控制原理图

https://upload.fanwen118.com/wk-img/img100/3997401_9.jpg

图8 数码管原理图

2.PCB制板图

数码管PCB图如下图图9所示,最小系统控制PCB图如下图图10所示。

https://upload.fanwen118.com/wk-img/img100/3997401_10.jpg

图9 数码管PCB图

https://upload.fanwen118.com/wk-img/img100/3997401_11.jpg

图10 最小系统PCB图

3.整体电路仿真图

整体电路仿真图如下图图11所示。

https://upload.fanwen118.com/wk-img/img100/3997401_12.jpg

图11 整体电路仿真图

4.元件清单

六、安装与调试

1. 电路安装

安照电路原理图把元器件安装到已打好的铜板对应的位置,把个元器件固定在铜板后,用导线把对应的元器件的引脚相连接,再用焊锡焊接好即可。

注意事项:(1)元器件的布局应尽量集中,且各个元器件间引脚的连线应尽量短、不弯曲,跳线尽量少。(2)各个元器件引脚的焊接不要虚焊。

2. 电路调试

把相应编译好的目标程序代码加载到单片机芯片AT89S52,可接上5V电压源即开始进行硬件电路的调试工作。如果显示结果不符合设计要求,即检查电路各连接点是否正确连接,再次进行硬件电路的调试工作,或是检查代码程序是否符合硬件电路的设计,若有错即进行相应的修改,编译后,再进行硬件电路的调试工作。如此反复操作,直到调试出正确结果。

3. 软件调试

(1) 在计算机上运行程序调试软件Keil,进行程序调试,若显示0错误(S),0警告(S)即证明程序代码正确。

(2)在Proteus软件画好的电路原理图中加载程序代码到单片机芯片AT89S52中,进行模拟仿真。若出现错误,查看错误后进行相应修改再进行调试与模拟仿真,直到调试出正确结果。

七、性能测试与分析

1、系统上电后进行功能的测试,通过测试观察到,系统上电后数码管上显示时间:12-00-00,

图12 实物图一

接着按下K1按键调整时间小时数的显示,即小时加1,按下K2按键调整时间分钟数的显示,即分钟加1,按下K3按键调整时间秒数的显示,即秒数加1,实物图二如下图图13所示。

图13 实物图二

然后按下K5按键调整时间12 小时制的显示或24 小时制的显示。在24小时制的显示的情况下,显示时间制的数码管上不显示,只显示时,分,秒;在12 小时制的显示的情况下,如果小时数大于12小时的情况,一个数码管上显示B(表示下午);反之如果小时数小于12小时的情况,一个数码管上显示A(表示上午);,实物图三如图14所示。

图13 实物图三

通过测试,本作品设计实现了数字电子钟的基本功能,还增加了时间制转换的功能,且系统工作稳定。

八、结论与心得

1、结论

本单片机数字电子钟系统的功能基本符合显示格式为:XX:XX:XX, 即

时:分:秒。时间可采用12 小时制显示或24 小时制显示,采用12 小时显示时

必须在另外一个数码管上显示A(表示上午)或B(表示下午)。设置一个按键用

于时间显示方式的切换。系统上电后从上电时初始化显示: 12-00-00开始计时,

能进行时间的调整,可暂停时间的变动,暂停时一位数码管上显示字母H,可按自

己的要求设置扩展的小键盘个数设计任务的要求,经过测试数据显示, 系统的

可靠性已经基本能够达到实际电子钟的设计要求,同时本单片机数字电子钟系统

具有扩展性。

课程设计是培养学生综合运用所学知识,发现实际问题、提出实际问题、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际学习能力、动手能力的具体训练和考察过程。

在此次数字钟设计过程中, 在学习新知识的同时,把在课程中学到的理论知识运用到实际作品设计、操作中,更进一步地熟悉了单片机芯片的结构及掌握了其工作原理和具体的使用方法与相关元器件的参数计算方法、使用方法,了解了电路的开发和制作及课程设计报告的编写。加深了对相关理论知识及专业知识的掌握度,增强自身的动手能力,锻炼及提高了理解问题、分析问题、解决问题的能力,更深刻的体会到了理论联系实际的重要性,进一步掌握画图软件的使用和提高相应的画图操作水平及技巧。

九、参考文献

[1] 沈精虎.Protel 99SE基础教程[J].

[2] 李广弟,朱月秀,冷祖祁. 单片机的硬件结构[J] . 页码148。

[3] 谭丙煜.怎样撰写科学论文[M].2版.沈阳:辽宁人民出版社,1982:5-6.(本条为中文图书著录格式)

[3] 陈正义. 单片机控制实习[D].页码148。

十、致谢

从课题的开始到最终的完成,本课程设计及报告论文是在指导老师的精心指导和同学的热心帮助下顺利完成的。

本课程设计能顺利地完成,与父母多年来一如既往的支持和关怀是分不开的,在此,向任劳任怨、含辛茹苦的父母致以衷心的感谢!

此外衷心感谢在本次课程设计中指点和帮助我的指导老师与同学!

感谢学院为我们提供了良好课程设计仪器设备及学习环境。

十一、程序清单

/********************************************************************

* 描述* * 电子时钟,LED数码管显示,晶振使用12MHz *

* K1---时调整 *

K2---分调整 * K3---秒调整 K4---时间暂停 K5---12小时制和24小时制切换

* 上电时初始化显示:12-00-00 *

*********************************************************************#include <reg51.h>

#include <intrins.h>

unsigned char data dis_digit;

unsigned char key_s, key_v;

unsigned char code dis_code[11]={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00

};//0,1,2,3 4, 5, 6, 7, 8, 9, off //共阴数码管

unsigned char data dis_buf[8];

unsigned char data dis_index;

unsigned char hour,min,sec;

unsigned char sec100;

unsigned char flag,flag1,flag2; //falg用于时间停止和启动标志,falg1为12小时和24小时的切换标志,falg2为12小时的上午和下午的切换标志

sbit K1 = P1^0; //用于时的调整

sbit K2 = P1^1; //用于分的调整

sbit K3 = P1^2; //用于秒的调整

sbit K4 = P1^3; //用于时间调整的开关,按下一次暂停时间,再按一次时则开始计时

sbit K5 = P1^4; //用于24小时制和12小时制的切换

bit scan_key();

void proc_key();

void inc_sec();

void inc_min();

void inc_hour();

void inc_hour1();

void delayms(unsigned char ms);

void main(void)

{

P0 = 0xff;

P2 = 0xff;

TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式

TH1 = 0xd8; //使用12MHz的晶振,定时时间为:10ms

TL1 = 0xf0;

TH0 = 0xf8; //定时时间为2ms,用于数码管的动态扫描

TL0 = 0x30;

hour = 12;

min = 00;

sec = 00;

sec100 = 0;

flag = 0;

flag1 = 0;

dis_buf[0] = dis_code[hour / 10]; // 时十位

dis_buf[1] = dis_code[hour % 10]; // 时个位

dis_buf[2] = dis_code[min / 10]; // 分十位

dis_buf[3] = dis_code[min % 10]; // 分个位

dis_buf[4] = dis_code[sec / 10]; // 秒十位

dis_buf[5] = dis_code[sec % 10]; // 秒个位

dis_buf[6] = 0x00; // 关闭该位数码管

dis_buf[7] = 0x7f; // 显示 B 表示下午

dis_digit = 0xfe;

dis_index = 0;

TCON = 0x01; //T1:TF1 TR1 T0:TF0 TR0 定时中断:IE1 IT1 IE0 IT0 //外部中断0的触发方式为下降沿触发

IE = 0x8a; // 使能timer0,1 中断,控制IE寄存器的格式:EA - - ES ET1 EX1 ET0 EX0

// 1 0 0 0 1 0 1 0

TR0 = 1; //开定时器0

TR1 = 1; //开定时器1

key_v = 0x1f; //定义为K1,K2,K3,K4,K5相应的按键,当没有按下时则为,K1,K2,K3,K4,K5,都为高电平,0x1f

while(1)

{

if(scan_key()) //先扫描一次是否有按键按下

{

delayms(10); //延时

if(scan_key()) //再次扫描一次是否有按键 按下

{

key_v = key_s; //将key_s的值传给key_v

proc_key();

}

}

}

}

bit scan_key()

{

key_s = 0x00; //设置key_s先为0

key_s |=K5;

key_s <<= 1;

key_s |= K4;

key_s <<= 1;

key_s |= K3;

key_s <<= 1;

key_s |= K2; //K2 -> P1.1,若K2按下则为0,当K2按下时key_s与K2或的结果会使得key_s为0x00,未按下时K2则为1,key_s与K2或的结果会使得key_s为0x01

key_s <<= 1; //将key_s左移一位,

key_s |= K1; //K1 -> P1.0,若K1按下则为0,当K1按下时key_s与K1或的结果会使得key_s为0x00或是0x02,没有按下时则得到的结果为0x01或是0x03

return(key_s ^ key_v); //进行逻辑异或运算,相同为0,不同为1. 已经定义了变量:key_v = 0x1f; 如果两个按键都没有按下则是得到0x03,异或的结果是为0

}

void proc_key()

{

if(K4==0) //K4是否按下

{

flag++; //关闭定时器

TR1=0; //关闭定时器1

dis_buf[6] = 0x76; // 显示 H,用于表示设定时间的标志

}

if(K5==0)

{

flag1++; //flag1的初始值是0,falg1为12小时和24小时的切换标志

if(flag1==1) //24小时制

{

if(dis_buf[7]==0x7f) //判断是不是下午

{

hour=hour+12;

dis_buf[7]=0x00;

}

dis_buf[7] = 0x00; // 关闭显示

if(hour >23)

{

hour = 0;

}

if(hour > 9)

dis_buf[0] = dis_code[hour / 10]; // 时十位

else

dis_buf[0] = 0x00; // 当小时的十位为0时不显示

dis_buf[1] = dis_code[hour % 10]; // 时个位

}

if(flag1==2) //12小时制

{

flag1=0;

if(hour>12||hour==0) //判断是不是下午,并用于处理24小时制的大于13和等于0的处理

{

if(hour>12)

hour=hour-12;

if(hour==0)

hour=12;

dis_buf[7]=0x7f; //显示下午 B

}

else

dis_buf[7] = 0x77; // 显示 A 表示上午

if(hour > 9)

dis_buf[0] = dis_code[hour / 10]; // 时十位

else

dis_buf[0] = 0x00; // 当小时的十位为0时不显示

dis_buf[1] = dis_code[hour % 10]; // 时个位

}

}

if((key_v & 0x01) == 0) // K1,当只有K1按下时,则key_s为0x02,没有按下时key_s则为0x03

{

if(flag1==0)

inc_hour();

if(flag1==1)

inc_hour1();

}

else if((key_v & 0x02) == 0) // K2, 当只有K2按下时,则key_s为0x01,没有按下时key_s则为0x03

{

min++;

if(min > 59)

{

min = 0;

}

dis_buf[2] = dis_code[min / 10]; // 分十位

dis_buf[3] = dis_code[min % 10]; // 分个位

}

else if((key_v & 0x04) == 0) // K3是否按下

{

sec++;

if(sec > 59)

{

sec = 0;

}

dis_buf[4] = dis_code[sec / 10]; // 秒十位

dis_buf[5] = dis_code[sec % 10]; // 秒个位

}

if(flag==2)

{

flag=0;

TR1=1;

dis_buf[6] = 0x00;

if(flag1==0)

{

if(flag2)

dis_buf[7] = 0x77; // 显示 A 表示上午

else

dis_buf[7] = 0x7f; // 显示 B 表示下午

}

}

}

void timer0() interrupt 1

// 定时器0中断服务程序, 用于数码管的动态扫描

// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量

// dis_digit --- 位选通值, 传送到P0口用于选通当前数码管的数值, 如等于0xfe时,

// 选通P2.0口数码管

// dis_buf --- 显于缓冲区基地址

{

TH0 = 0xf8; //定时时间为2ms

TL0 = 0x30;

P2 = 0xff; // 先关闭所有数码管

P0 = dis_buf[dis_index]; // 显示代码传送到P0口

P2 = dis_digit; //

dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管

dis_index++; //

dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描 ,限定了只扫描8位,当为超过8位时则开始清零.

} //0x07=0000 0111 dis_index在一个个加一时,则为加到8次。

//定时器1的定时时间为10ms

void timer1() interrupt 3

{

TH1 = 0xd8;

TL1 = 0xf0;

sec100++;

if(sec100 >= 100) //定时1秒的时间

{

sec100 = 0;

inc_sec();

}

}

void inc_sec()

{

sec++;

if(sec > 59)

{

sec = 0;

inc_min();

}

dis_buf[4] = dis_code[sec / 10]; // 秒十位

dis_buf[5] = dis_code[sec % 10]; // 秒个位

}

void inc_min()

{

min++;

if(min > 59)

{

min = 0;

if(flag1==0)

inc_hour();

if(flag1==1)

inc_hour1();

}

dis_buf[2] = dis_code[min / 10]; // 分十位

dis_buf[3] = dis_code[min % 10]; // 分个位

}

void inc_hour() //12小时制

{

hour++;

if(hour > 12)

{

flag2=~flag2;

hour = 1;

}

if(hour > 9)

dis_buf[0] = dis_code[hour / 10]; // 时十位

else

dis_buf[0] = 0x00; // 当小时的十位为0时不显示

dis_buf[1] = dis_code[hour % 10]; // 时个位

if(flag2)

dis_buf[7] = 0x77; // 显示 A 表示上午

else

dis_buf[7] = 0x7f; // 显示 B 表示下午

}

void inc_hour1() //24小时制时间

{

hour++;

if(hour >23)

{

hour = 0;

}

if(hour > 9)

dis_buf[0] = dis_code[hour / 10]; // 时十位

else

dis_buf[0] = 0x00; // 当小时的十位为0时不显示

dis_buf[1] = dis_code[hour % 10]; // 时个位

}

void delayms(unsigned char ms)

// 延时子程序

{

unsigned char i;

while(ms--)

{

for(i = 0; i < 120; i++);

}

}

相关推荐