很久之前写了一篇树莓派用Java驱动一个8x8 LED矩阵,搜索用Java实现级联8x8 Max7219,出来一些让人很无语的博客,不过好在在这片文章的帮助下解决了:
怎样将MAX7219驱动的LED矩阵8x8与ATtiny85微控制器连接-电子发烧友网 。
具体的实现类和功能看码云(基于这些个max7219LED做的一个闹钟):led-clock: 树莓派+max7219 LED矩阵钟表(闹铃) (gitee.com)
步入正题,首先如何接线就不多说了,之前的文章都有,上代码:
//len是数据长度,一个8x8矩阵可以用一个long表示,一个long有8个字节。
//比如len = 16,表示驱动两个led矩阵。
//推荐改 (len & 7) != 0 效率更高
if (len % 8 != 0) {
return;
}
int size = len/8;
if (!isInit) {
isInit = true;
wiringPiSetup();
pinMode(DIN,OUTPUT);
pinMode(CS,OUTPUT);
pinMode(CLK,OUTPUT);
//首先要明确,CS LOW表示解锁max7219内存,此时可以将数据送入到寄存器,所以将每个led矩阵的数据全部都送入后再将CS HIGH,表示锁住内存,即完成一次数据写入。
//再者,只要addr相同,重复往寄存器写数据,就是从第一个LED开始一个一个的有顺序的写入(同一个addr写完后一定要锁定内存来通知本次数据写完,可以写下一个addr的数据)。
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(0x09,0x00);
}
digitalWrite(CS, HIGH);
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(0x0a,0x03);
}
digitalWrite(CS, HIGH);
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(0x0b,0x07);
}
digitalWrite(CS, HIGH);
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(0x0c,0x01);
}
digitalWrite(CS, HIGH);
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(0xff,0x00);
}
digitalWrite(CS, HIGH);
}
long []all = new long[size];
for (int i = 0; i < all.length; i++) {
//此处我用的netty的buf,通过socket将数据输送过来(len就是从buf里读出来的数据长度),这里可以替换成自己的数据,可以参见 DefaultFont8x8.getPoints()方法将数据从long转为byte或从byte转为long,本质上就是用8x8的LED矩阵拼图拼成一个大的LED屏幕
all[i]=in.readLong();
}
int index = 0;
byte[][] data = new byte[size][8];
for (int i = 0; i < size; i++) {
//该类在我的单个8x8矩阵的文章里有,可以从那里copy出来。
data[i] = DefaultFont8x8.getPoints(all[index]);
index ++;
}
//注意这里,j = 1表示写入每个8x8矩阵的第一行,2表示第二行,以此类推;
//即把所有的LED矩阵的第一行都写完了再封锁内存,然后再写第二行,直到把8行数据都写完为止。
//这样写入的数据不会存在CSDN另一篇播客用户区评论的有剪影的问题。
for (int j = 1; j <= 8; j++) {
digitalWrite(CS, LOW);
for (int i = 0; i < size; i++) {
writeData(j, data[i][j-1]);
}
digitalWrite(CS, HIGH);
}
调用到的方法:
private void writeData(int addr, int data) {
//通知要往那个地址上写
writeByte(addr);
//往这个地址上写什么样的数据,连续写两次表示写完一次数据
writeByte(data);
//表示将数据flush出去
digitalWrite(CLK,HIGH);
}
private void writeByte(int data) {
for (int i = 0; i < 8; i++) {
digitalWrite(CLK, LOW);
digitalWrite(DIN, (data & 0x80) == 0 ? LOW : HIGH);
digitalWrite(CLK, HIGH);
data <<= 1;
}
}
需要导入的包:
import static com.pi4j.wiringpi.Gpio.HIGH;
import static com.pi4j.wiringpi.Gpio.LOW;
import static com.pi4j.wiringpi.Gpio.OUTPUT;
import static com.pi4j.wiringpi.Gpio.digitalWrite;
import static com.pi4j.wiringpi.Gpio.pinMode;
import static com.pi4j.wiringpi.Gpio.wiringPiSetup;