第三单元简易数字钟的设计数字钟是一种用数字显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显示直观、无需机械传动等优点。
因而得到了广泛的应用。
小到人们日常生活中的电子手表,大到车站、码头、机场等公共场所的大型数字电子钟,数字钟到处可见。
在数字电路的学习中,已经学习过用计数器芯片搭建数字钟。
51单片机内部集成了定时器/计数器,这为构建数字钟带来了方便。
在本单元中,学习如何用51单片机来构建一个功能数字钟。
【任务要求】➢在6个数码管上显示时、分、秒,共6位数字。
➢通过单片机内部定时器控制走时,走时准确。
➢系统有四个按键,功能分别是调整时间,加,减,确定。
在按下调整键时候,显示“时”的两位数码管以1 Hz 频率闪烁。
如果再次按下调整键,则“分”开始闪烁,“时”恢复正常显示,依次循环,直到按下确定键,恢复正常的显示。
在数码管闪烁的时候,按下加或者减键可以调整相应的显示内容。
按键支持短按和长按,即短按时,所修改的数字每次增加1或者减小1,长按时候以一定速率连续增加或者减少10。
【学习知识点】➢数码管的原理,驱动程序的实现。
➢51单片机内部定时器的原理及应用➢独立按键的原理及程序的实现。
【内容安排】第一节:数码管显示原理及应用实现第二节:独立按键检测原理及应用实现第三节:计时的原理及实现第四节:基于定时器的程序改进第五节:数字钟的构建第一节数码管显示原理及应用实现1.1 数码管显示原理数字钟要把时间显示到数字显示装置上,常用的数字显示装置有数码管、液晶、LED、CRT显示器等。
在单片机系统设计中,LED数码管是最基本的显示装置。
在数字钟的设计中我们用数码管对中的小时、分和表来进行显示。
LED数码管能显示各种数字或符号,由于它具有显示清晰、亮度高、寿命长、价格低廉等特点,因此使用非常广泛。
图1.1是几个数码管的图片:a图为单位数码管, b图为双位数码管,c图为四位数码管。
a 单位数码管b 双位数码管c 四位数码管图1.1 数码管图片那么数码管是如何的工作呢?还记得我们小时候玩过的“火柴棒游戏”吗,几根火柴组合起来,可以拼成各种各样的图形,数码管实际上就是利用这个原理做成的。
图1.2 单个数码管引脚标号,共阴和共阳的内部连接图单个数码管由8个发光二极管组成,其中7个长条形的发光管排列成一个“日”字形,我们称之为“段”,另一个圆点形的发光管在数码管的右下角作为小数点用,图1.2中的a 图是数码管的段标号以及外接引脚排列图,由图可以看出,单个数码管共有10个引脚,其中8个发光二极管的一端分别与数码管的8八个引脚相接,8个发光二极管的另外一端汇集在一起,称之为公共端,与数码管上下排引脚当中的那个引脚相连,称之为“公共端”。
公共端既可以接地,也可以接高电平。
公共端接地的数码管,是将发光二极管的阴极连接在一起接地,点亮数码管,各段需加高电平,称之为“共阴极数码管”;公共端接高电平的数码管,是将发光二极管的阳极连接在一起接高电平,点亮数码管,各段需加低电平,称之为“共阴极数码管”;图1.2中的b图和c图分别是共阴极数码管和共阳极数码管内部原理图。
1.2 单个数码管的控制我们以共阴极的数码管为例,先介绍如何控制一个8段数码管显示“0”-“F”16个数字或数字。
例1.1 单个数码管显示“0”-“F”1)硬件电路设计图1..4 单个LED数码管控制电路图1.3 单个数码管显示控制电路由于51单片机I/O高电平驱动能力有限,故在数码管与单片机之间串入锁存器74HC573,增加段的驱动能力,段限流电阻330Ω。
2)软件设计为了获得“0”-“F”16个不同字符,数码管各段所加的电平不同,因此I/O口输出的编码也不同。
因此首先要建立一个编码表,见表3.1。
表3.1 LED数码管字型字段编码表有了字型段码对照表,就可以用软件的方式进行8段码的译码。
如要显示字型“1”,P0输出值为0x06;显示字型“2”,P0口输出值为0x5B。
#include<reg51.h>#define uchar unsigned char#define uint unsigned int#define port_seg P1uchar code seg_7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F的字码放在数组中,数组名前面的code表示把数组的元素放在Flash中,而不是//RAM,这样可以节省RAM的空间。
//************************************************************************ // ms延时子函数//************************************************************************ void delayms(uint xms)//1ms的延时函数{uint i,j;for(i=0;i<112;i++)for(j=0;j<xms;j++);}//************************************************************************ // 主函数//************************************************************************ void main(void){uchar count;while(1) //定义循环变量{for(count=0;count<16;count++) //16次循环{port_seg=seg_7[count]; //从数组中取段码值赋给P1口delayms(1000); //间隔1s}}}讨论区:(1)限流电阻可以像图1.4那样接么?在图1.4中,限流电阻接在数码管和地之间,而不是接在锁存器与数码管之间,合理的选取电阻的阻值,可以实现数码管的点亮,而且只用了一个电阻,节省了电路的成本。
看起来是完美的方案,但是在实际调试的时候,我们会发现显示不同的数值,数码管的段亮度不同。
比喻说:显示”8”,亮度较低,显示”1”。
亮度较高,这是为什么呢?原因在于,只接一只电阻,各段电流和是一定的,当数码管段显示”8”的时候,7段全亮,那么每一段的电流就只有总电流的图1.3 只接一只电阻1/7,而如果显示”1”,那么每一段的电流为总电流的1/2,显示不同数字或者字符,段电流不相等,所以亮度也不同。
所以这种电阻的接入方法是不合理的。
(2)如何来识别数码管的引脚1.3 多位数码管的显示一个LED数码管只能显示一位数字,一般在系统中经常使用多个LED数码管,如要显示时间、温度、转速等等。
在上面一位数码管控制显示的简单例子中,我们可以看到,一个数码管要使用51单片机的8个I/O口来输出段码,当使用多个数码管的时候,显然采用这种控制方式有些问题,因为51单片机不能提供太多的I/O控制引脚。
多个数码管的显示驱动系统的实现,有多种不同的方式可以采用,而且在硬件和合软件的设计上也是不同的。
多个LED数码管显示电路按驱动方式可分为静态显示和动态显示两种方法。
采用静态方式显示时,除了在改变显示数据的时间外,所有的数码管都处于通电发光状态,每个数码管通电占空比为100%,静态显示的优点:显示稳定,亮度高,程序设计简单,MCU负担小,缺点是:占用硬件多(如I/O口、锁存电路等),耗电量大。
图2.19 是4个共阳极数数码管静态显示时的连接方式与显示状态,当单片机系统中使用静态数码管显示时,需要在每一个数码管上添加一个锁存器,当需要某个数码管显示其他内容时,只需要修改与其相连的锁存器的值即可。
而所谓动态显示方式,就是一位一位地轮流点亮各个数码管。
对于每一位数码管而言,每隔一定时间点亮一次,所以当扫描的时间间隔足够小时,观察者就不会感觉到数码管在闪烁,看到的现象就是所有数码管在一起发光(同看电影的道理是一样的)。
在动态显示中,数码管的将不仅仅由导通时电流的大小决定,而且还跟每一位点亮的时间和扫描周期这两个因素有关。
动态显示的优点:占用硬件资源小,耗电量小。
缺点是:显示稳定性不够好,亮度低,程序设计相对复杂,MCU负担过重。
为了减轻MCU的负担和编程的复杂性,同时简化外围电路,还可以使用专用的数码管控制器件。
图2.20 4个共阴极数码管动态显示时的连接方式与显示状态1. 使用串行传送数据的静态显示。
(1)硬件设计在静态显示的描述中,每位数码管都需要接一个锁存器,MCU把要显示的数据送给锁存器,锁存器锁存器之后再送给数码管,这里采用了移位寄存器74HC595来驱动8位静态数码管,74HC595末级带有锁存器,同时可以实现数据的串行传输,节省了I/O口。
图式串行传送数据的硬件电路图。
图设计中将八片八位串行输入/并行输出移位寄存器74HC595依次串接,第一片74HC595的DS端接到MCU的数据输出端P2^7,其他的74HC595的DS端分别接前一片的Q7’端,所有的74HC595的sTcp和sHcp分别相接到一起与MCU的P2^6和P2^5相连(sTcp是数据的移位脉冲,sHcp是存储器使能端)。
在经过sTcp时钟线64个脉冲后,要显示的8个字符并没有在8个数码管上显示,而是存储在移位寄存器内部的存储器中,然后再经过一个sHcp的脉冲,数据才会在8个数码管上显示,最先发送的显示字符段码将显示在最右边。
在这个电路中,硬件上使用了8片8位串行输入/并行输出移位寄存器74HC595串接,占用了MCU的3个I/O口,,硬件开销大,软件的实现比较简单,MCU只需把显示的内容一次性输出即可,如果显示内容没有变化时,MCU是不需要对显示部分进行任何操作的。
(2)软件设计#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit ds=P2^7;sbit sh_cp=P2^6;sbit st_cp=P2^5;uchar code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; //共阴数码管段码void seg595(uchar num){ uchar i,seg_num;seg_num=table[num];for(i=0;i<8;i++){ sh_cp=0;ds=seg_num&0x01;sh_cp=1;seg_num=seg_num>>1;}}void main(void){st_cp=0;seg595(1);seg595(2);seg595(3);seg595(4);seg595(5);seg595(6);seg595(7);seg595(8);sh_cp=1;while(1);}2. 数码管动态显示设计(一)采用数码管动态扫描显示方式,可以节省硬件电路,但软件设计相对复杂。