xuejd780126
驱动牛犊
驱动牛犊
  • 注册日期2006-10-25
  • 最后登录2010-06-04
  • 粉丝0
  • 关注0
  • 积分253分
  • 威望46点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
阅读:1434回复:2

关于linux下I2C应用程序开发的疑问

楼主#
更多 发布于:2009-09-06 00:34
本人开发s3c2410 linux下的I2C驱动程序,但是遇到问题,并产生一些疑问,希望大家能够帮助解答。

我所用的I2C设备是数字罗盘AK8974,  AK8974 3-axis Electronic Compass.pdf 手册见附件。

我写的测试代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

int main()
{
        int fd;
        int SLAVE_ADDR = 0x0C;                    /* Slave device Compass AK8974 */
        int CTRL_REG_ADDR = 0x0F;
        char sendbuf[2],receivebuf;
        
        fd = open("/dev/i2c/0",O_RDWR);      
        if(fd < 0)
            printf("open i2c error \n");
        else
            printf("open i2c success \n");
            
        /* Set I2C ioctl parameters */    
        if(ioctl(fd,I2C_TENBIT,0) < 0)            /* 0 for 7 bit addrs, != 0 for 10 bit   */
            printf("set 7bit mode error \n");
        else
            printf("set 7bit mode success \n");

        if(ioctl(fd,I2C_SLAVE,SLAVE_ADDR)<0)    /* Set Slave Address */
            printf("set slave address error \n");
        else
            printf("set slave address success \n");
            
        if(ioctl(fd,I2C_TIMEOUT,1)<0)    
            printf("set Timeout error \n");
        else
            printf("set Timeout success \n");    

        if(ioctl(fd,I2C_RETRIES,1)<0)    
            printf("set Retry error \n");
        else
            printf("set Retry success \n");                
      
        /* read and write */
        if(write(fd,0x0F,1) < 0)
            printf("write register address error \n");
        else
            printf("write register address success \n");
    
        close(fd);
}


下面是编译运行后的结果。显然,写寄存器0x0F出错了。关于该寄存器,手册上给出的信息是:WIA 0FH READ ”Who I am” value 8 Company ID。

[root@utu-linux /]# ./i2c
open i2c success
set 7bit mode success
set slave address success
set Timeout success
set Retry success
write register address error

我的问题是:
(1)根据I2C器件AK8974给出的one byte read时序图(其他I2C器件也基本一样),首先应该写入slave address(R/W=0),
          那么这是被我程序中的if(ioctl(fd,I2C_SLAVE,SLAVE_ADDR)<0)这句话已经执行了呢,还是需要额外通过write函数实现,比如write(fd,SLAVE_ADDR,1)?
(2)假设slave address已经被ioctl传递过去了,那么R/W的信息又是怎么传递的?
(3)为什么我写寄存器地址也会出错?
(4)linux到底实现了I2C协议的哪些细节?用户应用程序又需要做些什么工作?


注:我写的这个应用程序是参照了:http://www.21ic.com/app/embed/200903/33150.htm
xuejd780126
驱动牛犊
驱动牛犊
  • 注册日期2006-10-25
  • 最后登录2010-06-04
  • 粉丝0
  • 关注0
  • 积分253分
  • 威望46点
  • 贡献值0点
  • 好评度25点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-09-06 00:35
我试过把最后那段代码改为:

/* read and write */
    if(write(fd,0x0C,1) < 0)                                                /* slave address */
        printf("write register address error \n");
    else
        printf("write register address success \n");

也是同样出错
guningyi
驱动牛犊
驱动牛犊
  • 注册日期2009-11-09
  • 最后登录2009-12-08
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望51点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-11-23 12:04
可以 加我MSN:brosdepse@hotmail.com
讨论一下吗?
游客

返回顶部