通过I2C读取Ettus E310晴雨表,总是返回“无此设备或地址(-1)”

时间:2019-02-07 18:10:44

标签: i2c usrp

我一直在尝试为E310上的BMP 180气压计和温度传感器编写I2C设备驱动程序(如schematic第9页所示。) bosch给出的示例驱动程序。

驱动程序需要函数指针来阻止读取和写入以及睡眠,这基本上是唯一的原始代码:

int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)   
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
void user_delay_ms(uint32_t period)

我遇到的问题是此驱动程序(以及我编写的更简单的SMBUS命令(仅编写程序))始终无法读取或写入传感器应位于总线上的i2c地址0x77。

  

设备ID 0x77的readBytes:-1-没有此类设备或地址

即使我的代码似乎适用于其他设备所在的位置(尽管我对ping它们所做的工作并没有做很多事情)

运动传感器:

  

设备ID为0x69的readBytes:0-成功

温度传感器:

  

设备ID 0x19的readBytes:0-成功

我想知道我的代码到底是什么问题导致设备完全无法响应,或者我缺少什么硬件配置来解释与气压计在0x77处无法通信。

我注意到BMP-180气压计放在陀螺仪MPU-9150的辅助i2c上,但是接线和数据表使我认为它处于直通模式而不是主模式。只是我有一个想法。

这里是与bmpDriver交互的所有代码。

编译如下

  

gcc test.c -o test -std = c11 -D _DEFAULT_SOURCE

#include "bmp280.c"
#include <linux/i2c-dev-user.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
    int file;
    file = open("/dev/i2c-0", O_RDWR);
    if(file < 0)
    {
        printf("Failed to open /dev/i2c-0\n");
        close(file);
        return -1;
    }
    if(ioctl(file, I2C_SLAVE, dev_id) < 0)
    {
        printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
        close(file);
        return -2;
    }
    int readBytes;
    readBytes = i2c_smbus_read_block_data(file, reg_addr, data);
    printf("readBytes for device ID 0x%x: %d - %s\n", dev_id, readBytes, strerror(errno));
    close(file);
    return readBytes;
}

int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
    int file;
    file = open("/dev/i2c-0", O_RDWR);
    if(file < 0)
    {
        printf("Failed to open /dev/i2c-0\n");
        close(file);
        return -1;
    }
    if(ioctl(file, I2C_SLAVE, dev_id) < 0)
    {
        printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
        close(file);
        return -2;
    }
    int writeBytes;
    uint8_t shortLen = len;
    writeBytes = i2c_smbus_write_block_data(file, reg_addr, shortLen, data);
    printf("writeBytes for device ID 0x%x: %d - %s\n", dev_id, writeBytes, strerror(errno));
    close(file);
    return writeBytes;
}

void user_delay_ms(uint32_t period){
    unsigned int sleep = period;
    usleep(sleep * 1000);
}

int main(){
    int8_t rslt;
    struct bmp280_dev user_bmp;
    user_bmp.dev_id = BMP280_I2C_ADDR_SEC;
    user_bmp.intf = BMP280_I2C_INTF;
    user_bmp.read = user_i2c_read;
    user_bmp.write = user_i2c_write;
    user_bmp.delay_ms = user_delay_ms;
    rslt = bmp280_init(&user_bmp);
    if (rslt == BMP280_OK) {
      printf("Device found with chip id 0x%x\n", user_bmp.chip_id);
    }
    else {
      printf("Device not found, exiting...\n");
      return -1;
    }
    struct bmp280_config conf;
    rslt = bmp280_get_config(&conf, &user_bmp);
    conf.filter = BMP280_FILTER_COEFF_2;
    conf.os_pres = BMP280_OS_16X;
    conf.os_temp = BMP280_OS_4X;
    conf.odr = BMP280_ODR_1000_MS;
    rslt = bmp280_set_config(&conf, &user_bmp);
    rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &user_bmp);
    struct bmp280_uncomp_data ucomp_data;
    uint8_t meas_dur = bmp280_compute_meas_time(&user_bmp);
    printf("Measurement duration: %dms\r\n", meas_dur);
    uint8_t i;
    for (i = 0; (i < 10) && (rslt == BMP280_OK); i++) {
        printf("Running measurement: %d\n", i+1);
        user_bmp.delay_ms(meas_dur); 
        rslt = bmp280_get_uncomp_data(&ucomp_data, &user_bmp);
        int32_t temp32 = bmp280_comp_temp_32bit(ucomp_data.uncomp_temp, &user_bmp);
        uint32_t pres32 = bmp280_comp_pres_32bit(ucomp_data.uncomp_press, &user_bmp);
        uint32_t pres64 = bmp280_comp_pres_64bit(ucomp_data.uncomp_press, &user_bmp);
        double temp = bmp280_comp_temp_double(ucomp_data.uncomp_temp, &user_bmp);
        double pres = bmp280_comp_pres_double(ucomp_data.uncomp_press, &user_bmp);
        printf("UT: %d, UP: %d, T32: %d, P32: %d, P64: %d, P64N: %d, T: %f, P: %f\r\n", \
          ucomp_data.uncomp_temp, ucomp_data.uncomp_press, temp32, \
          pres32, pres64, pres64 / 256, temp, pres);
        user_bmp.delay_ms(1000);
    }
    if(rslt != BMP280_OK){
        printf("Result not okay at measurement: %d\n", i);
    }
}

1 个答案:

答案 0 :(得分:0)

在开始猜测之前,我将确保传输实际上已经到达陀螺仪后面的传感器。只需使用任何示波器即可测量SCL和SDA。如果设备正在传输,则示波器读数将提供有关设备NAK位置的其他信息。

过去,您能够解决的BMP与其他i2c设备之间的区别使我倍感头痛: BMP似乎需要在设备地址和寄存器读取之间重复启动条件。

据我所知,标准的i2c库不支持此功能,通常您必须使用linux / i2c-dev.h构建自己的读取/写入功能。