1 协议总结
开始:在SCL为高期间,SDA由高变低
结束:在SCL为高期间,SDA由低变高
应答:时钟脉冲9期间释放数据线,SCL为高期间,SDA读入为低电平
传输:在SCL为低电平期间,允许SDA变化,SCL变为高电平后,SDA必须稳定
写:设备地址+写控制字节 OK?--->内部寄存器地址 OK?---->写入数据
读:设备地址+写控制字节 OK?--->内部寄存器地址 OK?---->设备地址+读控制字节 OK?--->读入数据
写控制字节为0,读控制字节为1
2 gpio模拟注意点
(1) gpio的时钟clk会影响电平信号的建立时间,不宜过高
(2) 各个电平信号建立与维持时间需要遵循datasheet规定
(3) 主从设备的电平匹配需要注意,一般由io口上拉电平兼容设计
3 硬件i2c说明:
地址只有7bit,读写控制字单独.
从datasheet获取设备地址ADDR,硬件i2c填写地址为:addr = ADDR>>1;
linux下传输写法为:
(1) 写入
uint8_t *addr_buf;
struct i2c_msg msg;
addr_buf[0] = reg; //内部寄存器地址
memcpy(&addr_buf[1], data, len); //写入数据
msg.addr = client->addr;//设备地址
msg.flags = 0; //写控制字节
msg.buf = addr_buf; //内部寄存器地址
msg.len = len+1;
ret = i2c_transfer(client->adapter, &msg, 1);
(2) 读出
struct i2c_msg msg[2];
msg[0].addr = client->addr; //设备地址
msg[0].flags = 0; //写控制字节
msg[0].buf = ® //内部寄存器地址
msg[0].len = 1;
msg[1].addr = client->addr; //设备地址
msg[1].flags = I2C_M_RD; //读控制字节
msg[1].buf = data; //读入数据地址
msg[1].len = len;
ret = i2c_transfer(client->adapter, msg, 2);