【问题标题】:Write data to SSD1306 via I2C通过 I2C 向 SSD1306 写入数据
【发布时间】:2017-06-18 06:16:10
【问题描述】:

我正在使用 SSD1306 OLED,对此有疑问。

当通过 I2C 向其缓冲区写入数据时,一些库每次写入 16 个字节。

例如:

void SSD1306::sendFramebuffer(const uint8_t *buffer) {
  // Set Column Address (0x00 - 0x7F)
  sendCommand(SSD1306_COLUMNADDR);
  sendCommand(0x00);
  sendCommand(0x7F);
  // Set Page Address (0x00 - 0x07)
  sendCommand(SSD1306_PAGEADDR);
  sendCommand(0x00);
  sendCommand(0x07);
  for (uint16_t i = 0;i < SSD1306_BUFFERSIZE;) {
    i2c.start();
    i2c.write(0x40);
    for (uint8_t j = 0;j < 16; ++j, ++i) {
      i2c.write(buffer[i]);
    }
    i2c.stop();
  }
}

他们为什么不直接写1024字节呢?

【问题讨论】:

  • 不是硬件问题。一些(Arduino)I²C 库只是缓冲您提供给它们的数据,直到您结束传输。为了避免过度使用缓冲区,发送较小的块可能是有意义的。
  • mmmmar,感谢您接受我的回答。如果您也按向上箭头来投票,您的操作将使其他人更容易找到此答案。
  • LCD 本身对 I2C 传输没有限制(限制是在 ARDUINO 端的 SW I2C 实现)您可以一次复制整个 VRAM ...但是它具有与 ARDUINO SW I2C lib 相同的硬件错误(每个数据包发送一次 ACK 信号,而不是每个字节一次)LCD 无法使用正确的硬件/软件 I2C 实现。必须自己做才能解决 AVR32 上的这个问题(花了我几周时间来分析发生了什么)而且它没有用于重置 VRAM 地址指针的命令,使其在长期使用中不可靠,因为任何传输损坏都会将图像转移到 VCC电源开/关。

标签: arduino avr led


【解决方案1】:

我见过的大多数 I2C 库的源代码,包括 Aruduino 的源代码,都以这种方式分块数据。虽然 I2C 标准不要求这样做,但正如其他海报所提到的,可能存在缓冲区考虑。此处的.stop() 命令可能会通知设备处理刚刚发送的 16 个字节并准备更多。

总是,您需要阅读设备的数据表并了解它需要什么才能正确显示。他们在软件中说“RTFM”,但硬件至少同样无情。与外部硬件设备连接时,您必须阅读并遵循数据表。

【讨论】:

    【解决方案2】:

    当接收设备没有足够的缓冲区空间或速度不足以以全速率消化数据时,将数据分割成更多帧会有所帮助。 START/STOP 方法可能会给接收设备一点时间来处理接收到的数据。在您的特定情况下,16 字节块似乎正好是显示的一行。

    分段传输的其他原因是多主机操作,但这里似乎并非如此。

    【讨论】:

    • 只需将数据流式传输到其 DRAM,SSD1306 就会以支持的最大总线速度接受任意数量的数据。 (英国电信,德国电信)
    • 在这种特殊情况下,当我们谈论的是在修改刚刚传输到屏幕的行时容易出现屏幕闪烁的显示器,您也可以很容易地通过以下方式规避这一点逐行发送信息。
    • 不。 - 此外,SSD1306 的 DRAM 不是按行排列的。
    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2022-07-13
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    相关资源
    最近更新 更多