写点什么

【51 单片机】室友用一把王者时间,学会了去使用数码管

作者:泽En
  • 2022 年 3 月 11 日
  • 本文字数:5644 字

    阅读完需:约 19 分钟

【51单片机】室友用一把王者时间,学会了去使用数码管

Hello,大家好我是泽 En,一起共同学习,多多指教(●'◡'●)

🎁 数码管介绍

数码管相比较之前的按键和 LED 灯的内容稍微复杂一些,操作更加难一点♦

数码管位置:在单片机的最角的地方、八个型号的显示器件♦还有 138 译码器和右边的 74C595 存储器都是属于数码管操作这些的东西♦

数码管英文:Nixie tube

LED 数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成"8"字器件♦

应用:数码管的价格由于相对便宜,在电器特别是家电领域应用极为广泛,空调、热水器、冰箱等等。绝大多数热水器用的都是数码管,其他家电也用液晶屏与荧光屏♦



🎁 数码管的分类

  1. 数码管分 共阳数码管 和 共阴数码管♦

  2. 数码管其实就是 8 个段的发光二极管,只点亮其中的几个段即可显示出数字或字母用来表达信息♦

  3. 共阳数码管:把 8 段 LED 的正极并在一起作为公共端连接在 5V 上(共阳极),然后 8 个 LED 通过单片机的 8 个 IO 端口输出高低电平使其决定点亮哪几个段♦

  • 八段 LED 数码管

  • 分为共阳极及共阴极,共阳极的七段数码管的正极(或阳极)为八个发光二极管的共有正极。其他节点为独立发光二极管的负极(或阴极)♦

  • 使用者只需把正极接电,不同的负极接地就能控制七段数码管显示不同的数字,共阴极的七段数码管与共阳极的只是接驳方法相反而已,同样根据上面所说的 LED 数码管分类方法,我们可以知道还有下面几种较常见的类型♦

  • 九段 LED 数码管

  • 相较七段 LED 数码管,该类更多用在数码手表和传呼机上♦

  1. 按显示位数分类

  2. 按能显示多少个“8”可分为 1 位、2 位、3 位、4 位和多位 led 数码管

  3. 按发光二极管单元连接方式分类

  4. 按发光二极管单元连接方式分为共阳极数码管和共阴极数码管,共阳极数码管是指将所有发光二极管(LED)的阳极接到一起形成公共阳极(COM)的数码管。共阳极数码管在应用时,将公共阳极 COM 接到+5V



🎁 数码管的引脚定义

🎆 一位一体

这种①位的数码管,它就是由个 LED 灯组成的♦

那么这⑧个 LED 灯是怎么去连接的呢?在上述图片的右边当中可以看到。右边其实就是 LED 灯的连接方式,总共有两种连接方式!在上述图片当中它们的⑧个 LED 灯****阴极都连接到了一个端口上,这种方式就叫做共阴极连接!下面图中它们⑧个 LED 灯****阳极都连接到了一个端口上,这种方式就叫做共阳极连接!

那我们在看到这图上的左下角还定义了这个段的一个名称。首先它嘴上面的 LED 数字都起好了名字了分别是:A、B、C、D、E、F、G、DP💨这个断码加起来就是⑧个,正好和我们的①字节 = ⑧位 刚好相互对应的♦

  • 还有一个图是引脚的定义!在③号引脚上连接的是正极,在⑧号引脚上连接的是负极。 引脚的定义图是按照 "就近原则" 来的♦

那我们要在数码管上显示数字""那怎么办呢?很简单我们把段码:A、C、D、E、F、G、都点亮即可,然后让其它的全部熄灭!那么它显示的就会是 "⑥"。 首先我们点亮,我们肯定要先把这个共阴极公共端需要接地,接地那么就是给我们这个数据 "零" 或者是低电平, 那么它的这个公共端阴极接到了这个的负极上。那么首先就达到了第一个条件了,它在共阴极上负极接上负极当我们负极接好之后,这个就叫做位选 ,我们要把它选中它才能够亮,如果有多个点亮的话那么就控制它多个位选 端。 那么如果是共阳极的话那么我们是公共端VCC断码就是低电平"0" 才会点亮(这个数据就是操作我们共阳极的数码管显示)♦



🎇 四位一体


这种就是④位的数码管,它就是由④*⑧个 LED 灯组成的,在开发板上也是④位一体的。在单片机上总共有两个刚好是⑧个数码管

那么这个④位一体的数码管是如何连接的?首先它也是具有一个引脚的序号。如上图所示在角,总共有 12 个引脚。右边也是有种的连接方式,在上面是共阴极连接,下面是共阳极连接♦

那我们对比下①位的数码管,就是多分出③个,它们的公共端是单独分出来的。然后,它们的断码就是全部的连接在了一起(A 段、B 段、.....DP 段)♦

