#embedded-hal-driver #waveshare #driver #display #spi-driver #no-alloc

no-std lcd-ili9341-spi

ILI9341 SPI LCD的嵌入式_hal 驱动,兼容Waveshare 2、4英寸板

2个版本

0.1.1 2024年8月9日
0.1.0 2024年8月8日

#227 in 嵌入式开发

Download history 146/week @ 2024-08-03 50/week @ 2024-08-10

196 每月下载量

MIT 许可证

22KB
380

ILI9341 LCD Spi驱动

crates.io Documentation

基于ILI9341的Waveshare 2、4"板的设备无关LCD驱动

no_stdembedded_hal=1.0 兼容。

目前支持

  • 矩形/线条绘制
  • 精灵缓冲区渲染
  • 基本文本渲染(通过text功能)
  • 背光等级设置(通过PWM引脚)

文本渲染

由于文本渲染需要嵌入式字体,因此它已隐藏在功能标志后面,以在不需要时节省内存。字体支持基本ASCII范围:代码32 - 128(每个字符占用8字节)。

所需硬件连接

  • SPI:实现 SpiBus(来自 embedded_hal)
  • DC引脚:数据/命令选择器 - 数字引脚
  • RST引脚:设备复位 - 数字引脚
  • BL引脚:背光等级 - PWM引脚

Arduino Uno 示例

#![no_std]
#![no_main]
#![feature(abi_avr_interrupt)]

use arduino_hal::prelude::*;
use arduino_hal::simple_pwm::*;
use arduino_hal::spi;
use core::panic::PanicInfo;
use lcd_ili9341_spi::{
    Lcd, rgb_to_u16, rgb_to_u8, LcdOrientation
};

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);

    let spi_settings = spi::Settings {
        data_order: spi::DataOrder::MostSignificantFirst,
        clock: spi::SerialClockRate::OscfOver2,
        mode: embedded_hal::spi::MODE_0,
    };

    let (mut arduino_spi, _) = arduino_hal::Spi::new(
        dp.SPI,
        pins.d13.into_output(),        
        pins.d11.into_output(),
        pins.d12.into_pull_up_input(),
        pins.d10.into_output(),
        spi_settings
    );
    
    let timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Direct);
    let mut bl_pin = pins.d9.into_output().into_pwm(&timer1);
    bl_pin.enable();

    let mut lcd = Lcd::new(
            arduino_spi,
            pins.d7.into_output(),
            pins.d8.into_output(),
            bl_pin
        )
        .with_orientation(LcdOrientation::Rotate90);

    let mut delay = arduino_hal::Delay::new();
    let _ = lcd.init(&mut delay);

    let _ = lcd.set_backlight(140);

    // Make the screen black
    let _ = lcd.clear(0x0000);
    // Draw magenta rect
    lcd.fill_rect(10, 10, 20, 30, rgb_to_u16(255, 0, 255));
    // Draw blue-ish horizontal line
    lcd.fill_rect(0, 50, 320, 1, rgb_to_u16(0, 128, 255));

    // Draw 4x4 px red-black checker
    let (red_h, red_l) = rgb_to_u8(255, 0, 0);
    let sprite = [
        red_h, red_l, red_h, red_l, 0, 0, 0, 0,
        red_h, red_l, red_h, red_l, 0, 0, 0, 0,
        0, 0, 0, 0, red_h, red_l, red_h, red_l,
        0, 0, 0, 0, red_h, red_l, red_h, red_l,
    ];

    lcd.draw_sprite(50, 70, 4, 4, &sprite);

    loop {
        arduino_hal::delay_ms(100);
    }
}

Raspberry Pi 示例

use lcd_ili9341_spi::{rgb_to_u16, rgb_to_u8, Lcd, LcdOrientation};
use rppal::gpio::Gpio;
use rppal::hal::Delay;
use rppal::pwm::{Channel, Polarity, Pwm};
use rppal::spi::{Bus, Mode, Segment, SlaveSelect, Spi};

fn main() {
    let dc_pin = Gpio::new().unwrap().get(25).unwrap().into_output();
    let rst_pin = Gpio::new().unwrap().get(27).unwrap().into_output();
    let bl_pin = PwmHal(Pwm::with_frequency(Channel::Pwm0, 512.0, 0.5, Polarity::Normal, true).unwrap()); 

    let mut pi_spi = Spi::new(
        Bus::Spi0,
        SlaveSelect::Ss0,
        8_000_000,
        rppal::spi::Mode::Mode0,
    )
    .unwrap();

    let mut lcd = Lcd::new(pi_spi, dc_pin, rst_pin, bl_pin);
    let mut delay = Delay::new();
    let _ = lcd.init(&mut delay);

    let _ = lcd.set_backlight(140);

    // Make the screen black
    let _ = lcd.clear(0x0000);
    // Draw magenta colored rect
    lcd.fill_rect(10, 10, 20, 30, rgb_to_u16(255, 0, 255));
    // Render text
    lcd.draw_text(10, 120, "RustberryPi", rgb_to_u16(0, 128, 255), 0x0000, 2);

    std::thread::sleep(std::time::Duration::from_secs(15));
}

// SetDutyCycle impl is missing in the rppal crate?
struct PwmHal(Pwm);
impl embedded_hal::pwm::SetDutyCycle for PwmHal {
    fn max_duty_cycle(&self) -> u16 {
        255
    }
    fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
        self.0.set_duty_cycle(duty as f64 / 255.0);
        Ok(())
    }
}
impl embedded_hal::pwm::ErrorType for PwmHal {
    type Error = PwmError;
}

#[derive(Debug)]
struct PwmError;
impl embedded_hal::pwm::Error for PwmError {
    fn kind(&self) -> embedded_hal::pwm::ErrorKind {
        embedded_hal::pwm::ErrorKind::Other
    }
}

依赖项

~56KB