摘要:针对传统 LED 显示屏显示复杂界面时 MCU 的选择范围很窄的问题,提出一种 LED 矩阵链接方法。该方
法采用 ULN2003A[1]阴极电流放大电路和 KID65783AP[2]阳极电流放大电路,介绍行扫描、列扫描和全扫描 3 种扫描
方式,并给出主程序流程图、中断服务程序流程图及其程序清单。实践结果证明:该设计大大减小了所需要的单片
机输出端口数,降低了设计成本,并已在空调产品控制器多个产品的显示屏设计上大量运用。
关键词:LED 控制;LED 矩阵连接;LED 显示屏
0 引言
目前,家用电器普遍采用 LCD 液晶显示屏,由
于液晶本身不会发光,必须使用背光源照亮画面,
在某些场合其亮度不能达到用户需要。而且 LCD 的
控制较复杂,需要专用控制芯片,或者需要带 LCD
驱动的 MCU,控制成本相对较高。所以,在显示界
面比较简单的场合,常采用 LED 作为显示屏。
LED 显示屏本身能发光,亮度自由调节,显示画面任意组合,还可根据需要做成各种颜色,具有
抗震能力强等特点。但如果显示界面过于复杂,会
导致对单片微型计算或者使单片机 MCU(single
chip microcomputer)的选择范围变窄、芯片成本变
高,故笔者采用矩阵控制方案,提出 LED 矩阵链接
方法。
1 矩阵控制方案
1.1 电路连接方式
图 1 所示的 LED 显示屏,如果按通常的控制方 式(如图 2 所示),共需要 58 个 I/O 口,如采用图 3 所示的 8×8 矩阵连接方式,则只需要 16 个 I/O 口,
大大节省了 MCU 的管脚数目。如想进一步节省
MCU 的 I/O 口,可采用 74HC595[3]进行 I/O 口扩
展,甚至可采用多片 74HC595 以级联的方式扩展
I/O 口。1 片 74HC595 只需要 3 个 MCU 的 I/O 口,
便可得到 8 路输出,2 片 74HC595 级联,则可以得
到 15 路输出。
1.2 控制方式
点亮 1 只 LED,需要在 LED 阳极加上高电平
信号,同时在其阴极加上低电平信号;要熄灭 LED,
要在阳极上加入低电平,或在阴极上加上高电平信
号。一般同时在 LED 阳极加低电平,而在其阴极加
上高电平信号,由于此时 LED 中没有电流流过,可
达到熄灭 LED 的目的。为了控制每只 LED 灯的亮/
灭,可采用扫描控制方式控制其阳极、阴极的电平
信号,扫描控制方式一般采用以下 3 种:
1) 行扫描方式。
行扫描方式,逐行输出高电平,需要点亮的
LED 所在的列输出低电平,其他列输出高电平。对
于图 3 所示电路,如只需要 E3、T14 亮,则扫描到
第 3 行时,pin11 输出高电平(其他行全部输出低电
平),而 pin5、pin8 则同时输出低电平,同时,pin1~ pin4、pin6~pin7 均输出高电平。可见,流过 pin11
的电流为 2 只 LED 的电流,当第 3 行全部 LED 均
点亮时,则流过行扫描线 p11 的电流为所有点亮的
LED 电流总和,而列扫描线中流过的电流,在其点
亮的列为 1 只 LED 中流过的电流。如果在行扫描线
I/O 口输出电流能力一定的条件下,当某行同时有
多只 LED 点亮时,会造成每只 LED 中流过的电流
减小,引起显示屏亮度不均匀。解决问题的方法如
图 4 所示,在 MCU I/O 口与 LED 矩阵之间增加电
流放大电路,提高扫描线的电流驱动能力。此扫描
方式同全扫描方式相比,具有显示速度较快的特点。
2) 列扫描方式。
列扫描方式,逐列输出低电平,需要点亮的
LED 所在的行,则输出高电平,否则输出低电平。
除扫描到的列以外,其他列均输出高电平。列扫描
方式与行扫描方式具有相同的优缺点。
3) 全扫描方式。
全扫描是指,对每只 LED 灯进行扫描,每一时
刻只能有 1 只 LED 被点亮。从第 1 行开始每次输出
一行为高电平,其他各行为低电平,同时从第 1 列
开始扫描每一列,当遇到所在列的 LED 灯需要点亮
时,该列输出低电平,其他列输出高电平。间隔一
定的时间后,再扫描到下一列,当所有列扫描完后,
再扫描到下一行,按同样的方式再扫描每一列。当
所有行扫描完后,再从第 1 行开始按同样的方式扫
描。这种扫描方式,使得每个 I/O 口中流过的电流,
不会超过 1 只 LED 中流过的电流,显示屏亮度均匀,
但扫描时间较长,需要消耗额外的 MCU 时间。
1.3 电路原理框图
如图 4 所示,行扫描信号经电流放大电路 1 接
入到发光二极管的阳极,列扫描信号经电流放大电
路 2 后接入到发光二极管的阴极。本框图仅讨论 8
×8 的矩阵连接方式,其他多维 m×n 的连接方式,在原理上是相同的。
1.4 数据结构
针对图 4 所示电路,可以构建 8 个数据结构
(data0,data1,…,data7),作为显示缓冲区,每个数据
的每一位对应一只 LED,当位为 1 时代表点亮该
LED,为 0 则熄灭此 LED。图 4 中,P0.0~P0.7 为
P0 口的 8 个输出端口,P1.0~P1.7 为 P1 口的 8 个
输出端口。P1 口用于控制 LED 矩阵的行,P0 口则
控制矩阵的列。每个 LED 是否点亮,应该按照设计
时所赋予的功能来定义。
2 软件设计
2.1 主程序软件流程图
如图 5 所示,主程序包括初始化,解码显示字
符等子程序。其中,初始化包括:对变量的初始化,
设定定时器,将中断服务程序的服务地址放入中断
地址表、开中断等操作;解码显示字符子程序则根
据定义的功能对显示字符解码,将解码结果放入
(data0,data1,…,dada7)所示的显示缓冲区中,供中
断服务程序使用。假设待显示的数字为 26,其他字
符均不显示,则解码程序如下(数据 dig_high 表示
高位待显示数据,dig_low 表示低位待显示数据):
void decode (void)
{
di(); //关中断
data0=data1=data2=data3=data4=data5=data6=da
ta7=0;
//…………….
if(dig_high==2)
data0|=3,data1|=0x3,data2|=0,data3|=3,data4|=3,data5|
=0,data6=3;
//…………….
if(dig_low==6)
data0|=0x0c,data1|=0,data2|=0x0c,data3|=0x0c,data4|
=0x0c,data5|=0x0c,data6|=0x0c;
//…………….
ei(); //开中断
}
2.2 中断服务流程图
如图 6 所示,采用列扫描方式,首先要确定输
出端口(P0,P1)的值。特别要注意,在程序入口处放
置“P0=~0, P1=0”语句,目的是关闭所有的显示字
符,以避免显示出现闪烁及杂乱显示。设计时,放
大电路 2 采用 ULN2003 芯片,其控制逻辑是:当
输入高电平时 ULN2003 输出为低电平,当输入为
低电平时 ULN2003 输出处于高阻态,所以 P0 口输
出全部反向。其中断服务程序如下:
interrupt void display_led(void)
{
unsigned char p0a,p1a;
P0=~0, P1=0;
switch(col)
{
case 0:
{
p1a=data0;
col=1;
if(data0) p0a=~0x7f;
else p0a=~0xff;
break;
}
case 1:
{
p1a=data1;
col=2;
if(data1) p0a=~0xbf;
else p0a=~0xff;
break;
}
//case 2~case 6 程序结构基本相同
case 7:
{
p1a=data7;
col=0;
if(data7) p0a=~0xfe;
else p0a=~0xff;
break;
}
}
P0=p0a, P1=p1a;
}