OpenHarmony API-WifiIotI2cData 封装I2C收发数据结构体 作者:马育民 • 2025-10-07 20:02 • 阅读:10005 # 介绍 `WifiIotI2cData` 结构体是鸿蒙物联网(IoT)开发中用于 **I2C双向通信的数据封装结构**,通常在鸿蒙物联网设备(如智能传感器、小型 OLED 屏等通过 I2C 协议连接的硬件)开发中使用。 适合全双工或半双工场景中同时处理收发操作。 ### 头文件 ``` base\iot_hardware\interfaces\kits\wifiiot_lite\wifiiot_i2c.h ``` ``` #include "wifiiot_i2c.h" ``` ### 定义 ``` /** * @brief Defines I2C data transmission attributes. */ typedef struct { /** Pointer to the buffer storing data to send */ unsigned char *sendBuf; /** Length of data to send */ unsigned int sendLen; /** Pointer to the buffer for storing data to receive */ unsigned char *receiveBuf; /** Length of data received */ unsigned int receiveLen; } WifiIotI2cData; ``` # 说明 `WifiIotI2cData` 用于封装 I2C 通信中需要发送或接收的数据,包含 `数据缓冲区(存储实际传输的字节)` 和 `数据长度(字节数)` 两个核心成员。 ### 结构体成员详解 | 成员名 | 类型 | 作用说明 | |--------------|----------------|--------------------------------------------------------------------------| | `sendBuf` | `unsigned char *` | 指向发送缓冲区的指针,存储需要通过I2C总线发送到外设的数据(如指令、配置参数)。 | | `sendLen` | `unsigned int` | 发送数据的长度(单位:字节),即 `sendBuf` 中有效数据的字节数。 | | `receiveBuf` | `unsigned char *` | 指向接收缓冲区的指针,用于存储从I2C外设读取到的数据(如传感器采集值、状态信息)。 | | `receiveLen` | `unsigned int` | 接收数据的长度(单位:字节):- 输入时:表示期望从外设接收的字节数;- 输出时:表示实际接收到的字节数(由驱动填充)。 | ### 使用场景 在与支持读写操作的I2C外设(如带寄存器的传感器、OLED屏)通信时,该结构体可一次完成“发送指令+接收响应”的过程。例如,从I2C温湿度传感器读取数据: # OLED屏幕显示参数解释 将写数据到 I2C OLED屏幕的操作封装成函数 ``` #include "wifiiot_i2c.h" /* cmdType:指令类型:0x00表示写指令,0x40表示写数据 data:数据。 当cmdType是0x00时,data表示指令内容 当cmdType是0x40时,data表示显示的内容 */ static uint32_t Write(uint8_t cmdType, uint8_t data) { uint8_t buffer[] = {cmdType, data}; WifiIotI2cData i2cData = {0}; i2cData.sendBuf = buffer; i2cData.sendLen = sizeof(buffer)/sizeof(buffer[0]); return I2cWrite(WIFI_IOT_I2C_IDX_0, 0x78, &i2cData); } ``` ### 设置起始页 从哪一页开始显示数据 >显示屏有64行像素时,又分为8页,每页8行 ``` Write(0x00,0xb0 + page) ``` - `0x00`:表示写命令 - `0xb0 + page`: `page` 范围 `0~7`,`page` 为 `0` 表示从第一页开始显示,`page` 为 `1` 表示从第二页开始显示,以此类推 ### 设置起始列 从哪一列开始显示数据 ``` Write(((x & 0xF0) >> 4) | 0x10); // 列地址高4位 Write(x & 0x0F); // 列地址低4 ``` - `x`:横向位置,范围 `0~127`,对应 OLED 的 128 列像素 ### `Write(((x & 0xF0) >> 4) | 0x10);` 解释 - **功能**:设置列地址的“高4位”(确定列坐标的高半部分)。 - **指令解析**: - `x` 是列坐标(0~127),二进制表示为8位(如 `x=30` 对应二进制 `00011110`)。 - `x & 0xF0`:保留 `x` 的高4位,清除低4位。例如 `x=30` 时,`30 & 0xF0 = 00010000`(二进制)。 - `>> 4`:将高4位右移4位,得到一个0~15的数值。例如 `00010000 >> 4 = 00000001`(二进制,即十进制1)。 - `| 0x10`:与基础指令 `0x10` 组合,得到最终的列地址高4位指令。例如 `1 | 0x10 = 0x11`(二进制 `00010001`)。 - **作用**:OLED的列地址是8位(0~127),但需要分两次发送(高4位+低4位),这是OLED的通信协议规定的。 ### `OledSendCmd(x & 0x0F);` 解释 - **功能**:设置列地址的“低4位”(确定列坐标的低半部分)。 - **指令解析**: - `x & 0x0F`:保留 `x` 的低4位,清除高4位。例如 `x=30` 时,`30 & 0x0F = 00001110`(二进制,即十进制14)。 - 该结果直接作为指令发送,与上一条“高4位指令”组合,形成完整的8位列地址。 - **示例**:`x=30` 时,高4位指令为 `0x11`,低4位指令为 `0x0E`,组合后得到完整列地址 `0x1E`(即十进制30)。 ### 总结 1. 先通过 `0xB0 + page` 指令告诉OLED:“后续数据从第`page`页开始显示”(确定纵向位置)。 2. 再通过两条列地址指令告诉OLED:“在该页中,从第`x`列开始显示”(确定横向位置)。 设置完成后,发送的点阵数据,会从这个指定的`(x, page)`位置开始显示,从而实现“在OLED的任意行列位置显示内容”的功能。 原文出处:http://malaoshi.top/show_1GW200V68QBl.html