主题活动
- 点亮以及熄灭一个点:讨论单片机IO口上的数字信号是如何传递到LED点阵上指定的位置上的。
- 显示一些数字和图案。
一、点亮以及熄灭一个点
驱动链路与延迟
书接上篇,第一步是要简单整理一下,从单片机io到LED点阵的信号的怎么传递的。看一看下面的图片,信号传递存在两条前向通道,不存在反馈环路,我当然可以分别讨论它们,这样可以让自己舒服一点。

上面的图关于数据传输的细节不够,要添加一点点细节,然后得到下面的新图。这个8x8的LED点阵实际上由两个字节寄存器直接控制的,分管横坐标和纵坐标,也就是所谓的两条前向通道。

横坐标由P0寄存器控制,P0寄存器的各位的地址就是坐标刻度,如P00,P03,用于指定LED灯的横坐标。P0寄存器上各位的值(如P04=0)用于指定LED的状态,当然只有横坐标值是不够的。
纵坐标由一个字节数据操作,这个数据通过单片机的一个IO口一位一位地流向74HC595,然后74HC595在其DPa(bit0)-DPh(bit7)管脚上显示纵坐标数据,这八个管脚链接到纵坐标的思路和横坐标控制是一模一样的。
纵坐标的数据传输比横坐标多了一个环节,我用脑袋瓜感觉一下,纵坐标数据传得比横坐标慢,所以在进行端口操作时,如果先送横坐标数据,再送纵坐标数据,就有可能出点什么毛病。事实也证明了这一点,如果这么搞,上电时某列会出现残影,改变控制顺序就能解决这个问题,当然,我暂时也不在乎为什么会这样。
LED_X_COL_PORT = 0xFF; //关闭X轴所有列选,防止上一次的画面留下残影
LED_Y_COL_PORT(0x08); //送入Y轴数据
LED_X_COL_PORT = 0xF7; //送入X轴数据
到这里,很显然地完成一次操作是有延迟的,11.0592MHz晶振下,点阵完整地执行完一组有效指令所消耗的时间固定为625us,这是这个应用中操作点阵的最小时间单位。
点灯
我尝试用demo程序简单地操作了一下led点阵,发现他这个电路的设计方式对于程序设计很友好,或许设计师从一开始就是这个意图。


当操作P00为0(P0 = 0xFE),DPa = 1(为74HC595送入0x01)时,右下角的灯点亮,由于编程时变量的低位在右侧,所以灯的位置坐标顺序与变量的二进制表示的位是一一对应的,但是这个坐标系与数学上惯用的坐标系是关于y轴对称的,并不利于分析,思维惯性可能会导致出错。针对这个问题可以使用坐标变换来处理。

我们习惯的坐标系是图示的黑色的(x,y)坐标系,而本例中实际使用的坐标系是红色线展示的(x’,y’)坐标系。坐标变换是下面这个样子的。
{x’ = 7 - x, 0 <= x <= 7,
{y’ = y, 0 <= y <= 7.
这个数学运算在设计程序时显式地指出来(下面代码段中的7-columnIndex和columnIndex),仅仅只是为了便于分析。注意到列选表columnSeletor的内容不是用类似0xfe而是用类似0x01的数值来指定某一列,然后在主程序中进行按位取反操作,我想这样做或许会更加贴近直觉一点。
unsigned char columnSeletor[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
LED_X_COL_PORT = ~columnSeletor[7-columnIndex];
画出图像以及使用公式来描述的好处是,我们能轻易地看出来控制点阵的变量是存在定义域和值域的,并不能在整个二维平面上讨论这个问题。这会督促我们在编程时规避掉参数检查不够充分的错误。虽然从P0口和74HC595的8位寄存器特性来说也不可能越界操作,但是这应该会让自己安心一点。
二、显示一些数字与画面
动态显示
静态方式不能让点阵显示任意图形,只能得出一些点或者是类似正方形的东西。

我们总是可以考虑最朴素的方式来解决这个问题,点->线->面逐渐升维绘制图像。每次只绘制一个点,点穿过时间在点阵画布留下轨迹,只要点运动得足够快,加上视觉滞留效应,人眼就会在点阵上看到一副“完整的,静态的”图像。

后来人们利用并口驱动的特性,一次性点一排8个灯,将操作一幅画的时间从64个单位缩短到了固定的8个单位,缩短了操作一幅图像所消耗的时间,在有限的led余辉时间下,控制器可以以更高的刷新率操作点阵,好处是显示图像和数字的时候不会像上图中的0那样暗淡无光,允许显示内容变得更快,消耗的控制器资源更少。

单位时间内并行驱动的8个灯可以是以行为基础的也可以是以列为基础的。上图使用的方法是列扫描,一次一列逐列绘制完整个画布。
相关工具
或许是行扫描与列扫描的技术方法比较成熟,网络上出现了各种各样字模与图像提取工具。我恰好用的是下面这个,感谢作者。

通过这些工具,可以在平面上显示一些比较随意的图形,实际上数字也是一种图形,只不过人们给这类图像起了个别名叫做“数字”而已。

本文详细介绍了如何使用单片机通过C语言控制LED平面点阵,包括点亮和熄灭单个点,以及动态显示数字和画面。讨论了驱动链路、延迟问题以及坐标变换,还提到了动态显示技术以提高显示效果。
3681

被折叠的 条评论
为什么被折叠?



