数码管是一种非常普遍的显示器件,从本质上来说,它就是多个LED的组合题,下图是它的实物图和连接示意图(其中的数字是管脚号):
需要注意的是,根据二极管连接方式的不同,有共阴和共阳两种,所谓的共阴就是二极管的所有阴极连在一起,所谓的共阳就是二极管的所有阳极连在一起,不同厂商的数码管都会有自己的说明,当然,你也可以自己分别连接一下3和4到VCC和地,根据导通情况就可以判断数码管的类型了,上图中的数码管就属于共阳类型。
对于数码管而言,如果连接的管脚电平按照下面的顺序排列,则一个字节的电平组合刚好可以来驱动一个数码管,其顺序是:
(MSB) DP g f e d c b a (LSB)
其中的有效组合如下,如果要显示小数点,则需要取反最高位:
下面我们就可用使用mbed的数字输出来实现数码管的显示,我们这里给出的代码是用阳的数码管,其连接示意图如下:
下面是显示数字0的代码:
DigitalOut Sdp(p5);
DigitalOut Sg(p6);
DigitalOut Sf(p7);
DigitalOut Se(p8);
DigitalOut Sd(p9);
DigitalOut Sc(p10);
DigitalOut Sb(p11);
DigitalOut Sa(p12);
int main() {
Sdp=0;
Sg=0;
Sf=0;
Se=0;
Sd=0;
Sc=0;
Sb=0;
Sa=0;
}
显然,这样的处理方法是很麻烦的,其实我们前面已经说过,一个数码管的显示就对应着一个字节,那么能否让mbed直接通过多个管脚输出一个字节呢,答案是肯定的,这就是BusOut对象,它可以同时设定8个管脚的值,同DigitalOut一样,它也对应有BusIn和BusInOut对象,具体对象方法被定义在相应的.h文件当中,我们这样主要说明一下BusOut的方法,具体描述如下:
BusOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
BusOut(PinName pins[16]);
BusOut构造函数,最多可以设定16个管脚,也就是说必要时可以同时控制16个管脚;
void write(int value);
输出Bus的值,它会同时改变构造函数设定的管脚值;
int read();
读取Bus的值,它会同时读取构造函数设定的管脚值,并返回整合后的int类型;
BusOut& operator= (int v);
BusOut& operator= (BusOut& rhs);
操作符重载,相当于write方法。
operator int();
操作符重载,相当于read方法。
利用上面的方法,我们就可以写出更加简单的数码管显示代码了。下面的代码使数码管从0-9循环变化显示:
BusOut display(p5,p6,p7,p8,p9,p10,p11,p12);
int main()
{
while(1)
{
for(int i=0; i<10; i++)
{
switch (i)
{
case 0: display = 0xC0; break;
case 1: display = 0xF9; break;
case 2: display = 0xA4; break;
case 3: display = 0xB0; break;
case 4: display = 0x99; break;
case 5: display = 0x92; break;
case 6: display = 0x82; break;
case 7: display = 0xF8; break;
case 8: display = 0x80; break;
case 9: display = 0x90; break;
}
wait(1);
}
}
}
显然,这样的代码看上去就简洁多了。在实际应用中,1个数码管显然是不够用的,如显示温度数据32.12,但如果每个数码管都像现在这样独立操作,即每个数码管都需要用到8个GPIO显示是不行的,所以多位数码管采用的是端口服用的方式,其实物图盒连接示意图如下(同样也用共阴共阳两种,这里给出的是共阴的,DG1控制的是最右边的):
丛上面的连接图可以看出,其实所有的段位控制都是相同的,但它只有对阴低位拉低的位有效,我们只要保证每次输出时只让一位数码管的阴极为低即可(如果共阳,则让一位数码管德阳极为高即可),我们这里使用的是共阴的四为数码管,其连接示意图如下:
给出的代码是还是循环显示的代码:
BusOut display(p5,p6,p7,p8,p9,p10,p11,p12);
BusOut dispcontrol(p13,p14,p15,p16);
int vcontrol=0xF7;//11110111;
int main()
{
while(1)
{
for (int j=0;j<4;j++)
{
dispcontrol=(vcontrol>>j);//0111,1011,1101,1110
for(int i=0; i<10; i++)
{
switch (i)
{
case 0: display = 0x3F; break;
case 1: display = 0x06; break;
case 2: display = 0x5B; break;
case 3: display = 0x4F; break;
case 4: display = 0x66; break;
case 5: display = 0x6D; break;
case 6: display = 0x7D; break;
case 7: display = 0x07; break;
case 8: display = 0x7F; break;
case 9: display = 0x6F; break;
}
wait(0.2);
}
}
}
}
运行完代码,感觉还是没有解决我们的问题,我们需要的是不同位显示不同的数值,而且是同时显示,那应该怎么办呢。实际上很简单,就如同看电影一样,只要我们变化的速度足够快,用户就感觉是同时在显示了,下面的代码显示的就是37.25。
BusOut display(p5,p6,p7,p8,p9,p10,p11,p12);
BusOut dispcontrol(p13,p14,p15,p16);
int main()
{
while(1)
{
//37.25
dispcontrol=0x07;
display = 0x4F; //3
wait_ms(1);
dispcontrol=0x0B;
display = 0x87; //7.
wait_ms(1);
dispcontrol=0x0D;
display = 0x5B;//2
wait_ms(1);
dispcontrol=0x0E;
display = 0x6D;//5
wait_ms(1);
}
}