具有寄存器的I2C读取和I2C写入行为,设备无应答

时间:2017-10-11 08:47:04

标签: c embedded i2c

我已经阅读了一些关于i2c的详细教程和指南,但对我来说不清楚的是:

假设您必须在i2c从设备上读取寄存器,

我需要在i2c上“写”前7位为slave_address,1位用R / W然后是reg_address(作为数据),然后发出“read”来监听字节

h_i2c *i2c_dev = i2c_drv_open(I2C1_PORT, SLAVE_ADDRESS);
write_data[0] = 0x21;
write_len = i2c_drv_write(i2c_h, write_data, 1);
if (write_len != 1)
    printf("error write_len is %d", write_len);

uint8_t read_data[5];
read_len = i2c_drv_read(i2c_h, read_data, 5);
if (read_len != 5)
    wmprintf("error read_len is %d", read_len);

我是否只需要对一个地址发出一个读数,这个地址是从机和我想读的寄存器的“组合”?

此外,“自动增量”属性意味着只要我将SDA控制权交给奴隶,他就会继续发送数据吗?

EDIT1:

引用pdf:

ENS210是I²C从设备,固定从设备地址为 0x43中。这意味着启动条件之后的第一个字节是 1000 011x,其中x表示数据方向,因此0x86(1000 0110)用于写入,0x87(1000 0111)用于读取。

这是输出

https://imgur.com/a/8G8UR

在上升沿,我看到1 0 0 0 0 1 1 0 1

最后一个意味着nACK。

我的想法是:

  1. 传感器已经死了
  2. 电阻不好,传感器无法拉下SDA线
  3. 频率是125khz,这是正常的吗?
  4. PS: SCL探针有问题,所以信号质量比你在这里看到的更好

    此致

1 个答案:

答案 0 :(得分:0)

这取决于I2C设备。我见过的大多数都是让你先用写入设置地址指针,然后执行读取:

[START] - GT; [ADDR(W)] - > REG] - GT; [RESTART] - > [ADDR(R)] - >数据字节] - GT; [STOP]

我见过的大多数设备都会从指定的寄存器中读取数据,并自动递增主机确认的每个数据字节的地址指针。读取的每个数据字节将在内存中顺序执行。但情况并非总是如此。如果需要,许多设备实际上会让你关闭寄存器自动增量。

我见过的一些设备与他们期望读取寄存器命令的方式有所不同。有些设备不允许您将寄存器设置为读取AT ALL而您必须执行顺序读取以获取你想要的数据。 I2C器件应该具有关于如何在数据表中期望读/写命令的信息以及波形图。