前言:
本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记,在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。
引用:
51单片机入门教程-2020版 程序全程纯手打 从零开始入门_哔哩哔哩_bilibili
数码管显示:
【51单片机实验笔记】LED篇(三) 数码管的基本控制_51单片机数码管-CSDN博客
https://zhuanlan.zhihu.com/p/657909281
嵌入式硬件入门——74HC138译码器(三个IO实现8选1)-CSDN博客
51单片机(四):动态数码管的消影_数码管消影-CSDN博客
51单片机入门教程(3)——数码管显示学号_单片机_huy1n9-GitCode 开源社区
正文:
0. 概述
在淘宝上购买了江协科技51单片机开发板套件(普中科技STC51单片机A2型号),就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程,通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。
1. LED数码管的显示原理
LED数码管的简介:数码管是一种简单,廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件。
LED数码管的显示原理:
- 共阴极LED数码管
- 共阳极LED数码管
在如下截图里,共阴极/共阳极LED数码管的3和8号引脚都是地实际上是接在一起的。数码管的A,B,C,D,E,F,G,DP的和外部引脚是就近连接。
1位LED数码管的有8个外部引脚,
4位LED数码管的有12个外部引脚,8为引脚控制LED数码管显示的字符,4个引脚作为选择引脚控制哪个数码管显示。
2. 共阴极数码管驱动需要缓冲器(驱动器)
按LED的连接方式可以分为共阴极数码管和共阳极数码管。
- 共阴极:将LED的阴极连在一起称为公共阴极(COM)
- 共阳极:将LED的阳极连在一起称为公共阳极(COM)
共阴极需要单片机 IO 给高电平,对应的段(LED)才能点亮,而单片机的 IO 引脚电流输出能力不足,往往需要借助驱动芯片(如74HC245芯片)才可以点亮数码管。而共阳极只需要单片机 IO 给低电平,单片机的灌电流大于拉电流,故共阳极数码管应用更加广泛。
注:由于每段都是由LED组成,故实际电路中应该串联限流电阻,一般接一个8P排阻。
段选和位选
在数码管中有段选和位选两个概念,现阐释如下:
- 段选:针对单个数码管而言。选择要点亮数码管中 a、b、c、d、e、f、g、dp 哪些段。一般通过给 IO 引脚赋值实现。
- 位选:针对多位数码管而言。选择点亮哪个数码管。即控制COM端的高低电平。
仔细观察数码管的段选顺序,按 a、b、c、d、e、f、g、h 逆时针排列,依次对应字节的低位至高位。因此,我们可以给出共阴极数码管的字形码编码表。(有些字母不易表示,缺省)
字形码 | dp g f e d c b a | 十六进制 |
---|---|---|
0 | 0011 1111 | 0x3f |
1 | 0000 0110 | 0x06 |
2 | 0101 1011 | 0x5b |
3 | 0100 1111 | 0x4f |
4 | 0110 0110 | 0x66 |
5 | 0110 1101 | 0x6d |
6 | 0111 1101 | 0x7d |
7 | 0000 0111 | 0x07 |
8 | 0111 1111 | 0x7f |
9 | 0110 1111 | 0x6f |
A | 0111 0111 | 0x77 |
b | 0111 1100 | 0x7c |
c | 0101 1000 | 0x58 |
d | 0101 1110 | 0x5e |
E | 0111 1001 | 0x79 |
F | 0111 0001 | 0x71 |
G | - | - |
H | 0111 0110 | 0x76 |
I | 0011 0000 | 0x30 |
J | 0000 1110 | 0x0e |
K | - | - |
L | 0011 1000 | 0x38 |
M | - | - |
n | 0101 0100 | 0x54 |
o | 0101 1100 | 0x5c |
p | 0111 0011 | 0x73 |
q | 0110 0111 | 0x67 |
r | 0101 0000 | 0x50 |
s | 0110 1101 | 0x6d |
t | - | - |
U | 0011 1110 | 0x3e |
v | 0001 1100 | 0x1c |
w | - | - |
x | - | - |
y | 0110 1110 | 0x6e |
z | - | - |
如果是共阳极,其编码表刚好是共阴极的按位取反(~)。
其实可以看出,数码管对显示字母并不友好,一般用于显示数字,在电梯楼层显示,计算器显示应用广泛。
从上述一系列分析中我们得到,数码管相当于LED的堆叠,它对 IO 口资源的消耗是巨大的。如果要同时显示多个数字,除了采用芯片(如38译码器)来节约 IO 口,还可以采用不同的显示方式实现。数码管有两种驱动显示方式:静态显示和动态显示。
- 静态显示:即每个数码管的每一个段码都由一个单片机的I/O端口进行驱动。优点是编程简单,显示亮度高,缺点是占用I/O端口过多,这显然是致命的。
- 动态显示:利用人眼暂留效应,分时轮流控制 COM端(位选),每个数码管的点亮时间为1ms~2ms,因为频率很快,仿佛所有数码管都是同时点亮的,这即是动态的含义。优点的节省大量IO口,功耗低,缺点是亮度不及静态显示方式,但可以通过降低限流电阻的阻值来提高亮度。
3. 驱动芯片
我们需要清楚一点,单片机适合用于控制,它可以输入输出电平,但电流是很小的。或许单片机驱动单独一个LED是足够的,但当LED数量多起来时,它便无能为力了,更别提驱动大功率的灯泡或是电机了。
这些功率比较大的外设往往需要外接电源,通过驱动芯片来提供电流和能量,单片机提供信号指令。
使用138译码器和74HC245驱动器
- 74HC245驱动器(缓冲器)
- 74HC138译码器
3.1 74HC138译码器
使用74HC138译码器节省了单片机的IO口,使用单片机的3个IO口可以控制8个输出。
74HC138译码器,有A,B,C三个输入,Y0~Y78个输出,还有G1, G2A, G2B 三个控制引脚,当控制端如下电平配置G1=1,G2A=0,G2B=0时,74HC138译码器使能输出。
G1 | 1 |
G2A | 0 |
G2B | 0 |
74HC138译码器芯片上 Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, 引脚字符上面的横线表示低电平有效。 也就是说当 138译码器选中某个输出位的时候该引脚输出低电平,其它剩下的引脚输出高电平。
74HC138译码器真值表
嵌入式硬件入门——74HC138译码器(三个IO实现8选1)-CSDN博客
74HC138管脚定义及说明
管脚定义
管脚主要分为:输入
(A0、A1和A2)、输出
(Y0-Y7)、使能
(E1-E3)、电源
(VDD)和地
(GND)。
管脚说明
下表是74HC138所有管脚的功能说明
逻辑图
74HC138的逻辑图可以形象地展示其逻辑功能
,只有当E1=0,E2=0,E3=1
时,芯片才能被使能
,不然芯片不会有任何有效输出。
74HC138真值表
真值表
是在逻辑中使用的一类数学表,用来确定一个表达式是否为真或有效。H
代表高电平,L
代表低电平,X
代表随机电平(可高可低)
3.2 74HC245驱动器
因为单片机的高电平驱动能力弱通过的电流能力弱,单片机的低电平驱动能力强通过的电流能力强。
主要用于提升单片机 IO 口的驱动电流。一般 IO 口的输出电流为20mA,这个电流大小仅仅点亮一颗LED是没有问题的,但对于驱动数码管、点阵等多负载模块就力不从心了。
74HC245芯片可以将输出电流提升至70-80mA左右,具有8路输入和8路输出,可输出低电平高电平高阻态三态。
- 其中DIR引脚用于控制输入输出方向,高电平(A => B)、低电平(B => A)。
- OE为使能引脚,低电平输出有效。
3.3 课程使用普中51开发板电路原理图分析
课程使用普中51开发板电路原理图分析,从电路原理图看到 LE 接74HC245 的 DIR 方向控制引脚,DIR=1 时74HC245双向缓冲器输出方向为从A=>B,DIR=0时输出方向为从B=>A。在电路原理图中 LE 接 J21 跳帽引脚,通过跳帽把LE接到VCC 则 DIR=1, 74HC245的输出方向为从A=>B,这也是我们本次实验开发板需要的配置。
4. 数码管静态显示
根据可能使用的普中科技STC51单片机A2开发板的电路原理图,可以看到 P2_2,P2_3,P2_4 接到74HC138译码器的 A, B, C 三个输入引脚,通过P2_2,P2_3,P2_4 输出值可以控制选中8个数码管的那一个管显示。
P2_2 = 1,P2_3 = 0, P2_4 =1
A,B,C = 101(2进制) = 0x5 (16进制)
74HC138译码器的A,B,C输入0x5,则译码器的 Y5 输出引脚输出低电平,其它引脚输出高电平。因为此开发板使用的是共阴极数码管,当数码管位选信号为低电平时数码管亮。
P0口输出控制数码管的显示段码值。
#include <REGX52.H>
#include <INTRINS.H>
void main()
{
//ABC=0b101=0x5=选中Y5,连接LED6,从左往右数第3个数码管
P2_2 = 1;
P2_3 = 0;
P2_4 = 1;
//数码管段码
P0 = 0x3f;
while(1)
{
}
}
5.数码管动态显示
5.1 数码管动态显示
通过位选和段选的配合,实现了动态数码管的扫描显示。在每个显示周期内,位选依次选择每一个位,然后通过段选控制信号实现对选定位上每个段的控制。这种切换速度非常快,超过了人眼的分辨能力,从而使得多个位和多个段的数字看起来同时发光。
参考:
动态数码管的消影
需要注意的是,位选和段选的切换速度和同步是关键因素。切换速度过慢会导致数字闪烁或模糊,而同步不准确会导致扫描不全或错位显示。
同步:位选1-段选1、位选2-段选2、位选3-段选3。。。
不同步:位选1-段选1、段选1-位选2、位选2-段选2、段选2-位选3、位选3-段选3。。。
动态数码管的消影就是为了解决数码管显示过程中可能出现的残影问题(数码管位选、段选扫描不同步造成的)。当切换一个数码管的数字时,由于刷新频率有限,数码管的液晶分子需要一定的时间来重新排列,这可能会导致前一个数码管数字的残影留在屏幕上。消影的作用是在切换每个数码管之前,通过使数码管显示所有段选线都为高电平或低电平(由数码管的驱动方式决定—共阳极/共阴极),使得数码管的液晶分子重新排列,以消除残影,从而得到清晰的显示。
5.2 数码管显示残影
数码管的扫描显示的一个常见问题就是数码管显示的“残影”问题,需要对数码管扫描显示进行消影。例如,如下数码管快速动态扫描在在数码管位置8显示数字1,位置7显示数字2,位置6显示数字3。
#include <REGX52.H>
#include <INTRINS.H>
typedef unsigned char u8;
//共阴极数码管字形码编码
u8 code NixieTable[] = {0x3f,0x06,0x5b,0x4f,0x66, //0 1 2 3 4
0x6d,0x7d,0x07,0x7f,0x6f, //5 6 7 8 9
0x77,0x7c,0x58,0x5e,0x79, //A b c d E
0x71,0x76,0x30,0x0e,0x38, //F H I J L
0x54,0x5c,0x73,0x67,0x50, //n o p q r
0x6d,0x3e,0x1c,0x6e}; //s U v y
void Nixie(unsigned char Location, unsigned char Number)
{
switch(Location)
{
case 8: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
case 7: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
case 6: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
case 5: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
case 4: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
case 3: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
case 2: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
case 1: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
}
if(Number <= 9)
P0 = NixieTable[Number];
}
void main()
{
while(1)
{
Nixie(8,1);
//Delay(20);
Nixie(7,2);
//Delay(20);
Nixie(6,3);
//Delay(20);
}
}
下载到单片机开发板后,实际的显示效果如下,可以看到数码管数字显示出现篡位和残留,数字3显示在了第8位,位置5出现比较暗的数字2。这就是数码管动态快速扫描显示一个常见的问题,称为数码管显示“残影”问题。
5.3 数码管显示残影原因
为什么数码管快速扫描显示会出现“残影”?因为单片机执行速度非常快,在数码管同时显示多个数字单片机进行动态扫描的时,执行顺序是如下的:
位选 段选 位选 段选 位选 段选 位选 段选 位选 段选
问题就出现在这里,因为单片机的执行速度非常快,在第二次位选的时候,第一次的段选(段码)就篡到了第二次的位选选中的数码管位置,造成了数码管数字显示的篡位(残影)。
5.4 数码管显示残影消除
结论:想要实现动态数码管的“消影”,需要使用“延迟+断码清零”的组合。即“延迟+段码清零”或“延迟+段码清零+延迟”。
- 那么可能有人就要问了:“上述代码实现动态数码管的消影时,只使用延迟的方式也可以有效地减少或隐藏段码切换的瞬间亮灭,从而实现较为平滑的显示效果,那为什么还要进行段码清零呢?”
答:其实仔细观察就会发现,仅使用延迟的方式虽然能实现效果,但不该亮的断码管还是会有微弱的亮光的。但是由于期间只延迟了一段非常短的时间,超过了人眼的分辨能力,从而使得多个位和多个段的数字看起来同时发光,但并没有真正实现“消影”的效果。- 那么可能还有人要问:“上述代码实现动态数码管的消影时,只使用段码清零可不可以实现效果?”
答:当只使用段码清零时,会出现显示的数字亮度特别弱的情况,这还是由于代码执行过快导致的。
void Nixie(unsigned char Location, unsigned char Number)
{
switch(Location)
{
case 8: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
case 7: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
case 6: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
case 5: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
case 4: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
case 3: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
case 2: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
case 1: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
}
if(Number <= 9)
P0 = NixieTable[Number];
//数码管消影
Delay(1); //延时1ms让数码管显示,延时过短数字显示亮度较暗
P0 = 0; //共阴极数码管,p0=0 段码为0关闭LED显示
}
void main()
{
while(1)
{
Nixie(8,1);
Nixie(7,2);
Nixie(6,3);
}
}
6. 总结
本实验学习了STC51单片机数码管静态显示和动态扫描显示的原理,并认识了 74HC138 译码器和 74HC245 双向缓冲器(驱动器)的使用。
通过数码管的位选和段选(段码)进行快速扫描的方法实现了多个数码管数字同时显示,因为单片机执行速度很快数码管通过“位选+段选”快速的切换显示,由于人眼的视觉残留效应看起来就是多个数码管同时显示数字。
在数码管动态扫描显示中分析了数码管快速扫描中由于“位选 ” 和 “段选” 信号不同步出现的残影问题,并分析了动态数码管显示中残影消除的方法,即“延时+清零”的方法进行动态数码管显示的残影消除。
6.1 附加信息 Proteus 软件:
51单片机入门教程(3)——数码管显示学号_单片机_huy1n9-GitCode 开源社区
使用 Proteus 软件进行51单片机的布线模拟开发,练习布线使用不同的器件。
7. 结束
本文至此结束