一、数码管扫描介绍
这个实验是我们对GPIO输出功能的一个扩展,用GPIO驱动数码管进行动态扫描,达到显示数字的目的。本实验的硬件电路采用一个4位8段共阴数码管。
所谓“4位”指的是数码管上有4个子单元。每个子单元如下图所示。
所谓“8段”指的是每个子单元由8个发光二极管组成,如上图所示,八段分别为:A、B、C、D、E、F、G、DP。
数码管按照连接方式可以分为共阴数码管和共阳数码管。二者的区别在于每一位的8个发光二极管是阴极连接在一起还是阳极连接在一起。共阴数码管的阴极连接在一起,共阳数码管的阳极连接在一起。
共阴数码管的内部原理图如下图所示。
数码管的管脚图如下图所示。
由以上两个图可以看出,虽然4位8段共阴数码管中有32个发光二极管,但是数码管引出的管脚只有12个。首先是每一位的发光二极管的阴极连接在了一起,总共引出了4个阴极。其次,四位的名称相同的阳极都是连接在一起的一共有8个阳极。因此数码管只有12个管脚。由于数码管的这个构造,4位数码管使用相同的阳极,决定了要想在4位上显示不同的数字,必须采用扫描的方式来显示。
数码管扫描的方式是:先给阳极赋值需要显示的第一位的段码,然后令第一位的阴极为低电平,其余位为高电平,这样第一位有显示;经过一段时间之后,再向阳极赋值第二位的段码,然后令第二位的阴极为低电平,其余位为高电平,这样第二位有显示;同理来显示第三位和第四位。把显示的时间间隔调节到适当的值,由于人眼的视觉暂留现象,感觉4位数码管是同时显示的。共阴数码管显示数字和字母的段码如下图所示。
在本实验中,数码管的驱动电路的原理图如下图所示。
电路中采用4个三极管,对4位数码管的共阴极进行控制,当输入为高电平时,三极管导通,对应的阴极接地。
二、例程测试
在这个实验的例程中,采用ECT的输出比较功能进行定时,每隔5ms进入一次中断函数,对数码管进行扫描,中断函数的代码如下所示
interrupt void scan(void)
{
if(ECT_TFLG1_C0F == 1)
{
ECT_TFLG1_C0F = 1;
ECT_TC0 = ECT_TCNT + 1250; //设置输出比较时间为5ms
}
switch(single)
{
case 1:
CONT1 = 1;
CONT2 = 0;
CONT3 = 0;
CONT4 = 0;
DATA=shuma[data1];
break;
case 2:
CONT1 = 0;
CONT2 = 1;
CONT3 = 0;
CONT4 = 0;
DATA=shuma[data2];
break;
case 3:
CONT1 = 0;
CONT2 = 0;
CONT3 = 1;
CONT4 = 0;
DATA=shuma[data3];
break;
case 4:
CONT1 = 0;
CONT2 = 0;
CONT3 = 0;
CONT4 = 1;
DATA=shuma[data4];
break;
default:
break;
}
single +=1;
if(single == 5) single = 1;
}
在这段代码中,CONT1、CONT2、CONT3、CONT4为4位数码管的共阴极驱动三极管的控制端,高电平则相应的数码管阴极接地。single为标志位,表示的是显示哪路数码管。每个周期变换一次取值,对1~4位数码管进行扫描。shuma[ ]数组中保存的是数字对应的断码,DATA是数码管阳极对应的GPIO的数据寄存器,将断码赋值给相应的寄存器,就会显示相应的数字。data1~data4分别存储了需要显示的数字的数值。
程序的主函数如下所示。
void main(void) {
DisableInterrupts;
INIT_PLL();
initialize_ect();
INIT_port();
LEDCPU_dir=1;
LEDCPU=0;
EnableInterrupts;
ECT_TFLG1_C0F = 1;
ECT_TC0 = ECT_TCNT + 1250; //设置输出比较时间为5ms
for(;;) {
data1 = 1;
data2 = 2;
data3 = 3;
data4 = 4;
delay();
data1 = 5;
data2 = 6;
data3 = 7;
data4 = 8;
delay();
}
}
在主循环中,将data1~data4赋值为1~4或5~8,并延时。
将程序下载到单片机中,并执行,可以看到数码管显示1、2、3、4,过一段时时间显示5、6、7、8,然后又显示1、2、3、4,如此循环。