前言
数码管是在日常生活中常见的一个显示模块,比如一些时钟上面,在对单片机的开发当中,我们也会经常使用到它来显示一些参数
这是我们数码管的一个模型图,它的显示面板我们可以看到是8个LED灯,通过8个灯发光的排列来做到数字的显示,这样来看,它就只能显示数字一类的东西,在显示上面比较鸡肋可能会有一点,但是他简单,便宜,所以用的还算比较广泛
我们来看板子上面的数码管的显示模块
这个板子的数码管的显示分为这两个模块完成的,我们看到标注,上面的图片是一个138译码器,下面的是数码管的实体显示部分,这里我们稍微介绍一下138译码器,大家知道怎么对应的就行了
138译码器
在这里,我们把138译码器当作一个IO口的扩展,我们看他的左侧,连接的三个IO口,右侧输出了8个端口,使用上面可以认为是“3位2进制数输入”到一个“8路互斥低电平的输出”,这里我们对应一下
输入 | 输出 |
---|---|
000 | 11111110 |
001 | 11111101 |
010 | 11111011 |
011 | 11110111 |
100 | 11101111 |
101 | 11011111 |
110 | 10111111 |
111 | 01111111 |
这样对应起来,3路的输入转成了8路的输出,这样可以扩大我们IO口的使用效率,在这个板子上面,我们可以通过3路的输出来控制8路的数码管的选择
数码管显示
数码管的显示我们可以看下面的图
数码管是由8个LED组成,8个LED的排列组合顺序由上面我们可以看到,对每个LED都做了标记,A到G显示数字,DP是小数点,这样我们就可以显示不同的数字,我们可以看到他的上下由两个共极,这两个共极可能会是,正极或者负极,连接LED,通过A到DP输入相对应的高低电平,点亮相对应的数码管来显示不同的数字
数码管共极的不同,可分为共阳极数码管和共阴极数码管,共阳极数码管的共极为高电平(1)选中数码管,每个LED为低电平(0)导通;共阴极数码管共极为低电平(0)选中数码管,每个LED为高电平(1)导通。不同LED点亮组合的方式的排列我们叫做断码,下面分别是共阳极和共阴极数码管的断码
断码
显示 | 共阳极 | 共阴极 |
---|---|---|
0 | 0xc0 | 0x3f |
1 | 0xf9 | 0x06 |
2 | 0xa4 | 0x5b |
3 | 0xb0 | 0x4f |
4 | 0x99 | 0x66 |
5 | 0x92 | 0x6d |
6 | 0x82 | 0x7d |
7 | 0xf8 | 0x07 |
8 | 0x80 | 0x7f |
9 | 0x90 | 0x6f |
A | 0x88 | 0x77 |
B | 0x83 | 0x7c |
C | 0xc6 | 0x39 |
D | 0xa1 | 0x5e |
E | 0x86 | 0x79 |
F | 0x8e | 0x71 |
以上就是共阳极共阴极数码管显示常见不同的字母数字不同的断码,我们在使用的时候,可以给他存一个数组使用,比如这样:
共阳极:unsigned char SMG_table[] = {0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e};
共阴极:unsigned char SMG_table[] ={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}
在使用的时候我们直接调用相对应的数组位即可
中途小结
上面我们说了一下138译码器以及数码管的显示方式
现在我们来看一下对应51开发板的使用,我们再看一下原理图
此模组共两个模块,一个138译码器,一个8个的数码管,他的使用的顺序大概是这样:单片机输入三路信号到138译码器,然后由138译码器分为8路信号,这8路信号来选择数码管(这里不是LED灯,这里容易混),选择数码管后,通过P0口的信号点亮对应的LED灯,做到数码管显示相应的数字字母。
数码管显示逻辑(代码)
在网上开源的相关课程,大多都会分为静态数码管和动态数码管的显示进行教学,其实这里总感觉没什么必要,大家想,数码管的静态和动态字面意思上面有什么区别,无非就是静态的数不变,动态的数码管显示的数会变,这里我们通过给她不同的断码即可做到,所以这里我们直接上代码,大家开可以参考一下,然后自己通过对P0口的断码的改变或者不变来改动一下代码
#include <REGX52.H>
unsigned char SMG_table[] ={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
void display(int a,num)
{
switch(a)//这里是一个switch语句,用来对应上面的138译码器的选择数码管
{
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 = SMG_table[num];//直接对P0口输入断码,显示相应的数字
delay(20);//延时消影,这里后面会相应代码
P0=0x00;//清屏
}
void main()
{
while(1)
{
display(1,2);
display(2,0);
display(3,2);
display(4,5);
display(5,0);
display(6,6);
display(7,0);
display(8,4);//显示为作者书写代码时的日期
}
}
这是数码管显示的一种方式,数码管的显示方式很多,大家可以自己根据逻辑写一下,后期我也会分享一些数码管的方式
延时
上面代码里面提到了一个延时的概念,这个应该在上节里面就说的,但是比较懒,没有写
延时的字面意思就是等待一定的时间,在代码实际运行的时候什么都不做,但是他可以在延时的时候一直运行它的上一条代码直到延时结束运行下一条代码,在这里数码管显示的时候,加入延时可以消除数码管显示的一些“影子”,大家可以实际把代码烧进去看一下这个“影子”是什么东西,下面看一下延时的代码,就是一个空的循环,什么都不执行
void delay(unsigned int num)
{
while (num--);
}
大家可以调用使用一下
数码管部分大概就这么多,这里是最基础的使用部分,一些扩展的使用大家可以根据代码去做相应的修改