调试IIC过程中,需要准备示波器或逻辑分析仪,需要通过示波器查看波形确定硬件连接是否正确,不然出现问题,软件再怎么调试,都是枉然.
实际使用过程中,效果还不错,体积很小,USB接口, 自己解析IIC波形, 相比示波器,方便许多。
I2C设备驱动有两种模式:一种是用户层操作驱动设备,另一种是普通的设备驱动,应用层使用的时候像读写文件一样. 内核中驱动中/drivers/i2c/i2c-dev.c提供了I2C设备的驱动,实现了read().write().ioctl等函数,不过read()和write()函数每次只能读写一次数据,无法实现连续的数据读写,如下图:
注意:先write()地址之后总线上会有stop,之后read(),这种方式无法实现连续数据读取,使用ioctl函数来实现连续数据的读写,这样中间就没有stop.
两个重要的数据结构
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};
struct i2c_msg {
__u16 addr; /* slave address */
__u16 flags;
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
注意: 一般buf[0]是写的地址,buf[1]之后都是写的数据; 如果读,第一遍写地址时buf[0]是地址,第二遍读数据时存放读的数据
int i2cWriteByte(int* i2c, int devAddr, int slaveAddr, int len, unsigned char data_buf[])
{
int ret = 0;
struct i2c_rdwr_ioctl_data ctl_data;
struct i2c_msg msg;
unsigned char msg_buf[50];
memset((void *) msg_buf, 0, 50);
msg_buf[0] = (unsigned char) (slaveAddr & 0x00ff); //第0位存放寄存器地址
if (data_buf == NULL) {
return -1;
}
if (len < 50) {
memcpy((void *) &msg_buf[1], data_buf, len); //第1位之后是数据
} else {
printf("i2c write error!\n");
return -1;
}
msg.addr = devAddr; //从设备地址
msg.flags = I2C_M_WR;
msg.len = 1 + len;
msg.buf = msg_buf;
ctl_data.nmsgs = 1;
ctl_data.msgs = &msg;
ret = ioctl(*i2c, I2C_RDWR, &ctl_data);
usleep(5 * 1000);
return ret;
}
测试程序完成之后,需要进一步调试,通过示波器或逻辑分析仪查看I2c波形是否正确,调试过程中,抓取了一段波形:
发现第9位ACK信号为高电平(图中红色箭头),一番检查之后,最终发现硬件接线错误,修改之后,波形正常.
痛的领悟: 调试外设,软件写的再好,也是枉然.需要结合硬件,综合查看,才能快速定位问题
也可以结合芯片的DataSheet发现波形异常