点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87761539?spm=1001.2014.3001.5503
源码获取
主要内容:
电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。同时电子钟可以集成诸多功能,如秒表、温度测量、水平检测等功能。
基本要求:
1、能够实现展示当前时间
2、秒数误差控制在1秒以内
3、输出形式采用数字显示
4、给出范围,设定时间时不可超出范围使其完成循环
主要参考资料:
[1]余发山 王福忠.《单片机原理及应用技术》.中国矿业大学出版社.2008
[2]彭伟.《单片机C语言程序设计实训》电子工业出版社.2010.
[3]杨凌霄.《微型计算机原理与应用》.中国电力出版社2003
[4]李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,1998
[5]李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994
[6]阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989
[7]DS18B20数据手册
完 成 期 限 : 2022 年 12 月 23 日
指导教师签名 :
课程负责人签名 :
摘要
本课程设计完成了数字电子钟的设计,数字电子钟是一种用数字显示秒、分、时的计时装置,由于数字集成电路技术的发展和采用了先进的石英技术,它使数字钟具有走时准确、性能稳定、携带方便等优点。数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活带来极大的方便。在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系起来用于实际,来培养我们的综合分析和设计电路的能力。
关键词:电子钟;门电路及单次按键;琴键开关
目录
摘要 - 2 -
目录 - 3 -
1 设计要求 - 4 -
1.1 作品介绍 - 4 -
1.2 基本功能 - 5 -
1.3 扩展功能 - 5 -
2 工作原理 - 5 -
2.1 硬件设计原理 - 5 -
2.1.1 LCD1602液晶显示屏原理 - 6 -
2.1.2 LED模块原理 - 7 -
2.1.3 按键原理 - 7 -
2.1.4 单片机核心模块的时钟电路原理 - 8 -
2.2 软件设计原理 - 8 -
2.2.1 LCD1602液晶显示屏驱动 - 9 -
2.1.2 DS18B20数字温度器驱动 - 10 -
2.1.3 按键消抖与长按检测 - 11 -
3.使用说明 - 11 -
(1) 功能切换: - 11 -
(2) 时间校准: - 11 -
4.软件设计 - 12 -
5. 实验仿真 - 12 -
6.心得体会 - 13 -
7. 参考文献 - 13 -
附录:keil源码 - 14 -
1 设计要求
1.1作品介绍
电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。同时电子钟可以集成诸多功能,如秒表、温度测量、水平检测等功能。
本次单片机课程设计使用普中科技的A2开发板,如图1所示,板载单片机型号为AT89C52,采用C语言对其进行编程。
图1 普中A2开发板与课设成品展示图
1.2 基本功能
1、电子钟可显示时、分、秒;
2、可手动校时,待校时的时间闪烁;
1.3 扩展功能
1、可当作秒表使用;
2、可测量当前环境温度;
3、通过LCD1602液晶屏显示数据及特殊图形;
2 工作原理
2.1 硬件设计原理
硬件设计基于普中A2开发板,LCD1602接口、DS18B2O、独立按键模块、LED模块与单片机核心模块的电路连线如开发板原理图所示,开发板原理图见附件1,模块的逻辑关系如下图所示。
2.1.1 LCD1602液晶显示屏原理
图2 LCD1602液晶屏
LCD1602液晶屏实物图片如图2所示,LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成,其电气特性如图3所示。
显示容量 16×2个字符
芯片工作电压 4.5~5.5V
工作电流 2.0mA(5.0V)
模块最佳的工作电压 5.0V
字符尺寸 2.95mm×4.35mm(宽×高)
图3 LCD1602电气特性
图3 LCD1602接口
由图3所示的LCD1602接口图可知,LCD1602液晶屏由板载5V电压供电;VO引脚连接可调电阻,因此可以通过调节电阻阻值大小控制背光亮度;LCD RS、LCD WR、LCD EN分别连接单片机的P2.6、P2.5、P2.7,控制数据与命令的传输;LCD D0~LCD D7连接单片机P0口,作为单片机与模块之间的数据传送通道。
2.1.2 LED模块原理
图7 LED模块
由图7可知,LED模块由8位共阳极发光二极管,串联限流排阻,阴极连接单片机P2口组成。当单片机P2口的某一位输出低电平时,该位二极管点亮。
2.1.3 按键原理
图8 独立按键模块
由图8可知,4位独立按键K1K4分别连接单片机P3.1P3.3,只有按键按下时读引脚才可以得到高电平1。因此可以通过对引脚值电平进行分析,进而判断有无按键按下。
2.1.4 单片机核心模块的时钟电路原理
图9 单片机核心模块
单片机时钟信号的产生采用内部震荡方式,外接12MHZ晶振,得到频率为12MHZ的时钟信号。在AT89C52芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。把放大器与作为反馈元件的晶体振荡器和陶瓷电容相连,就构成了自激振荡器。
2.2 软件设计原理
电子钟上电后,延时10ms后等待外围设备状态稳定,初始化LCD1602,在用户自定义RAM区写入字符模型数据,在开机初始界面显示字模图形。启动计数器T0,每20ms进入中断一次,为其它功能的实现提供基准时间,如进行计时,进行温度数据的读取,在主函数中会循环检测按键,判定是否有按键按下,若有按键按下则进行相应操作,如功能切换,时间调整等。
时间计数值为长整型数据存储,对其进行相应的操作可以得到时分秒,从00:00:00至23:59:59循环计数。秒表每10ms计数一次,对计数值进行处理,将其在液晶屏上显示。对DS18B20数字温度器读寄存器得到的温度值进行分析与处理则可得到当前的温度。
2.2.1 LCD1602液晶显示屏驱动
图10 LCD1602操作时序
LCD1602读/写数据/命令的时序如图10所示,单片机与其通讯应满足其要求,查找芯片手册中对应的寄存器地址与操作提示可以实现LCD1602的功能。
2.1.2 DS18B20数字温度器驱动
图11 DS18B20操作时序
主机和从机通信使用单总线,即使用单线进行数据的发送和接收。首先需要判断总线上是否存在设备,确定有设备存在后在进行读/写操作,查找芯片手册中的寄存器地址与操作提示可以设置温度检测精度与温度值读取。
2.1.3 按键消抖与长按检测
图12 按键抖动示意图
当按键按下时,与按键相连线上的电压会波动,如图12所示,可能会在5V TTL电平阈值附近波动,如果程序只是对电平跳变进行计数,则可能会在按键按下一次时记录很多次,因此我们需要对按键进行消抖,同时对低电平时间进行计数,进而判断是短按还是长按。
3.使用说明
使用K1、K2、共2个按键
(1)功能切换:
单击K1,用于切换时间
(2)时间校准:
长按K2 进入/退出时间调整菜单,当菜单为时间调整时,单击K3 切换选择时/分/秒进行调整,待调整的时间会闪烁,单击K1,当前调整的时间值+1,单击K2则-1。时间调整完毕后,长按K2保存当前时间值,LED灯闪烁一次时,则表示校时成功。
菜单描述
4.软件设计
5.实验仿真
6.心得体会
在课程设计,将理论用于实践,实践又将丰富理论,对单片机的掌握更加深刻,收获颇丰。在制作过程中也遇到了许多问题,如LCD1602因为操作时序不正确导致无响应,因为清屏指令不合适造成屏幕闪烁明显;对读取DS18B20的高8位和低8位数据进行整合处理时遇到的难题;按键单击与长按复用功能的实现,消抖的细节处理等。通过查找CSDN与B站上的资源,与同学交流,问题最后得到了解决。但由于自己能力有限,做出来的成品只能尽自己所能做到最好。
单片机的型号千千万万,随着时代的发展,单片机更新迭代,只有掌握了基本的单片机原理与学习方法,有了坚实的基础才可以对任何单片机的开发水到渠成,应一步一步慢慢来。
国产MCU的崛起仍是我们的期望,期待那一天的到来,等到那一天我们发现国产MCU也可以在国际上掷地有声。
- 参考文献
[1]余发山 王福忠.《单片机原理及应用技术》.中国矿业大学出版社.2008
[2]彭伟.《单片机C语言程序设计实训》电子工业出版社.2010.
[3]杨凌霄.《微型计算机原理与应用》.中国电力出版社2003
[4]李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,1998
[5]李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994
[6]阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989
[7]DS18B20数据手册
附录:keil源码
#include <reg51.h>
sbit key1 = P1^0;
bit flag1s = 0;
bit KeySta = 1;
unsigned char hour = 20;
unsigned char minute = 30;
unsigned char second = 00;
unsigned char mode = 0;
void FreshTime();
void TimeInit();
void IntInit();
void InitLedBuff();
void keyscan();
unsigned char code LedChar[] = { //¹²ÒõÊýÂë¹ÜÏÔʾ×Ö·ûת»»±í
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00,0x40};
unsigned char LedBuff[8] = { //ÊýÂë¹ÜÏÔʾ»º³åÇø
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
void main()
{
TimeInit();
IntInit();
InitLedBuff();
while(1)//ÏÔʾÄÚÈÝ´¦Àí
{
if(flag1s&&!mode) //ʱ¼äÏÔʾģʽ
{
flag1s = 0;
FreshTime();
}
else if(mode == 1) //У׼·ÖÖÓ
{
LedBuff[0] = 17;
LedBuff[1] = 17;
LedBuff[4] = 17;
LedBuff[5] = 17;
LedBuff[6] = 17;
LedBuff[7] = 17;//²»ÏÔʾ
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
}
else if(mode == 2) //У׼Сʱ
{
LedBuff[2] = 17;
LedBuff[3] = 17;
LedBuff[4] = 17;
LedBuff[6] = 17;
LedBuff[7] = 17;
LedBuff[5] = 17;//²»ÏÔʾ
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
}
else if(mode == 3) //У׼Íê³ÉÖØÐÂÏÔʾ
{
InitLedBuff();
mode = 0;
}
keyscan();
}
}
void InitLedBuff()//³õʼ»¯Ê±¼äµ½ÏÔʾ»º³åÇø
{
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
LedBuff[4] = second/10;
LedBuff[5] = second%10;
LedBuff[6] = 18;
LedBuff[7] = 18;
}
void FreshTime()//Ë¢ÐÂʱ¼äµ½ÏÔʾ»º³åÇø
{
second++;
if(second == 60)//½øλ
{
second = 0;
minute++;
if(minute == 60)//½øλ
{
minute = 0;
hour++;
if(hour == 24)
hour = 0;
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
}
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
}
LedBuff[4] = second/10;
LedBuff[5] = second%10;
LedBuff[6] = 18;
LedBuff[7] = 18;
}