繁体   English   中英

AVR Atmega168 I2C LCD不想初始化

[英]AVR Atmega168 I2C LCD does not want to initialize

我正在使用 I2C 转换器将数据发送到我的液晶显示器。 转换器基于PCF85741,lcd为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();
}

液晶显示器

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 应该是 4bit 模式,有 2 行,但它不是 lcd 上的任何变化。

1)请说明你有什么 I2C 到并行的 IC? 我找不到 PCF85741 是什么,我只看到PCF8574 和 PCF8574A 的数据表。

在第一种情况下,从地址将为(包括 r/w 位)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 (0x28) 来轻松检测 IC 是否应答。 (请参阅数据表部分19.8.1 主发送器模式第 186-188 页)

或者,更简单地说,如果您将 PCF8574 的 P3 连接到背光,您可以尝试输出0x08 / 0x00以查看背光是否打开和关闭。

3)有关初始化序列,请查看HD44780 数据表第 46 页的图 24 4 位接口注意位 DB5 和 DB4 为高。 另外,请注意,由于您只是在写入显示控制器,因此位R/W (即输出的位 1)应始终为零(注意您发送的是wi_write_byte(0x03);然后是twi_write_byte(0x02);位 1 设置为高)。

该示例可能如下所示:

void send4bits(uint8_t fourbits, bool is_cmd) {
  uint8_t d = (fourbits << 4) | 0b1000;
  if (!is_cmd) d |= 1;
  twi_write_byte(d | 0b100); // E high
  twi_write_byte(d);         // E low
}

void sendcmd(uint8_t cmd) {
  send4bits(cmd >> 4, true);
  send4bits(cmd & 0xF, true);
}

void senddata(uint8_t cmd) {
  send4bits(cmd >> 4, false);
  send4bits(cmd & 0xF, false);
}


// initialization sequence

send4bits(0b0011, true);
_delay_ms(5);
send4bits(0b0011, true);
_delay_ms(1);
send4bits(0b0011, true);
// since I2C is slow enough the required 100us pause already happened here
send4bits(0b0010, true);

sendcmd(0b00101000);
sendcmd(0b00001000);
sendcmd(0b00000001);
delay_ms(2);
sendcmd(0b00000110);

sendcmd(0b00001110);

// Initialization is done

sendcmd(0x80); // Set cursor at the beginning
for (uint8_t i = 'A' ; i <= 'Z' ; i++) {
  senddata(i); // Send some random data
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM