esp32c3 运行 Rust(八)
上篇已经完成了 SSD1306 基本操作已经封装完成,将使用 embedded_graphics crate 在 SSD1306 上显示文字和图案。
环境
-
OS: Ubuntu 20.04.4 LTS
-
Rust: rustc 1.62.0-nightly
-
IDE: VsCode
-
ESP32C3: ESP-C3-13-Kit 开发板
-
SSD1306: 0.96 寸 OLED 模块
使用到的 GPIO
| GPIO | title |
|---|---|
| GPIO4 | SDA |
| GPIO5 | SCL |
embedded_graphics
embedded_graphics 是一个嵌入式 2D 图形库,embedded_graphics 的核心目标是在不使用任何缓冲区的情况下绘制图形。该库无需动态内存分配器即可工作,并且无需预先分配大块内存。为了实现这一点,它采用了一种基于方法,其中像素颜色和位置是动态计算的,并且保存状态最小。这允许使用的应用程序使用更少的 RAM,而性能几乎不会受到影响。
创建项目
使用上篇创建的项目工程。
-
为
ssd1306实现DrawTargettraitembedded_graphicscrate 不包含驱动程序,因此需要为 ssd1306 实现DrawTargettrait-
安装 embedded_graphics
# ... [dependencies] # ... embedded-graphics = "0.7.1" -
实现
DrawTargettraituse embedded_graphics::{ draw_target::DrawTarget, pixelcolor::BinaryColor, geometry::{Size, OriginDimensions, Dimensions}, Pixel, }; impl<Adapter, SIZE> OriginDimensions for SSD1306<Adapter, SIZE, FrameBuffer<SIZE>> where Adapter: I2CInterface, SIZE: DisplaySize { fn size(&self) -> Size { let (w, h) = self.dimensions(); Size::new(w.into(), h.into()) } } impl<Adapter, SIZE> DrawTarget for SSD1306<Adapter, SIZE, FrameBuffer<SIZE>> where Adapter: I2CInterface, SIZE: DisplaySize, { type Color = BinaryColor; type Error = SSD1306Error; fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error> where I: IntoIterator<Item = Pixel<Self::Color>> { let box_ = self.bounding_box(); pixels .into_iter() .filter(|Pixel(pos, _color)| box_.contains(*pos)) .for_each(|Pixel(pos, color)| self.set_pixel(pos.x as u32, pos.y as u32, color.is_on())); Ok(()) } }
-
-
显示文字
-
引入相关依赖
use embedded_graphics::{ mono_font::{ascii::FONT_6X10, MonoTextStyle}, pixelcolor::BinaryColor, prelude::*, text::Text, }; -
定义字体
let style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On); -
绘制文字
Text::new("Hello Rust!", Point::new(20, 30), style).draw(&mut display).unwrap(); -
刷新屏幕
display.flush().unwrap(); -
编译并上传
连接开发板,使用如下命令编译并上传
cargo espflash --release --monitor /dev/ttyUSB0
-
-
绘制直线
for i in 0..32 { Line::new(Point::new(0, i * 2), Point::new(128, i * 2)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) .draw(&mut display).unwrap(); display.flush().unwrap(); thread::sleep(Duration::from_millis(500)); } -
绘制矩形
let rect_style = PrimitiveStyleBuilder::new().stroke_color(BinaryColor::On).stroke_width(1).fill_color(BinaryColor::Off).build(); Rectangle::new(Point::new(0, 0), Size::new(128, 64)) .into_styled(rect_style) .draw(&mut display).unwrap(); display.flush().unwrap();