I2C 读
I2C 先写后读
其实所谓的 I2C 读,都是先写后读。
I2C spec 规定如下
详细解析如下(详细看图)
对从机进行读操作时,主设备发出开始标志 (S) 和读地址 (从机地址加一个 R/W 位,1 为读,0 为写)。等待从机产生应答信号。然后发送寄存器地址,告诉从机读哪一个寄存器。紧接着,收到应答信号后,主设备再发一个开始信号,然后发送从设备读地址。从机产生应答信号并开始发送寄存器数据。通信以主设备产生的拒绝应答信号 (NACK) 和结束标志 (P) 结束。
举例(例子进行了两次封装)
void ap3216c_readdata(struct ap3216c_dev *dev)
{
unsigned char i =0;
unsigned char buf[6];
/* 循环读取所有传感器数据 */
for(i = 0; i < 6; i++)
{
buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATALOW + i);
}
}
static unsigned char ap3216c_read_reg(struct ap3216c_dev *dev, u8 reg)
{
u8 data = 0;
ap3216c_read_regs(dev, reg, &data, 1);
return data;
}
static int ap3216c_read_regs(struct ap3216c_dev *dev, u8 reg, void *val, int len)
{
int ret;
struct i2c_msg msg[2];
struct i2c_client *client = (struct i2c_client *)dev- >private_data;
/* msg[0]为发送要读取的首地址 */
msg[0].addr = client- >addr; /* ap3216c地址 */
msg[0].flags = 0; /* 标记为发送数据 */
msg[0].buf = ® /* 读取的首地址 */
msg[0].len = 1; /* reg长度*/
/* msg[1]读取数据 */
msg[1].addr = client- >addr; /* ap3216c地址 */
msg[1].flags = I2C_M_RD; /* 标记为读取数据*/
msg[1].buf = val; /* 读取数据缓冲区 */
msg[1].len = len; /* 要读取的数据长度*/
ret = i2c_transfer(client- >adapter, msg, 2);
if(ret == 2) {
ret = 0;
} else {
printk("i2c rd failed=%d reg=%06x len=%dn",ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
设备
+关注
关注
2文章
4172浏览量
69260 -
I2C
+关注
关注
28文章
1346浏览量
120818
发布评论请先 登录
相关推荐
求问:proteus的i2c主模式的问题。
最近我用proteus仿真pic16f1828单片机,用i2c功能写入一串数据给24c02c,然后读出来。波形和显示都是正常的,就是时钟频率有点蹊跷:设置的sspadd=9,晶振时钟4m。按照公式
发表于 12-09 22:28
什么是软件I2C和硬件I2C
学习I2C总线通信协议,完成基于I2C硬件协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出。具体任务:1)解释什么是“软件I2C”和“硬件I2C”? (阅读野
发表于 08-23 06:19
评论