通过I2C将数据写入16x2 LCD的协议

时间:2017-06-29 23:32:41

标签: arduino i2c

我是电子新手,已经完成了如何使用liquidCrystal_I2C在Arduino中通过I2C操作16x2字符LCD的教程。一切正常,但我对I2C和LCD之间的低级别交互有疑问。看一下该库的源代码,我注意到当写入4位半字节(LiquidCrystal_I2C::write4bits)时,代码首先将半字节写入I2C扩展器 (LiquidCrystal_I2C::expanderWrite),然后在脉冲使能位时再次写 。为什么第一个expanderWrite是必要的?为什么写4位只能调用pulseEnable(设置blacklight位)?

我确信有一个原因,因为我检查了像RPLCD这样的其他库并看到了类似的模式。任何人都可以开导我吗?谢谢。

1 个答案:

答案 0 :(得分:0)

datasheet我发现LCD需要通信协议中的特定时序。 在使能线的上升沿,寄存器选择和读/写线必须已经为tsu1(100ns)稳定。在使能线的下降沿,数据必须已经为tsu2(60ns)确定。通过写_data,他们也在编写RS和R / W行,因为它们是_data的低位半字节。

This article非常详尽地介绍了这个主题。

TimingDiagram

//**** 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
}