关于I2C的问题,CU终于不维护了,大家帮我看看。
本帖最后由 kenchowcn 于 2012-06-11 17:07 编辑OS:linux 2.6.28
CPU:三星6410
I2C:HMC5883L数字电子罗盘传感器
我根据文档写运用程序的代码,我在linux下面配置了I2C的驱动,将hmc5883l焊接在i2c0上,能通过芯片在i2c的地址(0x1E)访问,用示波器看了,有信号,对不对没看,可以确定我操作有效果,我就觉得这个地址应该是正确的,DS上也是这样描述的。
我的代码大致是根据这个示例和自带的一个裸机程序写的。代码如下:int main()
{
int fd, opt, i;
unsigned int slave_address = 0x3C;
struct i2c_rdwr_ioctl_data compass_buf;
int x, y, z;
int x1, y1, z1;
fd = open(CHIP_DEV, O_RDWR);
if (0 > fd)
{
perror("open");
return -1;
}
compass_buf.nmsgs = 3;
compass_buf.msgs = (struct i2c_msg*)malloc(compass_buf.nmsgs*sizeof(struct i2c_msg));
if (NULL == compass_buf.msgs)
{
perror("malloc error");
return -1;
}
/* 设置超时和重发 */
ioctl(fd, I2C_TIMEOUT, 1);
ioctl(fd, I2C_RETRIES, 2);
/* 设置寄存器的个数 */
compass_buf.nmsgs = 1;
compass_buf.msgs.len = 3;
compass_buf.msgs.addr = CHIP_ADDR;
compass_buf.msgs.flags = 0;
compass_buf.msgs.buf = (unsigned char*)malloc(3);
compass_buf.msgs.buf = slave_address;
compass_buf.msgs.buf = 0x02;
compass_buf.msgs.buf = 0x00;
opt = ioctl(fd, I2C_RDWR, (unsigned long)&compass_buf);
if (0 > opt)
{
perror("io write error");
}
usleep(6);
while(1)
{
compass_buf.nmsgs = 3;
compass_buf.msgs.len = 2;
compass_buf.msgs.addr = CHIP_ADDR;
compass_buf.msgs.flags = 0; /* 标记写 */
compass_buf.msgs.buf = (unsigned char*)malloc(2);
compass_buf.msgs.buf = slave_address;
compass_buf.msgs.buf = 0x03; /* 存储起始地址 */
compass_buf.msgs.len = 2;
compass_buf.msgs.addr = CHIP_ADDR;
compass_buf.msgs.flags = 0;
compass_buf.msgs.buf = (unsigned char*)malloc(2);
compass_buf.msgs.buf = slave_address+1;
compass_buf.msgs.buf = 0x06;
/* 读取数据存放初始化 */
compass_buf.msgs.len = 6;
compass_buf.msgs.addr = CHIP_ADDR;
compass_buf.msgs.flags = I2C_M_RD; /* 标记读 */
compass_buf.msgs.buf = (unsigned char*)malloc(6);
compass_buf.msgs.buf = 0;
compass_buf.msgs.buf = 0;
compass_buf.msgs.buf = 0;
compass_buf.msgs.buf = 0;
compass_buf.msgs.buf = 0;
compass_buf.msgs.buf = 0;
opt = ioctl(fd, I2C_RDWR, (unsigned long)&compass_buf);
if (0 > opt)
{
perror("io write error");
}
for (i=0; i<6; i++)
{
printf("%02x ", compass_buf.msgs.buf);
}
printf("\n");
#if 0
/* 补码:高位是1的,原码是负数 */
x = (compass_buf.msgs.buf<<8) | compass_buf.msgs.buf;
z = (compass_buf.msgs.buf<<8) | compass_buf.msgs.buf;
y = (compass_buf.msgs.buf<<8) | compass_buf.msgs.buf;
if (x1 != x || y1 != y || z1 != z)
{
printf(" x=%d\n y=%d\n z=%d\n", (x), (y), (z));
x1 = x; y1 = y; z1 = z;
printf("-------------------\n\n");
}
#endif
usleep(100);
}
close(fd);
return 0;
}
这个运行结果是:
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
没有取到数据,我开始从i2c协议,再到linux里面的代码,继续看芯片文档,最后写的代码。
以前没做过这方面,大家看看我这个程序缺什么? 要怎么调试? 我没主意了。
楼主CHIP_ADDR是多少?
你的slave_address是0x3C,我的理解是0x3C是芯片的I2C写地址,0x3D是读地址,所以CHIP_ADDR应该是0x1E,而slave_address指的应该是芯片内部的寄存器地址,你是不是弄错了.. 女人一定要对自己好一点。一旦累死了,就会有别的女人化你的钱,住你的房,睡你的老公,还打你的娃!
知道了 不错~~~
对,我搞错了,现在好了,谢谢了
回复 2# ricky221006
楼主,我想知道,你说的linux下配置了I2C驱动,配置了哪里呢? 我怎么觉得楼主的程序是对的?到底错在哪?求解。
页:
[1]