简体   繁体   English

如何读取16位硬件寄存器

[英]How to read 16 bit hardware register

I am working on VEML7700 Lux Sensor.我正在研究 VEML7700 Lux 传感器。 datasheet link .数据表链接 I can detect the sensor and read/write data using i2c-tool.我可以使用 i2c-tool 检测传感器和读/写数据。 I2C address of sensor is 0x10.传感器的 I2C 地址为 0x10。 Here I am getting correct reading of 0x04 result register.在这里,我得到了 0x04 结果寄存器的正确读数。

apalis-imx8-06852506:~$ i2cdetect -y -r 4
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: 10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
apalis-imx8-06852506:~$ i2cget -y 4 0x10 0x00 w
0x0000
apalis-imx8-06852506:~$ i2cget -y 4 0x10 0x00 w
0x0000
apalis-imx8-06852506:~$ i2cget -y 4 0x10 0x04 w
0x0930
apalis-imx8-06852506:~$ i2cget -y 4 0x10 0x04 w
0x093c
apalis-imx8-06852506:~$ i2cget -y 4 0x10 0x04 w
0x0939
apalis-imx8-06852506:~$ 

When I am trying to read the register in c program i am getting constant 0 value.当我试图读取 c 程序中的寄存器时,我得到的是常量 0 值。 But I can write the configuration register using write command in c program also.但我也可以在 c 程序中使用写入命令写入配置寄存器。

Here is my c program.这是我的 c 程序。

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

//sensor i2c address is 0x44
#define SLAVE_ADDR 0x10

void main()
{
    // Create I2C bus
        int file;
        char *bus = "/dev/apalis-i2c1";
        if((file = open(bus, O_RDWR)) < 0) 
        {
                printf("Failed to open the bus. \n");
                exit(1);
        }
        // Get I2C device, VEML7700 I2C address is 0x10-7BIT
        ioctl(file, I2C_SLAVE, SLAVE_ADDR);

        //unsigned char reg[1] = {0};
        //unsigned char data[2] ;
        __uint16_t reg_data;

        //configuring the register 0x00
        char config[3] = {0};
        config[0] = 0x00;
        config[1] = 0x00;
        config[2] = 0x00;
        write(file,config,3);
        sleep(1);

        unsigned char reg[1] = {0x04};
        write(file, reg, 1);
        sleep(1);
        unsigned char data[2] = {0};
        if(read(file, data, 2) != 2)
        {
                printf("Erorr : Input/output Erorr \n");
                exit(1);
        }
        printf(" data[0] %x\n data[1] %x\n",data[0],data[1]);

        close(file);
}

root@apalis-imx8-06852506:/bhagwatws# gcc light_sensor.c -o light_sensor
root@apalis-imx8-06852506:/bhagwatws# ./light_sensor
 data[0] 0
 data[1] 0
root@apalis-imx8-06852506:/bhagwatws# ./light_sensor
 data[0] 0
 data[1] 0
root@apalis-imx8-06852506:/bhagwatws# ./light_sensor
 data[0] 0
 data[1] 0

Your attempt to read register 0x04 fails, because your write transaction to select register 0x04 and the following word read are not preformed within the same I2C transaction, but as separate transactions.您尝试读取寄存器 0x04 失败,因为您对 select 寄存器 0x04 的写入事务和后续读取的字不是在同一 I2C 事务中执行的,而是作为单独的事务执行的。

From https://www.kernel.org/doc/Documentation/i2c/dev-interface :来自https://www.kernel.org/doc/Documentation/i2c/dev-interface

Note that only a subset of the I2C and SMBus protocols can be achieved by the means of read() and write() calls.请注意,只有 I2C 和 SMBus 协议的一个子集可以通过 read() 和 write() 调用来实现。 In particular, so-called combined transactions (mixing read and write messages in the same transaction) aren't supported.特别是,不支持所谓的组合事务(在同一事务中混合读取和写入消息)。 For this reason, this interface is almost never used by user-space programs.出于这个原因,这个接口几乎从不被用户空间程序使用。

Instead use the following access method:而是使用以下访问方法:

ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset) ioctl(文件,I2C_RDWR,结构 i2c_rdwr_ioctl_data *msgset)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM