本实验使用MAX7219驱动8x8点阵。上位机使用Ubuntu 14.04,下位机使用Raspberry pi。
1.基础:认识MAX7219
拿到MAX7219驱动的LED矩阵,第一件事是先连接并尝试显示图案。使用MAX7219除了需要提供GND以及VCC外,只需要再提供三根引脚即可点亮矩阵。其中,DIN引脚输入数据,CS(LOAD)引脚控制数据输入,CLK引脚用于区分每个bit。
MAX的整个写入流程为,首先CS引脚置0,表示允许写入。而后从高位顺序写入16个bit。每个bit的写入方式为首先DIN置为要写入的bit值,而后CLK产生一个下降沿(图中为上升沿,不知道为何有差别)即被读入。最后CS引脚置1表示写入结束。
时序图如下:
在运行之前,需要进行一次初始化,其行为是向某几个特定的地址写入特定的值。至少需要写入两个地址,第一个是0x0b,写入0x07表示扫描显示所有行。第二个是0x0c,写入1表示进入工作模式。
而后点阵上每一行都有其地址,如第一行是0x01到第八行是0x08,每次向固定行的地址写入一个8位二进制数即可在指定行上显示图案。
2. 树莓派对GPIO的访问——虚拟文件系统访问
Linux可以通过访问sys/class/gpio下的一些文件,通过对这些文件的读写来实现对于GPIO的访问。
树莓派下面的可用的GPIO如右图所示,需要注意树莓派一代和二代的区别。
这里根据大大的博客攻略,我首先尝试用shell。代码直接参考了大大的。先试着玩一下。
!/bin/bash
# DIN, CS, CLK的GPIO口位置
DIN=4
CS=3
CLK=2
# 一些文件路径
GPIO_BASE=/sys/class/gpio
GPIO_EXPORT=${GPIO_BASE}/export
GPIO_UNEXPORT=${GPIO_BASE}/unexport
BIN=(00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000)
# 生成指定GPIO引脚的文件夹位置
function GPIO(){
echo ${GPIO_BASE}/gpio$1
}
# 将某个引脚export到用户态
function GPIO_export(){
if [ -d `GPIO $1` ]; then
echo GPIO pin $1 found in folder.
else
echo $1 > ${GPIO_EXPORT}
fi
}
# unexport某个引脚
function GPIO_unexport(){
if [ -d `GPIO $1` ]; then
echo $1 > ${GPIO_UNEXPORT}
else
echo GPIO pin $1 not found.
fi
}
# 改变某个引脚的方向
function GPIO_direction(){
echo $2 > `GPIO $1`/direction
}
# 改变某个引脚的值
function GPIO_set(){
echo $2 > `GPIO $1`/value
}
# 改变DIN的值
function GPIO_DIN(){
GPIO_set $DIN $1
}
# 改变CS的值
function GPIO_CS(){
GPIO_set $CS $1
}
# 改变CLK的值
function GPIO_CLK(){
GPIO_set $CLK $1
}
# 向MAX7219发送一个byte的值
function Matrix_send_char(){
local i=1
for ((i=1;i<=8;i++)); do
chr=`expr substr $1 $i 1`
GPIO_DIN $chr
GPIO_CLK 1
GPIO_CLK 0
done
}
# 向MAX7219发送一次完整的信号
function Matrix_send_word(){
GPIO_CS 1
GPIO_CS 0
GPIO_CLK 0
Matrix_send_char $1
Matrix_send_char $2
GPIO_CS 1
}
# 初始化GPIO引脚
function GPIO_init(){
GPIO_export $DIN
GPIO_export $CS
GPIO_export $CLK
sleep 2
GPIO_direction $DIN out
GPIO_direction $CS out
GPIO_direction $CLK out
}
# 清除GPIO引脚
function GPIO_clear