通过 I2C 将数据写入 16x2 LCD 的协议
Protocol for writing data to 16x2 LCD via I2C
我是电子学新手,已完成有关如何使用 liquidCrystal_I2C 在 Arduino 中通过 I2C 操作 16x2 字符 LCD 的教程。一切正常,但我对 I2C 和 LCD 之间的低级交互有疑问。查看库的源代码,我注意到在编写 4 位半字节 (LiquidCrystal_I2C::write4bits
) 时,代码首先将半字节写入 I2C 扩展器
(LiquidCrystal_I2C::expanderWrite
),然后在对启用位施加脉冲时再次写入 。为什么第一个 expanderWrite
是必要的?为什么 write4bits 不能只调用 pulseEnable
(设置了 blacklight 位)?
我确定这是有原因的,因为我检查了 RPLCD 等其他库并看到了类似的模式。谁能启发我?谢谢。
从datasheet我发现LCD在通信协议中需要特定的时序。
在使能线的上升沿,寄存器 Select 和 Read/Write 线必须已经稳定为 tsu1 (100ns)。在使能线的下降沿,数据必须已经稳定为 tsu2 (60ns)。通过写 _data
他们也写了 RS 和 R/W 行,因为它们是 _data
.
的低半字节
This article 非常全面地涵盖了主题。
//**** From LiquidCrystal_I2C.h
// flags for backlight control
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100 // Enable bit
#define Rw B00000010 // Read/Write bit
#define Rs B00000001 // Register select bit
// ^--------Backlight bit defined above
// ^^^^---------Data bits
//**** From LiquidCrystal_I2C.cpp
void LiquidCrystal_I2C::write4bits(uint8_t value) {
expanderWrite(value);
pulseEnable(value);
}
void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
Wire.beginTransmission(_addr);
Wire.write((int)(_data) | _backlightval);
Wire.endTransmission();
}
void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
expanderWrite(_data | En); // En high
delayMicroseconds(1); // enable pulse must be >450ns
expanderWrite(_data & ~En); // En low
delayMicroseconds(50); // commands need > 37us to settle
}
我是电子学新手,已完成有关如何使用 liquidCrystal_I2C 在 Arduino 中通过 I2C 操作 16x2 字符 LCD 的教程。一切正常,但我对 I2C 和 LCD 之间的低级交互有疑问。查看库的源代码,我注意到在编写 4 位半字节 (LiquidCrystal_I2C::write4bits
) 时,代码首先将半字节写入 I2C 扩展器
(LiquidCrystal_I2C::expanderWrite
),然后在对启用位施加脉冲时再次写入 。为什么第一个 expanderWrite
是必要的?为什么 write4bits 不能只调用 pulseEnable
(设置了 blacklight 位)?
我确定这是有原因的,因为我检查了 RPLCD 等其他库并看到了类似的模式。谁能启发我?谢谢。
从datasheet我发现LCD在通信协议中需要特定的时序。
在使能线的上升沿,寄存器 Select 和 Read/Write 线必须已经稳定为 tsu1 (100ns)。在使能线的下降沿,数据必须已经稳定为 tsu2 (60ns)。通过写 _data
他们也写了 RS 和 R/W 行,因为它们是 _data
.
This article 非常全面地涵盖了主题。
//**** From LiquidCrystal_I2C.h
// flags for backlight control
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100 // Enable bit
#define Rw B00000010 // Read/Write bit
#define Rs B00000001 // Register select bit
// ^--------Backlight bit defined above
// ^^^^---------Data bits
//**** From LiquidCrystal_I2C.cpp
void LiquidCrystal_I2C::write4bits(uint8_t value) {
expanderWrite(value);
pulseEnable(value);
}
void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
Wire.beginTransmission(_addr);
Wire.write((int)(_data) | _backlightval);
Wire.endTransmission();
}
void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
expanderWrite(_data | En); // En high
delayMicroseconds(1); // enable pulse must be >450ns
expanderWrite(_data & ~En); // En low
delayMicroseconds(50); // commands need > 37us to settle
}