1 个不稳定版本
0.1.0 | 2023年12月19日 |
---|
#1843 在 嵌入式开发
22KB
203 行
lcd1602_gpio
通过GPIO连接树莓派和lcd1602 - 16x2液晶显示屏模块的抽象层
此用于控制lcd,无需额外的I2C控制器模块
总共使用8个引脚:1个+5v输出,1个地线和6个GPIO连接
通过发送4位两次来表示单个8位字符、ASCII符号或指令/命令进行通信-
目录
请阅读说明!!!
在尝试连接之前,您必须确保您理解lcd模块和树莓派上使用的引脚,错误的接线可能会损坏您的树莓派或/和lcd模块。
首先确保您的lcd模块与lcd1602模块具有相同的配置,其他模块可能不适用于本指南。
如何正确将lcd连接到pi的所有功劳归功于此指南 - mbtechworks.com
接线
LCD引脚 | LCD功能 | 连接到 | 树莓派引脚 |
---|---|---|---|
01 | VSS(地) | 面包板地 | |
02 | VDD(+5v) | 面包板+5v | |
03 | VO(对比度) | 电位器的中间引脚 | |
04 | RS | GPIO7 | 26 |
05 | RW | 面包板地 | |
06 | E | GPIO8 | 24 |
07 | D0 | ||
08 | D1 | ||
09 | D2 | ||
10 | D3 | ||
11 | D4 | GPIO25 | 22 |
12 | D5 | GPIO24 | 18 |
13 | D6 | GPIO23 | 16 |
14 | D7 | GPIO18 | 12 |
15 | A(+5V) | 面包板+5v | |
16 | K(地) | 面包板地 |
使用
安装
将crate添加到您的项目中
cargo add lcd1602_gpio
或将手动添加到Cargo.toml
[dependencies]
lcd1602_gpio = "0.1.0"
在crates.io/lcd1602_gpio上检查最新版本
基本使用
use std::error::Error;
use std::thread;
use std::time::Duration;
// Import the library
use lcd1602_gpio::{LCDController, LcdLine};
fn sleep(secs: u64) {
let delay = Duration::new(secs, 0);
thread::sleep(delay);
}
fn main() -> Result<(), Box<dyn Error>> {
// Create an LCD controller instance
// You can use the default pins specified in the README or specify your own pin configuration with LCDController::new()
let mut controller = LCDController::default().unwrap();
// Print LCD controller information
println!("{controller}");
for _ in 0..5 {
// Display text on the LCD
controller.display_text("Hello World!", LcdLine::Line1);
sleep(3);
controller.display_text("Hello Rustaceans", LcdLine::Line2);
sleep(5);
controller.clear_screen();
sleep(1);
}
Ok(())
}
高级使用
在单独的线程中使用LCDController
基本使用示例可能不适合您的需求,因为它会锁定主线程,例如,如果您可能想要记录一些传感器数据并将其显示在lcd显示屏上,则程序必须等待lcd更新才能进行进一步处理。在这种情况下,您可能希望使用单独的线程中的LCDController。
use std::error::Error;
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
use lcd1602_gpio::{LCDController, LcdLine};
enum LCDCommand {
DisplayText(String, LcdLine),
ClearScreen,
Quit,
}
fn main() -> Result<(), Box<dyn Error>> {
// Create an LCD controller instance and wrap it in a mutex
let shared_controller = Arc::new(Mutex::new(LCDController::default()?));
// Create a channel for communication between main thread and LCD thread
let (lcd_tx, lcd_rx) = mpsc::channel();
// Clone the Arc to send to the LCD thread
let shared_controller_clone = shared_controller.clone();
// Spawn a new thread for handling the LCD
let lcd_thread = thread::spawn(move || {
for command in lcd_rx {
match command {
LCDCommand::DisplayText(text, line) => {
let mut controller = shared_controller_clone.lock().unwrap();
controller.display_text(&text, line);
}
LCDCommand::ClearScreen => {
let mut controller = shared_controller_clone.lock().unwrap();
controller.clear_screen();
}
LCDCommand::Quit => {
// Cleanup and exit the thread
break;
}
}
}
});
// Continue with the main thread logic here
// ...
// Example: Send commands to the LCD thread
lcd_tx.send(LCDCommand::DisplayText(
"Hello World!".to_string(),
LcdLine::Line1,
))?;
thread::sleep(Duration::new(3, 0));
lcd_tx.send(LCDCommand::DisplayText(
"Hello Rustaceans".to_string(),
LcdLine::Line2,
))?;
thread::sleep(Duration::new(5, 0));
// Send a command to clear the screen
lcd_tx.send(LCDCommand::ClearScreen)?;
// Signal the LCD thread to quit
lcd_tx.send(LCDCommand::Quit)?;
// Wait for the LCD thread to finish before exiting
lcd_thread.join().unwrap();
Ok(())
}
常见问题(问答)
为什么我的显示显示错误的字符/符号?
这可能发生在您以错误顺序连接数据引脚或任何数据引脚短路的情况下,导致短路引脚同时将位注册为打开,而实际上只有一个打开,使用万用表检查并重新焊接引脚即可。
代码
本节对于使用该盒式音箱不是必需的,但有助于理解其背后的代码是如何工作的。
这些都是您需要理解pi和液晶显示屏之间通信的基础知识。通过复制相同的原理,您可以编写任何支持GPIO的语言中的相同模块。
引脚
基本来说,数据是通过数据引脚(D4,D5,D6,D7)发送的。
RS(寄存器选择)引脚控制显示屏的模式。
- 低 - 命令模式(数据被解释为命令)
- 高 - 字符模式(数据被解释为字符)和
RW(读/写)引脚选择显示屏的读或写模式
- 在这种情况下,我们将其连接到地线引脚,因为我们只发送数据而不读取任何内容。
E(使能)引脚在数据准备好时发送信号
4位通信
默认通信使用8位,需要连接所有8个数据引脚。在我们的场景中,我们以4位模式运行LCD显示屏,通过向显示屏发送命令(0x32)启用此模式。这样,我们可以减少连接到树莓派的引脚数量。
通信是通过首先将RS模式设置为命令或字符模式,然后以2-4位块的形式发送字符或命令,并在每个块之后切换E引脚来完成的,以表示数据已准备好被处理。
二进制 & 十六进制
首先,我们需要了解二进制如何转换为十六进制,这对于数据通过数据引脚发送至关重要,这将在引脚上转换为“低”代表0和“高”代表1。
(binary, hexadecimal, decimal)
// for the first digit of the hexadecimal
0000 0001 = 0x01 = 1
0000 0010 = 0x02 = 2
0000 0011 = 0x03 = 3
0000 0100 = 0x04 = 5
...
0000 1000 = 0x08 = 9
// for the second digit of the hexadecimal
0001 0000 = 0x10 = 16
0010 0000 = 0x20 = 32
0011 0000 = 0x30 = 48
0100 0000 = 0x40 = 64
...
1000 0000 = 0x80 = 128
// both digits
0001 0001 = 0x11 = 17
0001 0010 = 0x12 = 18
0010 0001 = 0x21 = 33
0010 0010 = 0x22 = 34
...
1001 1001 = 0x99 = 153
您可以看到十六进制的第一位代表二进制的前4位,第二位代表第二4位
十六进制的最大值是0x99,即十进制的153,这意味着您可以在8位十六进制中表示154个不同的值(因为0x00)
位运算
字符是如何转换为需要激活的引脚信号的?
字符的比较是通过逻辑AND运算符完成的,该运算符返回1,如果两个单独的位对都等于1
以字符“C”为例,它是0x43(十六进制)= 0100 0011(二进制)
"C" (0100 0011, 0x43)
// Low bits
0100 0011 = 0x43 &&
0000 0001 = 0x01
|||| |||| == equal
0000 0001 = 0x01
0100 0011 = 0x43 &&
0000 0010 = 0x02
|||| |||| == equal
0000 0010 = 0x02
0100 0011 = 0x43 &&
0000 0100 = 0x04
|||| |||| != not equal
0000 0000 = 0x00
0100 0011 = 0x43 &&
0000 1000 = 0x08
|||| |||| != not equal
0000 0000 = 0x00
// High bits
0100 0011 = 0x43 &&
0001 0000 = 0x10
|||| |||| != not equal
0000 0000 = 0x00
...
如果操作的结果等于等于1的位的引脚,则将引脚翻转至打开/高电平,表示4位(可以是高位或低位(0xHL)H-高,L-低)
参考
- 用于解决这个问题的方法 - mbtechworks.com
- 日立HD44780液晶控制器
- GPIO引脚分配
- rppal - 用于通过rust与树莓派的GPIO引脚进行接口的盒式音箱
- 十六进制到二进制转换器
依赖关系
~375KB