与数码管一样,LED点阵模块内部也是由多个LED发光单元构成的,只不过发光单元被封装成圆形或矩形的透光窗口,通常称为像素(Pixel)。LED点阵模块的像素按行列均匀排列,通常使用每列与每行的像素数量来区分,最常用的5×7(5列7行)与8×8点阵模块如图12.1所示。
图12.1 常用LED点阵模块
当然,即使行列像素数量相同,像素本身的尺寸也可能会有差异,所以也会以像素的直径(方形像素使用边长)大小来衡量,常用的有3.00mm、3.75mm、5.0mm。大尺寸的LED点阵屏通常也是由这些小尺寸点阵模块组合而成的。例如,256×128点阵模块每行有32个8×8点阵模块,总共16行。先来看看8×8点阵模块的内部结构,如图12.2所示。
从图中可以看到,8×8点阵模块内部由64个LED组成,每一列(Column,COL)LED的阴极是连接在一起的,每一行(ROW)LED的阳极也是连接在一起的,与8位数码管的电路结构完全一样。LED点阵模块本质上并不区分共阴与共阳,因为把行或列当作位选通或段驱动都可以,但是通常以LED与第1行(不是引脚号,这里对应就是PIN9)的连接极性来约定是共阴还是共阳,所以图12.2所示LED点阵模块为共阳极。
共阴极点阵模块内部结构如图12.3所示,读者可以自行对比一下。
特别提醒一下: LED点阵模块的引脚号排列是没有规律的,可不要直接把行号或列号当成位选通或段驱动 。常用的8×8点阵模块的引脚定义如图12.4所示(字母A~H对应1~8行,数字1~8对应1~8列)。
图12.2 8×8 LED点阵模块内部结构
图12.3 8×8共阴极LED点阵模块
图12.4 某LED点阵模块的引脚顺序及定义
一般LED点阵模块某一侧会有厂家的生产型号丝印,当我们正向面对丝印时,左侧第一脚为PIN1(有些厂家会直接在第一脚标记一下),然后按逆时针方向直至PIN16。至于每一个引脚的具体定义最好参考相应的数据手册,厂家可能会因为一些实际的考量(例如兼容其他点阵模块)而使得引脚定义有所不同。
Proteus软件平台中的点阵模块没有标记共阴或共阳,从器件库中调出来的时候,左上角为第1脚(有一个原点标记),上侧引脚名从左到右依次为1~8,下侧引脚名从左到右依次为A~H,相应的内部电路结构如图12.5所示(器件型号MATRIX-8X8-RED)。
图12.5 LED点阵仿真模块
有人可能会问:你怎么知道的?可别信口开河呀!其实很简单,在Proteus软件平台中单击鼠标右键调出LED点阵模块,在弹出的快捷菜单中选择“取消组合(Decompose)”项可以打散该模块,然后用鼠标双击任意一个引脚,就可以弹出该引脚信息的属性对话框,类似如图12.6所示。
图12.6 LED点阵仿真模块的引脚信息
至于各LED发光单元对应的引脚,只能通过加电压的方式实验了。 为了统一全书描述,对于没有标记引脚的器件均不做旋转镜像操作,以从器件库中调出来的默认方向为准,且引脚定义以第一次介绍为准。
由于LED点阵模块相当于多位数码管,所以只能使用动态扫描的方式来驱动。假设需要显示数字“5”,首先需要得到相应的字型码,如图12.7所示。
图12.7 数字“5”的字型码
如果把行(见图12.5)作为位选通,把列作为段驱动,则从上到下的字型码依次为(左高位)0x00、0x7E、0x40、0x40、0x7E、0x02、0x02、0x7E。如果把行作为段驱动,把列作为位选通,则从左至右的字型码依次为(下高位)0xFF、0x61、0x6D、0x6D、0x6D、0x6D、0x0D、0xFF(注意字型码是反过来的,因为此时位选通为高电平有效,相当于8个共阳数码管)。由字符(可以是数字或汉字)形状得到的字型码称为字模,获取字模的过程称为取模。
下面来看看单个8×8点阵模块是被如何驱动的,相应的仿真电路如图12.8所示。
这里使用74HC138把行作为位选通(A~H),使用74HC573把列作为段驱动(1~8),由于取模方向是从左到右,所以在线路连接时应该把P1.7与LED点阵第1脚(左上脚)对应连接,相应的源代码如清单12.1所示。
图12.8 LED点阵模块仿真驱动电路
清单12.1 点阵模块显示数字“5”
读者可自行阅读源代码,它与清单7.2几乎是完全一样的,主要的区别就在于字模,此处不再赘述。
也可以使用两片74HC595级联来动态驱动LED点阵模块,这样可以节省不少控制引脚,相应的仿真电路如图12.9所示。
图12.9 两片74HC595动态驱动LED点阵
74HC595与单片机的连接仍然与图10.1完全一样,所以清单10.1所示源代码可以直接拿来修改,只需要使用清单12.1中的字模数组,同样来看看相应的源代码,如清单12.2所示。
这里仍然要注意点阵模块与74HC595的连接方式:我们使用U 2 作为段驱动,U 3 作为位选通(与图10.1一致)。由于取模方向是从左至右,当串行数据输入到芯片时,最低位 应该 出现在Q 7 ,所以在移入数据时采用 低位先行 的策略。同时还要注意,我们给位选通传递的参数是“~(0x80>>i)”,而不再是清单10.1中的“~(0x01<<i)”,后者显示出来的将是上下倒过来的数字“5”(也就是数字“2”)。
MAX7219也同样可以驱动LED点阵模块,相应的Proteus软件平台仿真电路如图12.10所示。
在硬件设计上需要注意,由于MAX7219只能用来驱动共阴数管码(DIG 0 ~DIG 7 最多只一个低电平),所以我们必须把段(A~DP)输出用来驱动列(1~8),而把位选通(DIG 0 ~DIG 7 )用来驱动行(A~H)。同时,还要注意MAX7219输出与LED点阵模块引脚的连接顺序,这样我们就可以把之前的取模数据直接发送到芯片中。
为节省篇幅,这里不再给出对应的源代码,读者只需直接使用清单10.2将字模写入到MAX7219即可,这里使用VisualCom软件平台给出具体发送的串行数据,从中还可以观察MAX7219内部寄存器的状态,如图12.11所示。
该模组的LED点阵与MAX7219连接方式与图12.10完全等价,相应的预置数据如图12.12所示。
通过与图11.5所示的预置数据进行对比,会发现只有两点不同,其一,将所有 数据寄存器 设置为不译码模式,其二,写入 数据寄存器 的就是刚刚定义的字模,仅此而已。
清单12.2 74HC595动态驱动LED点阵模块
图12.10 MAX7219驱动LED点阵模块
图12.11 仿真效果
图12.12 预置数据
如果驱动的点阵模块更多该怎么办呢?通过进一步扩展图12.8所示电路能够实现吗?可以!但是这种方案是由单片机承担动态扫描的任务,所以能够驱动的LED点阵模块的数量是有上限的,是什么因素限制的呢?主要是将一行(包括选通)数据完整移入到74HC595所花费的时间,我们来看图12.13所示时序。
图12.13 扫描时序
当开始扫描驱动点阵模块第 N 行显示时,这一行需要持续显示一定的时间,在这段时间内,应该进行第 N +1行数据的准备工作,如果点阵的列数量越多,准备好一整行数据需要花费的移位时钟也就越多,那么第 N 行的持续显示时间也就越长,对不对?这看起来好像没什么问题,因为显示时间越长则亮度也越大,但是如果扫描行列数量一旦多了起来,完整刷新一帧所需要的时间也就越长,相应的帧率就会下降,显示效果也就会变差。
例如,在清单12.2所示write_multi_74hc595_ex函数中,每移入1位数据需要的时间约为15μs(可通过观察汇编指令估算),假设LED点阵屏的行列数均为40,我们需要10片74HC595来驱动,则移入一整行(含选通)数据所需的时间为15μs×(2×40)=1.2ms,相应的帧率只有1/(40×1.2ms)≈21fps。换句话说,想通过扩展图12.8所示电路来驱动超过40×40的LED点阵屏,刷新帧率将不会高于21fps,这很有可能无法令客户满意。虽然更换速度更快的单片机会有一定的积极意义,但是很遗憾,改善的空间仍然不会太大。
值得一提的是,当点阵屏的 列(段驱动) 数量很多,且相应的LED全部被点亮时,所有流过LED的电流都会通过对应 位选通 的驱动引脚,这极有可能会超过74HC595的输出驱动能力,所以实际进行大屏幕LED点阵显示产品的设计时,我们一般 不能 直接使用74HC595(或类似的芯片,如74HC138)直接驱动点阵模块的 位选通 ,而是通过三极管或场效应管扩流的方式间接驱动,下一章就会讲到这种应用。