一、数码管介绍
1、数码管分类:
静态数码管(单个,一位) 和 动态数码管(联排,2位、4位、8位)
开发板上数码管位置如图所示:
可以看到数码管就是显示器件,用来显示数字的
2、数码管定义:
是由多个发光二极管封装在一起形成“8”字形的器件
3、共阳极和共阴极数码管
一个数码管内部的8个LED是独立驱动的。如果8个LED的一端接在一起接到VCC上(负极分别接到单片机的不同引脚),这种接法就叫共阳极。
反之如果8个LED一端接在一起接到GND(正极就分别接到单片机的不同引脚)就叫共阴极。
两种接法都可以驱动数码管显示,但是一个是给予低电平才能亮,一个是给予高电平才能亮。总而言之,原理都一样,不管那一端默认接的是正极还是负极,只要通过程序控制另一端是低电平还是高电平(给0还是给1),使其电路完整就能点亮LED,进而获得自己想要的数字。
二、静态数码管:
1、根据原理图可知:
静态数码管一端默认为VCC(也就是高电平),所以要使静态数码管显示数字,只需要在其另一端(也就是J8引脚处给予低电平即可),同样可以看到,J8的8个引脚分别对应“8”字形的8个LED二极管(a、b、c、d、e、f、g、dp) ,所以也就是通过给予低电平来决定哪个LED灯亮进而显示出想要的数字
2、静态数码管编程示例
要想显示数字0,则需要除了g和dp以外的二极管发光,所以需要给予g和dp高电平,给予其他低电平(低电平给0 高电平给1),如下:
通过杜邦线将J8与P0一一对应连接:
注意:因为P0_7至P0_0是高位到低位,所以应该是从P0_7开始读起,也就是1100 0000,转化为十六进制为0xC0
代码如下:
#include <REGX52.H>
void main()
{
while(1)
{
P0 = 0xC0; //1100 0000
}
}
所以想要获得什么数字,只需要修改并查询所对应的十六进制是什么即可;
3、动态数字闪烁
如果想要得到动态的数字闪烁,只需要在循环中增加程序和延时功能即可,程序如下:
#include <REGX52.H>
void Delay(unsigned char xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main()
{
while(1)
{
P0 = 0xC0; //显示0
Delay(200);
P0 = 0xF9; //显示1
Delay(200);
P0 = 0xA4; //显示2
Delay(200);
P0 = 0xB0 ; //显示3
Delay(200);
}
}
三、动态数码管
1、原理图:
根据对静态数码管的解释,再看动态数码管就会简单简单一些,可以清楚递看到二者的区别,虽然说静态数码管驱动简单直接,且好编程,但是它每一个LED灯都需要一个端口,所以这才有了动态数码管,可以看到动态数码管8个a位LED灯全部接在一个引脚上(此板J6给1则亮,J1给0则亮)
2、动态数码管端口
数码管有2端:COM端和段码端
COM(共极)接单片机一个IO口,多个联排数码管的COM共同接一个IO端
静态和动态数码管本质区别是:静态数码管中只要给了段码数码管就一定工作(显示只取决于段码端),动态数码管中段码端给了段码值后还需要COM端配合才能点亮数码管。
简单来说:J1操控的是8个“8”字形,相当于总开关;而J6操控的是每一个“8”字形里面的LED灯亮灭情况,需要二者配合才能成功点亮某一个位置8并且显示数字。
3、动态数码管编程示例
想要在第二个位置显示数字0:
连线如下:两组杜邦线,一组连接J1和P0端 ,一组连接J6和P1端
程序如下:
#include <REGX52.H>
void main()
{
while(1)
{
P0 = 0xBF; //1011 1111
P1 = 0x3F; //0011 1111
}
}
供参考:0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F 分别是0-9的表示(针对P1端)
0x7F; 0xBF; 0xDF; 0xEF; 0xF7; 0xFB; 0xFD; 0xFE 分别是1-8的表示,决定第几个8字形亮(针对P0端)
4、动态数码管静态显示
新的问题来了,如果我想要指定某个位置的8显示某个数字,我就得重新再对重新进行修改,未免过于麻烦,所以想到使用数组和switch-case,将上面的参考数据全部装起来。
程序如下:
#include <REGX52.H>
int Number[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char Location,number)
{
switch (Location)
{ case 1 : P0 = 0x7F;break;
case 2 : P0 = 0xBF;break;
case 3 : P0 = 0xDF;break;
case 4 : P0 = 0xEF;break;
case 5 : P0 = 0xF7;break;
case 6 : P0 = 0xFB;break;
case 7 : P0 = 0xFD;break;
case 8 : P0 = 0xFE;break;
}
P1=Number[number];
}
void main()
{
Nixie(2,0); //只需要改变这里的两个数即可获得第几个位置显示什么数字,这表示第2个位置显示0)
while(1)
{
}
}
5、动态数码管动态显示
在以上基础,又如何实现流动的数字呢?只需要在循环当中增贴即可:
#include <REGX52.H>
int Number[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Delay(unsigned char 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 : P0 = 0x7F;break;
case 2 : P0 = 0xBF;break;
case 3 : P0 = 0xDF;break;
case 4 : P0 = 0xEF;break;
case 5 : P0 = 0xF7;break;
case 6 : P0 = 0xFB;break;
case 7 : P0 = 0xFD;break;
case 8 : P0 = 0xFE;break;
}
P1=Number[number];
}
void main()
{
while(1)
{
Nixie(1,1);
Delay(200);
Nixie(2,2);
Delay(200);
Nixie(3,3);
Delay(200);
Nixie(4,4);
Delay(200);
Nixie(5,5);
Delay(200);
Nixie(6,6);
Delay(200);
Nixie(7,7);
Delay(200);
Nixie(8,8);
Delay(200);
}
}
效果如下:
WeChat_20240218172716