💥那么我们想到第三位数码管显示数字的话,那么我们这么样才可以实现呢?首先,我们在位选(公共端)当中给第三位数码管给上"0"低电平,再给①、②、④上的位选给上"1"高电平 因为是共阴极。所以给低电平就可以让 位选 点亮。那么这就是只有第三个才会点亮,亮的前提是什么呢?位选 接上相应的数据,在'B'、'C'中给上数据 '1' ,其余的全部给上 '0' ♦****



🎁 数码管原理图


  • 数码管138 译码器都是用来控制数码管显示的♦

COM 就是公共端,这个数码管的就是共阴极的数码管。首先我们要点亮的话我们就要把它的公共端给选中。如果点亮第三个数码管的话,那么就把这第三个数码管选中 "0" ,其它的公共端都选中 "1" 。 那么如果想要给数码管数据的话,那么就给数码管下面的段码给"1",如果想让第三位数字①的话,就把 B、C 给上①,其它的都给上"0"♦

那么这里接上的网络编号 (LED1~LED8) 都是接到 138 译码器上的输出端 , 那么 138 译码器是什么工作原理呢?在这里解释一下:我们现在的目的是使得它的输出端输出为"0",剩下的全部输出"1"。那么这个 138 译码器正好可以实现这一个功能,并且还可以把③(P22、P23、P24) 个端口变成⑧个端口来控制的!左边的 A、B、C、是输入端(正极) ,右边这个 Y0~Y7 是输出端(负极) 💨 然后这个芯片需要接电源 VCC 上面的就是,下面就是它的电源负极 GND脚的③个引脚叫做它的使能端:相当于一种开关,如果使能电平有效的话,它就是可以进行工作的,如果无效的话它就不会进行工作♦

138 译码器左上角的个引脚上(P22、P23、P24),C 是高位、B 在中间、A 是低位。 按照顺序也就是 — C B A。从而我们这个 138 译码器从而也被称作是 "③⑧线" ,好接下来就是怎么样去使用:其实这里的作用是让数码管的哪一位可以进行显示❗❗❗❗如果假设(P24、P23、P22) C B A ,把高低位进行排序之后,二进制转换为十进制数对应着输出端(Y0~Y7), 那么假设 C B A:0 0 0 = Y0, 从而:LED1 是可以被允许显示的,因为这里 "0"输出端(低电平)(共阴极)才能让公共端 LED1 数码管允许显示,其它的 7 个都是不被允许的!如果是:0 0 1,那么转换成十进制数字就是:Y1 对应着 LED2,那么这里就是 Y1 是有效的值,Y1 输出给上 "0" (低电平)♦

总结:下来就是我们只要给上 CBA 的数据,然后用二进制转换成十进制的数据。对应着 Y 的引脚,然后再对应 LED 的引脚上,对应到了哪个 LED 给上输出端"0",那么这个 LED 就是有效位的数码管了♦



🎆 74HC595

74HC245 这个芯片有什么作用呢?解:这个芯片被称之为双向数据缓冲器这个芯片的作用,用来进行数据缓冲( 提高驱动能力 ) 的。那么缓冲这个是什么意思?

假设我们给上二进制,就从 A0 到达 B0 这是连接的关系,DIR 如果接的是高电平(1) 那么就能把左边的数据接到我们右边的数据上。电容(100nf ) 在这里的作用是:芯片的供电更加稳定叫做电源滤波,然后电阻的哪些东西是位一体的排阻,电阻的阻值是 100R(Ω) 作用:同样跟 LED 灯是一样的起到限流的作用,防止电流过大。好那么这些数码管的电路也都是总结完毕了!



🎇 总结:某一位显示一个数据呢?

  1. 138 译码器上控制个口(P24、P23、P22)

  2. 看你(LED1~LED8)哪一位输出 "0" 低电平选中

  3. 比如说 C B A = 0 1 1 = 3,也就是=Y3 = LED4LED4 就是有效的,允许显示数码管的,那么其它的数码管是不能被允许显示的、不是有效的。—— 位选

  4. 那么选中之后,就是给 P0 口段码的数据:假设给上数据,经过缓冲送到公共端的段码端。那么,送到段码端就会显示数码管相对应的数字!注意:P0 口给上数据是从高位到低位给上段码端的。—— 段选

  5. 就相当于两步骤:1、选中 P2   2、给段码数据 P0



🔎 C 语言数组

C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量♦

数组的声明并不是声明一个个的变量而是一个集合♦



