一、数码管电路分析
数码管,其实就是将8个LED摆成了一定的形状。我们控制不同的灯亮就可以让数码管显示不同的数字。一般会将数码管内部的8个LED阳极或者阴极接到一起,对应叫共阳极或共阴极数码管。这里找到了一份3位共阳极数码管的等效电路图大致如下所示:
给sel引脚高电平可以选择想让哪一位数码管亮;然后给阴极不同的电平,就可以控制它显示不同的数字了。可以看到这3个数码管相同位置LED的阴极引脚是连接在一起的,也就是说不可能让3个数码管同时显示不同的数字。
我们知道人眼是有余辉效应的,当我们点亮一位数码管之后,快速去点亮下一个数码管,人眼看上去是同时显示的。
我手中的开发板上是8位共阴极数码管。理论上要控制8位数码管需要16个单片机引脚,开发板上为了节约IO口资源,给位选和段选都接了锁存器,然后将锁存器的输入端口接到相同的IO端口,通过控制锁存器的使能端选择让哪一个锁存器工作。
锁存器,顾名思义,可以将电平状态锁存下来。即在使能状态下将需要写入的电平送给输入端口,在失能期间锁存器将保持这个状态直到下一次被改变。一般锁存器的响应速度都是很快的,为了避免数据紊乱造成显示异常,最好先将要写入的数据准备好,然后将使能端口打开再关闭。使能打开和关闭之间可以不加延时,这个间隔足够将数据锁存进去。
二、数码管驱动编写
先编写一位数码管显示的函数。在编写一个函数之前要先考虑清楚我这个函数要实现什么功能,需要什么样的传入参数,需要返回什么数据。这里我们考虑创建一个可以让任意位显示任意字符的驱动函数,显然我们需要将在哪一位显示和这一位需要显示什么字符传进去。
即:void play_smg_bit(unsigned char where,unsigned char led)
在函数内部,先进行位选,确定让哪一个数码管工作,然后将显示的数字对应的段选信号送进去。
当编写完一位数码管的显示,再来编写多位的显示,对于多位显示,可以考虑使用for循环来让数码管依次点亮。将不同的位选中对应的状态存储在一个数组中,然后通过for循环依次读取这个数组中的值,就可以控制不同的位选中。对于每一位要显示的数据,可以创建一个外部数组来存储,在进行段选的时候依次读取这个数组的值即可。
最终代码如下:
unsigned char code wei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
unsigned char led[]={0,0,0,0,0,0,0,0};
void play_smg_bit(unsigned char where,unsigned char led)
{
P0=wei[where];
wela=1;
wela=0;
P0=table[led];
dula=1;
dula=0;
}
void play_smg()
{
unsigned char i;
for(i=0; i<3; i++)
{
P0=wei[i];
wela=1;
wela=0;
P0=table[led[i]];
dula=1;
dula=0;
delay_ms(1);
}
}