【I2C】高效实现I2C寄存器读取函数
根据你提供的软件I2C驱动代码,我来帮你实现 qst_sw_readreg()
函数。这个函数需要结合现有的 soft_iic_xxx()
系列函数,实现从I2C设备指定寄存器读取数据的功能。
函数实现
/*** qst_sw_readreg - 从I2C设备的指定寄存器读取数据* @slave_addr: I2C从机地址(已经左移1位,包含读写位)* @reg_add: 目标寄存器地址* @buf: 读取数据的缓冲区* @num: 要读取的字节数* * 返回值:* >=0 - 成功读取的字节数* -1 - 读取失败(未接收到ACK或参数错误)*/
qs32 qst_sw_readreg(qu8 slave_addr, qu8 reg_add, qu8 *buf, qs32 num)
{u8 i2c_addr_write = slave_addr & 0xFE; // 写操作地址(最低位为0)u8 i2c_addr_read = slave_addr | 0x01; // 读操作地址(最低位为1)soft_iic_dev iic = 0; // 假设使用第一个I2C控制器// 检查输入参数if (slave_addr == 0 || !buf || num <= 0) {return -1;}// 步骤1:发送起始信号 + 从机地址(写模式) + 寄存器地址soft_iic_start(iic);// 发送从机地址(写模式)if (!soft_iic_tx_byte(iic, i2c_addr_write)) {soft_iic_stop(iic); // 发送停止信号return -1;}// 发送要读取的寄存器地址if (!soft_iic_tx_byte(iic, reg_add)) {soft_iic_stop(iic); // 发送停止信号return -1;}// 步骤2:发送重复起始信号 + 从机地址(读模式) + 读取数据soft_iic_start(iic); // 重复起始信号// 发送从机地址(读模式)if (!soft_iic_tx_byte(iic, i2c_addr_read)) {soft_iic_stop(iic); // 发送停止信号return -1;}// 读取数据qs32 bytes_read = soft_iic_read_buf(iic, buf, num);// 发送停止信号soft_iic_stop(iic);return bytes_read; // 返回实际读取的字节数
}
函数说明
-
参数处理:
slave_addr
是已经左移1位的从机地址,通过& 0xFE
得到写操作地址,通过| 0x01
得到读操作地址。reg_add
是目标寄存器地址,buf
是存储读取数据的缓冲区,num
是要读取的字节数。
-
通信流程:
- 步骤1:发送起始信号 → 从机地址(写模式) → 寄存器地址。
- 步骤2:发送重复起始信号 → 从机地址(读模式) → 读取
num
字节数据。 - 最后发送停止信号结束通信。
-
返回值:
- 返回实际成功读取的字节数(应该等于
num
)。 - 返回-1表示读取失败(任何步骤未收到ACK或参数错误)。
- 返回实际成功读取的字节数(应该等于
I2C读取流程说明
从I2C设备读取指定寄存器数据的标准流程是:
- 发送起始信号 (
START
) - 发送从机地址(写模式)
- 发送要读取的寄存器地址
- 发送重复起始信号 (
REPEATED START
) - 发送从机地址(读模式)
- 读取数据
- 发送停止信号 (
STOP
)
这个函数严格遵循了上述流程,确保能够正确读取I2C设备中的寄存器数据。