2个版本
0.1.1 | 2024年8月9日 |
---|---|
0.1.0 | 2024年8月8日 |
#227 in 嵌入式开发
196 每月下载量
22KB
380 行
ILI9341 LCD Spi驱动
基于ILI9341的Waveshare 2、4"板的设备无关LCD驱动
no_std
和 embedded_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