如何控制链接在一起的4 8x8 LED矩阵,并使用Max7219供电? [英] How to control 4 8x8 led matrices that are chained together and are powered with the Max7219?
本文介绍了如何控制链接在一起的4 8x8 LED矩阵,并使用Max7219供电?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我希望使用raspbercrypi控制矩阵的每个单独像素,但我只是不知道必须如何发送数据以及必须发送哪些数据。
我已经查看了SPI接口,但在阅读了这篇article,其中他没有使用它并因此而手动操作后,我不知道该怎么办。
调试也非常困难,因为我无法检查发送数据的时间和内容
我还检查了各种Python库,但我无法运行它们,即使在安装了每个依赖项之后也是如此 但这是不必要的,因为我不想使用python。我从来没有做过这样的事情,所以我非常缺乏经验。
我在guide中对其进行了布线,并用RUST编写了一些代码以通过SPI接口发送数据:
use std::io;
use std::io::prelude::*;
use spidev::{Spidev, SpidevOptions, SpiModeFlags};
fn create_spi() -> io::Result<Spidev> {
let mut spi = Spidev::open("/dev/spidev0.0")?;
let options = SpidevOptions::new()
.bits_per_word(8)
.max_speed_hz(20_000)
.mode(SpiModeFlags::SPI_MODE_0)
.build();
spi.configure(&options)?;
Ok(spi)
}
fn main() {
let mut spi = create_spi().unwrap();
spi.write(&[0x01, 0x02, 0x03]).unwrap();
}
在PI上运行它后,它似乎成功地发送了数据而没有死机,但我无法检查它是否真的起作用了。
在矩阵上未按预期显示任何内容。
谁能向我解释一下如何配置SPI连接,以及我必须发送哪些数据才能初始化矩阵并在上面显示一些内容?
更新
在查看this driver之后,我现在能够在第一行的第一个和第四个矩阵上显示从0到255的值。 代码如下:
use std::io;
use std::io::prelude::*;
use spidev::{Spidev, SpidevOptions, SpiModeFlags};
use std::thread::sleep;
use std::time::Duration;
// Possible command register values on the display chip.
#[derive(Clone, Copy)]
pub enum Command {
Noop = 0x00,
Digit0 = 0x01,
Digit1 = 0x02,
Digit2 = 0x03,
Digit3 = 0x04,
Digit4 = 0x05,
Digit5 = 0x06,
Digit6 = 0x07,
Digit7 = 0x08,
DecodeMode = 0x09,
Intensity = 0x0A,
ScanLimit = 0x0B,
Power = 0x0C,
DisplayTest = 0x0F,
}
// Decode modes for BCD encoded input.
#[derive(Copy, Clone)]
pub enum DecodeMode {
NoDecode = 0x00,
CodeBDigit0 = 0x01,
CodeBDigits3_0 = 0x0F,
CodeBDigits7_0 = 0xFF,
}
fn create_spi() -> io::Result<Spidev> {
let mut spi = Spidev::open("/dev/spidev0.0")?;
let options = SpidevOptions::new()
.bits_per_word(8)
.max_speed_hz(20_000)
.mode(SpiModeFlags::SPI_MODE_0)
.build();
spi.configure(&options)?;
Ok(spi)
}
fn main() {
let mut spi = create_spi().unwrap();
// turns on 4 displays (address, command, on)
for display in 0..4_u8 {
spi.write(&[display, 0x0c, 0x01]).unwrap();
}
// sets decode mode (adress, mode) to 0x00
spi.write(&[0x00, 0x09, 0x00]).unwrap();
// writes data (address, digit, data)
for data in 0..255 {
spi.write(&[0x00, 0x01, data]).unwrap();
sleep(Duration::from_millis(50));
}
}
但我不知道如何访问其他行或单个矩阵。
更新2
现在我清理了代码,发现将扫描限制设置为7可以将数据绘制到所有8行 代码如下:#![allow(dead_code)]
use spidev::Spidev;
use std::io::prelude::*;
// Maximum number of addrs connected in series supported
const MAX_DISPLAYS: usize = 8;
// Digits per addr
const MAX_DIGITS: usize = 8;
// Possible command register values on the addr chip.
#[derive(Clone, Copy)]
pub enum Command {
Noop = 0x00,
Digit0 = 0x01,
Digit1 = 0x02,
Digit2 = 0x03,
Digit3 = 0x04,
Digit4 = 0x05,
Digit5 = 0x06,
Digit6 = 0x07,
Digit7 = 0x08,
DecodeMode = 0x09,
Intensity = 0x0A,
ScanLimit = 0x0B,
Power = 0x0C,
DisplayTest = 0x0F,
}
// Decode modes for BCD encoded input.
#[derive(Copy, Clone)]
pub enum DecodeMode {
NoDecode = 0x00,
CodeBDigit0 = 0x01,
CodeBDigits3_0 = 0x0F,
CodeBDigits7_0 = 0xFF,
}
pub struct Matrix {
pub spi: Spidev,
pub devices: u8,
pub decode_mode: DecodeMode
}
impl Matrix {
pub fn power_on(&mut self) {
for addr in 0..self.devices {
self.spi.write(&[addr, Command::Power as u8, 0x01]).unwrap();
}
}
pub fn power_off(&mut self) {
for addr in 0..self.devices {
self.spi.write(&[addr, Command::Power as u8, 0x00]).unwrap();
}
}
pub fn set_decode_mode(&mut self, addr: u8, mode: DecodeMode) {
// sets decode mode (adress, command, mode)
self.spi.write(&[addr, Command::DecodeMode as u8, mode as u8]).unwrap();
}
pub fn send_command(&mut self, addr: u8, command: Command, value: u8) {
self.spi.write(&[addr, command as u8, value]).unwrap();
}
pub fn draw_raw(&mut self, addr: u8, data: &[u8; MAX_DIGITS]) {
let mut digit: u8 = 1;
for b in data {
// addr ..
self.spi.write(&[addr, digit, *b]).unwrap();
digit += 1;
}
}
pub fn clear_addr(&mut self, addr: u8) {
for i in 1..9 {
self.spi.write(&[addr, i, 0x00]).unwrap();
}
}
pub fn set_intensity(&mut self, addr: u8, intesity: u8) {
self.spi.write(&[addr, Command::Intensity as u8, intesity]).unwrap();
}
}
let spi = create_spi().unwrap();
let mut matrix = Matrix{
spi,
devices: 4, // 4 displays chained together, not working rn
decode_mode: DecodeMode::NoDecode
};
matrix.power_on();
matrix.send_command(0x00, Command::ScanLimit, 0x07);
matrix.draw_raw(0x00, &[
0b1001001,
0b0110110,
0b1001001,
0b0110110,
0b1001001,
0b0110110,
0b1001001,
0b0110110
]);
sleep(Duration::from_secs(1));
matrix.power_off();
但它显示在第一个和第四个显示器上,我仍然无法单独控制它们。
推荐答案
因为我部分解决了问题,所以将其标记为已解决。
我打开了关于如何控制链接在一起的多个矩阵的updated question。
这篇关于如何控制链接在一起的4 8x8 LED矩阵,并使用Max7219供电?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文