7个版本
0.2.0 | 2024年4月13日 |
---|---|
0.1.6 | 2023年4月24日 |
0.1.2 | 2022年12月28日 |
110 在 嵌入式开发 中
342 每月下载量
37KB
632 代码行
liquid_crystal
liquid crystal 是一个模块化库,用于与HD44780控制器兼容的字母数字LCD显示器,使用Rust和Embedded_hal API编写
如何使用
第一步
首先,您必须选择一个显示通信接口,该库提供两个内置接口,并行和I2C(您可以在此处 创建自己的接口)
然后,您必须选择通信中的位数,可以是:Bus4Bits或Bus8Bits
最后,您必须选择一个布局(您可以在此处 创建自己的布局)
let mut lcd_interface = Parallel::new(D4, D5, D6, D7, rs, en, en2);
let mut lcd = LiquidCrystal::new(&mut interface, Bus4Bits, LCD16X2);
(默认情况下,LCD实现使用阻塞延迟,使用async
方法创建具有异步支持的LCD,请记住在库功能中启用异步)
并非所有接口都支持8位通信,但所有支持8位通信的接口都可以支持4位
发送命令和文本
(这可能在将来发生变化,请参阅此处)
首先,您必须配置显示。
为此,您必须调用“begin”函数。(您可以直接使用低级“send”函数进行配置,如果您不了解如何配置HD44780,则不推荐这样做)
lcd.begin(&mut delay);
您可以通过“write”函数发送文本和命令,该函数接收来自延迟函数的引用和一个名为“SendType”的枚举,可以是文本或命令
要发送文本,传递一个 &str 到“Text”变体
要发送命令,从命令列表中传递一个命令到“Command”变体
lcd.write(&mut delay,Command(Clear))
.write(&mut delay,Text("hello World!"));
您可以通过“CustomChar”变体发送自定义字符,但首先您需要通过“custom_char”函数创建自定义字符,该函数接收与所有其他函数相同的延迟,一个指向大小为8的u8数组的引用以及它将占据的插槽
HD44780 允许您创建 8 个自定义字符(槽位 0 - 7),您可以在任何时间创建和修改这些槽位,但一次只能同时在显示屏上写入 8 个不同的字符。(创建这些字符会将显示屏返回到初始位置,然后在创建这些字符后使用 "set_cursor")
使用带字符槽位的 CustomChar 变体来发送
let lightning: [u8; 8] = [0x03, 0x06, 0x0C, 0x1F, 0x1F, 0x03, 0x06, 0x0C];
lcd.custom_char(&mut delay, &lightning, 0);
lcd.write(&mut delay, CustomChar(0));
示例
#![no_std]
#![no_main]
use panic_halt as _;
use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*};
use liquid_crystal::{prelude::*};
use liquid_crystal::Parallel;
#[entry]
fn main() -> ! {
//Rust logo
let rust1: [u8; 8] = [0b00001,0b00011,0b00011,0b01110,0b11100,0b11000,0b01000,0b01000];
let rust2: [u8; 8] = [0b10001,0b11111,0b00000,0b00000,0b11110,0b10001,0b10001,0b11110];
let rust3: [u8; 8] = [0b10000,0b11000,0b11000,0b01110,0b00111,0b00011,0b00010,0b000010];
let rust4: [u8; 8] = [0b01000,0b01000,0b11000,0b11100,0b01110,0b00011,0b00011,0b00001];
let rust5: [u8; 8] = [0b11000,0b10100,0b10010,0b00000,0b00000,0b00000,0b11111,0b10001];
let rust6: [u8; 8] = [0b00010,0b00010,0b00011,0b00111,0b01110,0b11000,0b11000,0b10000];
let cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let mut gpioc = dp.GPIOC.split();
let mut gpioa = dp.GPIOA.split();
let en = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
let rs = gpioc.pc14.into_push_pull_output(&mut gpioc.crh);
let d4 = gpioc.pc15.into_push_pull_output(&mut gpioc.crh);
let d5 = gpioa.pa0.into_push_pull_output(&mut gpioa.crl);
let d6 = gpioa.pa1.into_push_pull_output(&mut gpioa.crl);
let d7 = gpioa.pa2.into_push_pull_output(&mut gpioa.crl);
let mut delay = cp.SYST.delay(&clocks);
let mut lcd_interface = Parallel::new(d4, d5, d6, d7, rs, en, lcd_dummy);
let mut lcd = LiquidCrystal::new(&mut lcd_interface, Bus4Bits, LCD16X2);
lcd.begin(&mut delay);
lcd.custom_char(&mut delay, &rust1, 0);
lcd.custom_char(&mut delay, &rust2, 1);
lcd.custom_char(&mut delay, &rust3, 2);
lcd.custom_char(&mut delay, &rust4, 3);
lcd.custom_char(&mut delay, &rust5, 4);
lcd.custom_char(&mut delay, &rust6, 5);
lcd.write(&mut delay,Text("hello World!"))
.write(&mut delay,Command(MoveLine2))
.write(&mut delay,Text("made in Rust!"));
lcd.set_cursor(&mut delay, 0, 13)
.write(&mut delay, CustomChar(0))
.write(&mut delay, CustomChar(1))
.write(&mut delay, CustomChar(2));
lcd.set_cursor(&mut delay, 1, 13)
.write(&mut delay, CustomChar(3))
.write(&mut delay, CustomChar(4))
.write(&mut delay, CustomChar(5));
loop {}
}
创建自己的接口
要创建自己的接口,您必须实现包含 "send" 函数的 "Interface" Trait
"send" 函数接收两个 u8 参数,"data" 和 "config",其中它们的位表示
位 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0 |
---|---|---|---|---|---|---|---|---|
DATA | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
CONFIG | 保留 | 保留 | 保留 | 保留 | EN2 | EN | R/W | RS |
(目前还没有读取功能,所以将 R/W 引脚拉低)(Reserved
对应于 I2C 模块中的显示屏背光)
其中 0 和 1 表示引脚的状态 1:HIGH 0:LOW 将位连接到相应的端口,并祝贺您已创建自己的接口
(要使用 PCF8574,您可以复制此行 let package = (config & 0b00000111) | (data & 0xF0) | 0x08;
并通过您选择的 I2C 库发送它)
命令列表
Clear
清除显示屏
Reset
重置显示屏的内部变量
ShiftCursotLeft
将光标移到左边
ShiftCursotRight
将光标移到右边
ShiftDisplayLeft
将显示屏向左移动
ShiftDisplayRight
将显示屏向右移动
MoveLine1
将光标移动到控制器的第一行开头
MoveLine2
将光标移动到控制器的第二行开头
配置函数
echo
启用所有显示屏
select_lcd
选择显示屏(0 = EN1 | 1 = EN2)
enable_blink
启用闪烁光标
enable_cursor
启用光标
enable_display
启用显示屏
enable_autoscroll
启用自动滚动
disable_blink
禁用闪烁光标
disable_cursor
禁用光标
disable_display
禁用显示屏
disable_autoscroll
禁用自动滚动
set_autoscroll_increment
自动滚动增加位置
set_autoscroll_decrement
自动滚动减少位置
update_config
将配置发送到显示屏
布局
您可以使用 Layout 结构体创建自定义布局。
创建自定义布局非常有用,如果您想使用数字字母 LCD 创建用户界面。
HD44780 支持总共 2 行和最多 40 列,每行都有一个地址。
行 1 = 0x80 行 2 = 0xC0
许多 LCD 将这些行和列重新排列以更改布局,例如
针对20X4显示屏的工作,每行的40列分为两个20列,访问它需要使用行地址加上20的偏移量,因此行组织如下
行1 = 0x80 行2 = 0xC0 行3 = 0x80 + 20 行4 = 0xC0 + 20
您可以使用struct Layout创建它!
Layout接受两个泛型参数COLUMNS和LINES,在这个struct内部有一个u8数组和LINE大小
每个位置代表Layout中的一行,只需按照下面的示例放置地址即可
const LCD16X2: Layout<16,2> = Layout{
addrs: [0x80, 0xC0],
};
const LCD20X4: Layout<20,4> = Layout{
addrs: [0x80, 0xC0, 0x80+20, 0xC0+20],
};
(注意,如果您不想使用所有40列,则不必使用)
为什么是这个API?
我长期使用lcd显示屏,每次需要使用一些IO扩展器时,我总是需要重写驱动程序,因为当前API没有提供简单的通信移植方式。
此API目前是使用嵌入式_hal进行个人测试,当前语法可能会根据用户反馈而更改。
-
"write"方法可能被分成几个函数,包括新的写入数据方法,就像其C++版本:"omnicrystal"(Arduino)和UniversalLCD。
-
正在审查对使用保留的"config"位进行用户自定义功能的支持(这个主要想法是多色显示屏的使用)
依赖项
~62KB