精华内容
下载资源
问答
  • verilog实现I2C,可以用于控制标准I2C寄存器; 代码中I2C采用:7bit寄存器地址+寄存器地址+写/读数据模式
  • 读写i2c寄存器(8位)

    千次阅读 2019-06-21 15:48:33
    在linux系统中经常会用到i2c的操作,但是i2c寄存器的写在不同系统层面代码有所不同,直接使用应用层的代码到内核中就会常常报找不到函数的错误。 分享一下自己的不同层面i2c写寄存器的代码。针对8位的,16位在研究...

    在linux系统中经常会用到i2c的操作,但是i2c寄存器的写在不同系统层面代码有所不同,直接使用应用层的代码到内核中就会常常报找不到函数的错误。

    分享一下自己的不同层面i2c写寄存器的代码。针对8位的,16位在研究。

    在内核驱动中写操作

    static int i2c_write(unsigned char reg_addr,unsigned char value)
    {
             int ret;
             unsigned char buf[2];
             struct i2c_msg msg[1];
             msg[0].addr  = 0x59;
             
             buf[0] = reg_addr;
             buf[1] = value;
    
             msg[0].addr  = 0x59;
             msg[0].buf   = buf; 
             msg[0].len   = 2;
             msg[0].flags = 0;//读写标准位
             
             ret = i2c_transfer(xx.i2c_client->adapter, msg, 1);
             printk("%s:0x%x = 0x%x\n",__func__,buf[0],buf[1]);
             return ret;
    }

    在内核代码中读操作

    static int i2c_read(unsigned char reg_addr)
    {
        int ret;
        unsigned char buf[2];
        buf[0] = reg_addr;
        ret = i2c_smbus_read_byte_data(xx.i2c_client,reg_addr);
        printk("%s:0x%x = 0x%x\n",__func__,reg_addr,ret);
        return ret;
    }

    在应用层中

    void i2c_rw(unsigned char i2c_addr,unsigned char reg_add,unsigned char reg_val){
            int fd = -1;
            int ret ;
            struct i2c_rdwr_ioctl_data data;
            data.msgs = (struct i2c_msg *)malloc(2 * sizeof(struct i2c_msg)); 
            unsigned char sendbuf[sizeof(unsigned char) + 1] = {0};
            unsigned char recvbuf[sizeof(unsigned char) + 1] =  {0};
    
            fd = open("/dev/i2c-2",O_RDWR);
    
            if(fd < 0) {                                                                                                                                                                                                  
                 printf("Failed to open device /dev/i2c-2\n");                                                                                                                                                         
                 return -1;                                                                                                                                                                                                  
           }
           data.nmsgs = 1;
           data.msgs[0].len = 2;
           data.msgs[0].addr = i2c_addr;
           data.msgs[0].flags = 0;
           data.msgs[0].buf = sendbuf;
           data.msgs[0].buf[0] = reg_add;
           data.msgs[0].buf[1] = reg_val;
           ret = ioctl(fd,I2C_RDWR,(unsigned long)&data); 
           if(ret < 0)
    		printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
           
           printf("buf[0] = %x\n",data.msgs[0].buf[0]);
    
           close(fd);
    }

    最后给大家推荐使用如下工具

    i2cdetect 查看i2c挂载的设备地址及使用情况

    i2cdetect -f -y 0(查看i2c0下挂载的设备地址),参数0代表i2c0下查找,看到0x1a写着uu代表使用中。

         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- 0f 
    10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- -- -- -- --

    i2cdump -f -y 0 0x0f (查看i2c0下的0x0f设备寄存器值)

    No size specified (using byte-data access)
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    80: 00 00 00 00 00 00 11 00 00 cf 00 00 e2 65 0c 31    ......?..?..?e?1
    90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
    f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

    i2cset -r -y 0 0x0f 0 0x11(向i2c0的0x0f设备中的地址0寄存器写0x11)

    展开全文
  • I2C寄存器控制

    千次阅读 2019-09-03 22:55:46
    /* 设置寄存器启动传输 */ /* 1. 配置为 master tx mode */ IICCON |= (1<<7); /* TX mode, 在ACK周期释放SDA */ IICSTAT = (1<<4); /* 2. 把从设备地址写入IICDS */ IICDS = msg->...

       

          /* 设置寄存器启动传输 */
          /* 1. 配置为 master tx mode */
        IICCON |= (1<<7); /* TX mode, 在ACK周期释放SDA */
        IICSTAT = (1<<4);
            
        /* 2. 把从设备地址写入IICDS */
        IICDS = msg->addr<<1;
        
        /* 3. IICSTAT = 0xf0 , 数据即被发送出去, 将导致中断产生 */
        IICSTAT = 0xf0;
        

        /* 后续的传输由中断驱动 */

        /* 循环等待中断处理完毕 */

    发送模式:

    IICDS = 第一个字节------> 发送完成---->产生中断,拉低SCL----------->在中断程序中判断状态--------->

    IICDS = 第二个字节------->发送。。。

    接收模式:

    发起传输,接收第一个字节-------->产生中断------->SCL被拉低--------->中断程序中判断

     

     

     

     

    展开全文
  • i2c时序读写寄存器

    2016-11-03 20:01:14
    i2c时序读写寄存器Read and write registers according to i2c timing
  • 要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章《手把手教你写Linux I2C设备驱动》已经做了初步的介绍,并且留下了两个疑问尚未解决,第一个...

     

     

    要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章《手把手教你写Linux I2C设备驱动》已经做了初步的介绍,并且留下了两个疑问尚未解决,第一个是如何对Linux提供的I2C操作函数进行进一步封装,实现对芯片寄存器的读写;另一个是如何在用户空间调用该I2C驱动代码。本文将讨论前一个问题。

        

    首先,我们要了解Linux系统提供的I2C操作函数怎么使用,上篇文章已经提到过,对I2C设备的读写,Linux系统提供了多种接口,这些接口可以在内核的 i2c.h 中找到,这里我主要介绍下面这组读写接口:

     

    extern int i2c_master_send(struct i2c_client *,const char* ,int);    
       
    extern int i2c_master_recv(struct i2c_client *,char* ,int);

        

    第一个参数是 i2c_client 对象指针,第二个参数是要传输的数据buffer指针,第三个参数为buffer的大小。

        

    接口函数已经有了,下面我们要解决的问题就是以何种形式/规则去使用这些接口才能正确地读写芯片的相关寄存器。

        

    首先,我们需要查询芯片手册,找到芯片手册中,关于寄存器的I2C读写时序,其实,大多数芯片的I2C寄存器的读写时序都是一样的,下面我还是以手头的TVP5158芯片为例。

        

    首先分析写操作,该芯片的手册中给出的I2C寄存器写时序图如下:

     

        

    从上图可以看出,真正需要执行写操作的有两处,Step4 和 Step6 ,Step4首先写入寄存器的偏移地址,而Step6则是写入到该寄存器的值。由此已经很清楚了,对于写I2C寄存器,我们需要做的就是给 i2c_master_send 函数传入两个字节的数据即可,第一个字节为寄存器的地址,第二个字节为要写入寄存器的数据。示例如下:

     

    static int tvp5158_i2c_write( struct i2c_client* client,uint8_t reg,uint8_t data)  
    {  
        unsigned char buffer[2];  
          
        buffer[0] = reg;  
        buffer[1] = data;  
          
        if( 2!= i2c_master_send(client,buffer,2) ) {  
            printk( KERN_ERR " tvp5158_i2c_write fail! \n" );  
            return -1;  
        }      
        return 0;  
    }

        

    其实挺简单的,没有什么复杂的代码。下面再看看读时序。

     

         

    由上图可以,读时序需要做的操作是,先向I2C总线上写入需要读的寄存器地址,然后读I2C总线上的值。代码写起来也不难,示例如下:

     

    static int tvp5158_i2c_read( struct i2c_client* client,uint8_t reg,uint8_t *data)  
    {  
        // write reg addr     
        if( 1!= i2c_master_send(client,&reg,1) ) {  
            printk( KERN_ERR " tvp5158_i2c_read fail! \n" );  
            return -1;  
        }      
        // wait  
        msleep(10);  
        // read  
        if( 1!= i2c_master_recv(client,data,1) ) {  
            printk( KERN_ERR " tvp5158_i2c_read fail! \n" );  
            return -1;  
        }      
          
        return 0;  
    }

      I2C时序: Start, I2C Address 7b, R/W, ACK, Register adress 8b, ACK, DATA, ACK, STOP

      (转自某处)

     

    展开全文
  • 命令行读写i2c寄存器操作

    千次阅读 2017-07-14 19:08:13
    写命令格式: 寄存器地址 长度 数据 读命令格式: # echo “寄存器地址” &gt; getreg # cat getreg 1.使能寄存器 ... /sys/bus/i2c/devices/1-20/setreg" 2.禁掉寄存器 # adb ...
    写命令格式:
             寄存器地址 长度  数据
     读命令格式:
             # echo “寄存器地址” > getreg
             # cat getreg
     1.使能寄存器
      # adb shell "echo "0x01,0x01,{0xff}" > /sys/bus/i2c/devices/1-20/setreg"
     2.禁掉寄存器
      # adb shell "echo "0x01,0x01,{0x00}” > /sys/bus/i2c/devices/1-20/setreg"
    
     3.读寄存器
      # adb shell "echo "0x01" > /sys/bus/i2c/devices/1-20/getreg"
      # adb shell "cat /sys/bus/i2c/devices/1-20/getreg"

     

    展开全文
  • 因工作需要,本人写了一个小程序来完成对i2c设备寄存器的读写,源码示例。
  • 要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章《手把手教你写Linux I2C设备驱动》已经做了初步的介绍,并且留下了两个疑问尚未解决,第一个...
  • STM32 HAL/LL寄存器读写I2C(硬件I2C

    千次阅读 2019-08-29 19:37:48
    HAL库底层中有超时返回函数,在这里精简掉,此函数验证与STM32L...写寄存器 uint8_t BSP_IIC_WriteReg(uint8_t ucChannel, uint16_t DevAddress, uint16_t Reg, uint8_t *pData, uint16_t usLen, uint32_t ulTimeout...
  • 控制ARM12C总线接口需要配置总线控制寄存器(rIICCON)、总线状态寄存器(rIICSTAT)、总线发送接收移位寄存器(rIICDS)和总线地址寄存(rIICADD)这4个寄存器。总线控制寄存器通常在程序开始时配置,包括应答信号和接收
  • 调试I2C设备时经常需要修改寄存器的值,通常的方法是修改-》编译-》烧写-》重启,哪怕改一个寄存器也要这样折腾一下,很消耗时间,下面提供一种在线修改寄存器的方法,在终端中敲命令就可以写寄存器,不要上面那些...
  • I2C从设备地址设置。
  • STM32寄存器列表 I2C相关寄存器

    千次阅读 2018-03-09 19:15:52
    I2C_CR1(控制寄存器1)15位:SWRST软件复位,当被置位时,I2C处于复位状态,在复位该位前确信I2C的引脚被释放,总线是空的,定义:0(I2C模块不处于复位状态),1(I2C模块处于复位状态) 注:该位可以用于BUSY位为’1’,...
  • 应用层读写i2c从设备寄存器

    千次阅读 2015-09-29 11:59:20
    在配置i2c从设备寄存器时往往需要修改驱动中的初始化函数来修改寄存器的值,这样往往需要重新编译内核,其实可以使用i2c驱动提供给应用层的接口函数ioctl来在命令行修改寄存器,只需要编写一个类似i2c测试程序的程序...
  • 在Android手机中通过i2c读取芯片寄存器(含i2c-tools)tags: Android Linux i2c driver需求:同事甩来一个某品牌的手机,Android系统,需要把里面某个芯片的寄存器配置参数值读出来。折腾了两天(坑爹的网络以及...
  • 海思hisi I2C SPI读写寄存器

    千次阅读 2019-08-20 15:39:25
    I2C 读写命令示例 此操作示例通过 I2C 读写命令实现对 I2C 外围设备的读写操作。 a. 在控制台使用 i2c_read 命令对 I2C 外围设备进行读操作: ~ $ i2c_read <i2c_num> <device_addr> <reg_addr> ...
  •  1、I2C波特率为100Khz,数据位宽8位,BQ24250 I2C 7bit从机地址0x6A;  2、随便读取哪个寄存器读取地址的数据和器件手册对不上;  3、原来是每次读取的寄存器不对,比如Register #1寄存器,你以为实际寄存器地址...
  • STM32_IIC程序_寄存器

    2018-05-02 14:46:17
    2,串口1(波特率:9600,PA9/PA10连接在板载USB转串口芯片CH340上面) 3,ALIENTEK 2.8/3.5/4.3/7寸TFTLCD模块(通过GPIO驱动,连接关系见lcd.h) 4,按键KEY0(PC5)/KEY_UP(PA0,也称之为WK_UP) 5,24C02(IIC连接在PC11/...
  • I2C控制器寄存器基地址MBASE由VHDL代码中常量BASE ADDRESS决定,基地址为地址总线的高16位,低8位地址将决定哪一个寄存器被寻址。此I2C控制器寄存器共有如下4个。 (1)MADR:地址寄存器(地址为MBASE+$8Dh) ■Bit7...
  • 原因:寄存器只写
  • I2C无法写入和读出寄存器

    千次阅读 2018-11-29 15:22:34
    之前不小心把自己做的通过6124B控制dms模组的功能的源码全给删掉了,可是吓死我了,没办法只能自己加班偷偷赶出来。...我用的是我之前写的linux应用层的i2c设备文件的读写方式进行控制i2c接口的。一直以为是...
  • 最近在写一段linux shell脚本,通过I2C控制一颗IC,获取它寄存器的值,它寄存器的值即表示想要获取的电压。 先解释一下: sudo i2cget -y -f 0 0x2a 0x10表示用root权限通过i2cget命令获取地址为0...
  • stm32 i2c通信 [操作寄存器+库函数]

    千次阅读 2016-08-30 21:29:24
    I2C总线是由NXP(原PHILIPS)公司设计,有十分简洁的物理层定义,其特性如下: 只要求两条总线线路:一条串行数据线SDA,一条串行时钟线SCL; 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机/从...
  • I2C通信模块 时钟模块 寄存器配置模块,代码有本人的详细注释,看一篇就懂,可以灵活修改
  • SW3518S寄存器列表,可以用来读取SW35xx系列的电流,电压,温度,当前协议,以及调整输入输出电流电压,开启关闭某些保护,使用IIC总线通信,内部资料,网络上比较稀少。
  • 有关I2C总线时序,下面的文章写得很好,推荐阅读 https://www.cnblogs.com/BitArt/archive/2013/05/28/3103917.html#commentform 8位设备地址,8位寄存器地址,8位数据的情况完全够了 下面我想补充的是8位设备...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,088
精华内容 69,635
关键字:

i2c寄存器