我正在使用I2C转换器将数据发送到我的LCD。 该转换器基于PCF85741,而液晶显示器为Hitachi hd44780。
PCF85741和LCD之间的端口映射如下:
P0-> RS
P1-> RW
P2-> E
P3->
P4-> D4
P5-> D5
P6-> D6
P7-> D7
文档说,我的从站的默认地址是0x20,但是带有RW位,我需要发送0x40。
这是我的代码:
void twi_start()
{
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA);
while (!(TWCR & (1 << TWINT)));
}
void twi_stop()
{
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
while (!(TWCR & (1 << TWSTO)));
}
void twi_write(uint8_t byte)
{
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
}
void twi_write_byte(uint8_t byte)
{
uint8_t SLAVE_ADDRESS = 0x40;
twi_start();
twi_write(SLAVE_ADDRESS);
twi_write(byte);
twi_stop();
}
LCD初始化
void lcd_init2()
{
for (int i = 0; i < 3; i++) {
twi_write_byte(0x03);
_delay_ms(20);
}
twi_write_byte(0x02);
_delay_ms(20);
//4 bit mode
twi_write_byte(0x24); // D5 -> 1, E -> 1
_delay_ms(10);
twi_write_byte(0x20); // D5 -> 1, E -> 0
_delay_ms(10);
//2 lines
twi_write_byte(0x24); // D5 -> 1, E -> 1
_delay_ms(10);
twi_write_byte(0x20); // D5 -> 1, E -> 0 first nibble
_delay_ms(10);
twi_write_byte(0x84); // D7 -> 1, E -> 1
_delay_ms(10);
twi_write_byte(0x80); // D7 -> 1, E -> 0 second nibble
_delay_ms(10);
}
此代码之后,lcd应该处于4位模式,有2行,但不是 LCD上没有任何变化。
答案 0 :(得分:1)
1)请说明您拥有的I2C并行IC?我找不到什么是PCF85741,我仅看到PCF8574 and PCF8574A的数据表。
在第一种情况下,从站地址为0x40 ... 0x4F(包括读/写位),在第二种情况下为0x70 ... 0x7F。
根据我的经验,这些显示器随附的常规I2C电路上面装有PCF8574A(即地址为0x7 *)。顺便说一下,那里的引脚3用于控制背光。
2)确保地址的低位?输入A0 A1 A2是否上拉或接地?
再次,根据我的经验,这些电路板通常具有上拉至+5的电阻,并且电路板上的可焊跳线将其接地。默认情况下,跳线不焊接,因此A0 A1 A2具有高逻辑电平,因此设备的I2C地址为 0x7E (写)/ 0x7F(读)。如果板上装有PCF8574T,则地址为 0x4E / 0x4F
通过在发送地址后检查TWSR寄存器(TWSR & TW_STATUS_MASK)
中的TWS位是否等于TW_MT_SLA_ACK
(0x18)或TW_MT_DATA_ACK
,可以轻松检测出IC是否已应答。数据字节发送后(0x28)。 (请参阅the datasheet部分 19.8.1主发送器模式第186-188页)
或者,更简单地说,如果将PCF8574的P3连接到背光,则可以尝试输出0x08
/ 0x00
,以查看背光是否打开和关闭。
3)有关初始化序列,请查看HD44780 datasheet第46页上的图24 4位接口
注意,DB5和DB4位为高。另外,请注意,由于您只写显示控制器,因此 R / W 位(即输出的位1)应始终为零(请注意,您发送的是{{1 }},然后将wi_write_byte(0x03);
的第1位设置为高)。
示例可能如下:
twi_write_byte(0x02);