🎆 数组定义

  • 类型说明符 数组标识符常量表达式


  1. 类型说明符:表示数组中所有元素的类型☑

  2. 数组标识符:表示该数组类型变量的名称,命名规则与变量名一致☑

  3. 常量表达式:定义了数组中存放的数据元素的个数,即数组长度。例如:arr[10] ,10 表示数   组当中有 10 个元素,索引(下标)从 0 开始,到 4 结束☑

例如:定义一个数组:

int arr[10] = {0,1,2,3,4,5,6,7,8,9};

在数组 arr[10] ****中只能使用 [0~9] ,不能访问 arr[10] ,若使用就会出现下标越界错误

注意:当数组不完全初始化也就是当数组元素比小标的值小的话,默认为 0 ☑


🔍 C 语言子函数


C 语言的库函数在编写的时候是可以直接调用的,比如 printf 输出函数。而用户自定义函数则必须由用户对其进行定义,在其函数的定义中完成函数所特定的内容功能,这样才能被其他函数调用♦



🎇 函数定义

  • 返回类型    函数名称(参数列表)

  • {

  • 函数体(函数实现特定功能的过程)

  • }

返回类型:一个函数可以返回一个值。返回类型 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,返回类型 是关键字 void

函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名

参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数

函数主体:函数主体包含一组定义函数执行任务的语句



🎁  点亮第③位数码管显示⑥

#include <REGX52.H>
int main(void){ //显示数码管的位置 P2_4=1; P2_3=0; P2_2=1; while(1) { //显示数码管的数字 P0=0x7D; }}
复制代码

那么如果我们要第位显示数字的话该怎么办?很简单把 P2_4=1;P2_3=0;P2_2=0;

LED 会亮的原因是因为引脚冲突这个不需要去管它。



🎁 静态数码管显示

#include <REGX52.H>//                          0    1    2    3    4    5    6    7    8    9unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//Location:数码管的位置; Number:显示数码管的数字【高电平点亮段码】 void Nixie(unsigned char Location,Number){ switch(Location) //位码端输出 { case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break; } P0 = NixieTable[Number]; //P0接收数码管中的数字}int main(void){ Nixie(2,2); while(1) { }}
复制代码

这段代码比上面的代码更加的复杂,因为这段运用到了数组和子函数的功能!大家仔细的去思考一下这数组和组函数的用法!


🎁 动态数码管显示

nclude <REGX52.H>
//数码管段码表unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//延时子函数void Delay(unsigned int xms){ unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); }}
//数码管显示子函数void Nixie(unsigned char Location,Number){ switch(Location) //位码输出 { case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break; } P0=NixieTable[Number]; //段码输出 Delay(1); //显示一段时间 P0=0x00; //段码清0,消影}
int main(void){ while(1) { Nixie(1,1); //在数码管的第1位置显示1// Delay(20); Nixie(2,2); //在数码管的第2位置显示2// Delay(20); Nixie(3,3); //在数码管的第3位置显示3// Delay(20); }}
复制代码


那么在这里解释下数码管的消影就是比方说:

当我们要显示数码管的时候首先要:位选 段选、还要显示的话就还要 位选、段选,循环。

那么这样就会出现问题:首先是选择"位选端"给上低电平,然后是段选给上数据,然后给上下一位位选的数据。但是:由于我们单片机的速度是很快的,在段选到下一个位选之间就会出现问题。我们选中下一位这个时刻很短的时间内,上一个数据就会串到下一个数据。因为它们是挨着一起的,我在选中下一位之后 上一位的数据自然是会直接过来的。这样就会显示出数据的串位的问题了!

那么我们应该怎么避免这个问题?那我们就需要在上一个段选端给清零这样即使到下一位它也不会对上一位产生影响!因为以及清零了。所以在子函数上需要优化下,显示玩之后我们首先要延迟 1ms 这个是为了能让程序更加稳定显示 并且 进行清零!



🎁 数码管的驱动方式


静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个的单片机 I/O 口进行驱动,或者使用如 BCD 码二-十进制译码器译码进行驱动。

  • 静态驱动的优点是编程简单,显示亮度高,缺点是占用 I/O 端口多。

数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的 8 个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极 COM 增加位选通控制电路,位选通由各自独立的 I/O 线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是哪个数码管会显示出字形,取决于单片机对位选通 COM 端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的 COM 端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为 1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的。

  • ​​​​​​动态驱动的优点是能够节省大量的 I/O 端口,而且功耗更低。缺点是花费 cpu 占用时间,编程较为复杂。



发布于: 2022 年 03 月 11 日阅读数: 23
用户头像

泽En

关注

好像没有😅 2022.01.29 加入

CSDN嵌入式领域新星创作者、2021年度博客之星物联网与嵌入式开发TOP5、2022博客之星TOP100 掘金创作者

评论

发布
暂无评论
【51单片机】室友用一把王者时间,学会了去使用数码管_3月月更_泽En_InfoQ写作平台