AndroidThings驱动MAX7219点阵
之前用MAX7219点阵做过跑马灯显示,但其实对MAX7219的显示原理并不清楚,大概知道是SPI的协议。这次通过AndroidThings来彻底搞明白怎么显示的。首先看一下MAX7219点阵的原理图:
因为MAX7219是用来控制数码管,所以在原理图上可以看的DIG和SEG,这本来对应数码管的位和段,但在点阵模块中对应行和列,这样我们就把引脚和每一个点阵中的led对应起来了。
然后再来研究一下MAX7219数据传输。MAX7219每一次数据传输是16位,其中高八位表示寄存器地址,低八位表示数据,而高八位的地址中只有低4位才有意义,因为MAX7219只有15个寄存器用4位就可以表示了。
再回到原理图上,每一个DIG对应于一个寄存器,而这个寄存器中的数据就和SEG一一对应,也就是说8x8点阵中的一行对应一个寄存器地址,寄存器中的数据中的每一位对应这一行中的SEG值。另外还需要注意MAX7219可以设置译码方式,这主要是为了简化数码管的现实,设置BCD译码之后可以直接用真实的数字来表示数码管的显示,而不用去组合各个SEG的亮灭。但是在控制点阵时就用不上这个功能了。在非译码模式下,寄存器数据与各个SEG的对应关系如下图所示:
而每一行的寄存器地址是从0开始的,DIG0也就是第一行的寄存器地址是0,依次类推第八行对应的寄存器地址是1。这样就基本能够理解点阵的显示原理了。
比如说我们要让第一行第一个led点亮,那就向寄存器地址0写入10000000b,如果想要第一行全亮,那就写入11111111b。以数字0为例,想要在8x8点阵上显示,各行的亮灭情况如下所示:
其中红色的数字就是我们需要依次向0,1,2寄存器地址写入的数据。这样整个显示过程就很清晰了吧。
再回到数据传输上,16位数据中的寄存器概念并不是SPI协议本身,SPI每次传输8位数据。而MAX7219是按16位数据为一组数据对待,所以MAX7219需要知道数据起始,这时就需要CS来配合了,当CS为低电平时表示传输数据,为高电平时表示数据传输结束,否则传输的数据会被丢弃。
在Things中使用SpiDevice的write函数就可以写入数据,然后配合GPIO控制CS的高低电平,以上图中第一行数据为例,代码大概如下:
1 | csGPIO.setValue(false); |
其实掌握了以上这些,然后对SPI协议也比较了解的话,就会发现网上的许多代码是通过GPIO来模拟SPI通信来驱动Max7219点阵的。现在我们来尝试直接用Things的SpiDevice来驱动Max7219。
首先,获取SpiDevice,这个跟之前的获取GPIO和UART类似,使用PeripheralManagerService的openSpiDevice函数即可,这里我们用的是SPI0.0,引脚如下所示:
将BCM10接DIN,BCM11接CLK,BCM25接CS,GND接Ground,VCC接3.3V。
初始化SPI及CS GPIO的代码如下:
1 | private boolean initSPI () { |
在Max7219的Datasheet中提到CLK的最大频率是10MHz,这里我们设置为8MHz。
然后我们封装一个向Max7219发送一个字节的函数:
1 | private void writeMax7219Byte(byte data) throws IOException { |
一般来说网上看到这部分的代码是通过GPIO来模拟的,我以前在NanoPi上用GPIO模拟SPI的C代码如下:
1 | void WriteMax7219Byte(uchar data) { |
比较来看用SPI代码简单了很多。但是直接GPIO模拟SPI还是比较易用。
然后封装一下Max7219的一次16字节的addr+data数据
1 | private void writeMax7219(byte addr, byte data) throws IOException { |
注意CS的操作,传输数据开始前需要置为低电平,结束后需要置为高电平,这两步非常重要。
最后初始化一下Max7219
1 | private void initMax7219() throws IOException { |
这样就完成了,接下来就是之际通过writeMax7219来显示想要显示的数据就可以了。
注意:在测试的时候发现打开SPI的时候会出错,但是再运行一次就好了,通过adb shell发现,默认/dev下是没有spidev0.0和spidev0.1,打开失败之后就会出现这两个设备,可能是驱动没有常驻,还没有去深究。在使用示例代码的时候,可能需要多点两次按钮才能成功。
来一张效果图:
完整代码下载链接: https://pan.baidu.com/s/1smPf09R 密码: 7bgv