0
点赞
收藏
分享

微信扫一扫

2.树莓派与Java驱动多个Max7219的LED矩阵

流计算Alink 2022-03-26 阅读 44
java

很久之前写了一篇树莓派用Java驱动一个8x8 LED矩阵,传送门: Java控制树莓派8x8矩阵LED_xss13的博客-CSDN博客​​​​​​​

今天我要吐槽一下,CSDN各种低质量的文章,没有任何用处而且还帮倒忙,驱动多个LED矩阵这个问题在开始的时候卡了我好几天,后来被迫无奈放弃了,好在今天想起来了,又拾起来再研究了一次,终于搞清楚了。

首先感谢这篇文章对我的帮助,不胜感激:
​​​​​​​怎样将MAX7219驱动的LED矩阵8x8与ATtiny85微控制器连接-电子发烧友网 ,让我明白了一些API具体的意义,接下来再进行操作,即便不清楚,也可以慢慢的猜,慢慢的试验出来。

步入正题,首先如何接线就不多说了,之前的文章都有,上代码:

//len是数据长度,一个8x8矩阵可以用一个long表示,一个long有8个字节。
//比如len = 16,表示驱动两个led矩阵。
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;     

好了,到此为止,一个多段LED驱动就告一段落了,接下来就可以尽情的玩耍了。

举报

相关推荐

0 条评论