簡體   English   中英

如何讀取16位硬件寄存器

[英]How to read 16 bit hardware register

我正在研究 VEML7700 Lux 傳感器。 數據表鏈接 我可以使用 i2c-tool 檢測傳感器和讀/寫數據。 傳感器的 I2C 地址為 0x10。 在這里,我得到了 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:~$ 

當我試圖讀取 c 程序中的寄存器時,我得到的是常量 0 值。 但我也可以在 c 程序中使用寫入命令寫入配置寄存器。

這是我的 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

您嘗試讀取寄存器 0x04 失敗,因為您對 select 寄存器 0x04 的寫入事務和后續讀取的字不是在同一 I2C 事務中執行的,而是作為單獨的事務執行的。

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

請注意,只有 I2C 和 SMBus 協議的一個子集可以通過 read() 和 write() 調用來實現。 特別是,不支持所謂的組合事務(在同一事務中混合讀取和寫入消息)。 出於這個原因,這個接口幾乎從不被用戶空間程序使用。

而是使用以下訪問方法:

ioctl(文件,I2C_RDWR,結構 i2c_rdwr_ioctl_data *msgset)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM