如何控制链接在一起的4 8x8 LED矩阵,并使用Max7219供电? [英] How to control 4 8x8 led matrices that are chained together and are powered with the Max7219?

查看:10
本文介绍了如何控制链接在一起的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