简体   繁体   English

I2C 读取 function 发送确认位后卡住

[英]I2C Read function gets stuck after sending Acknowledge bit

I'm trying to communicate with a MPU-9250 (Accelerometer and a lot of other stuff) from my PIC16F1789.我正在尝试与我的 PIC16F1789 中的 MPU-9250(加速度计和许多其他东西)通信。 My functions look like the following:我的函数如下所示:

void i2cWait(){
  while((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
}

unsigned char i2cReadCycle(unsigned char regAddr){
    unsigned char val;
    // Start
    i2cWait();
    SEN = 1;

    // Address + Write Bit
    i2cWait();
    SSPBUF = (slvAdd<<1 | (0b1<<0)); // address slave + write
    i2cWait();

    //Register address
    SSP1BUF = regAddr; // address register + read
    i2cWait();

    //Start
    SEN = 1;
    i2cWait();

    // Address + Read Bit
    SSP1BUF = ((slvAdd<<1) | (0b0<<0)); //Address + read (0)
    i2cWait();

    // Daten Auslesen
    RCEN = 1;
    i2cWait();
    val = SSP1BUF;
    i2cWait();
    ACKDT = 1; // set acknowledge Bit (1 = Not Acknowledge, 0 = Acknowledge)
    ACKEN = 1; // send acknowledge Bit

    // Stop
    i2cWait();
    PEN = 1;

    return val;
}

I've worked with the "Single-Byte Read Sequence" on page 35 of the 9250 Datasheet: https://cdn.sparkfun.com/assets/learn_tutorials/5/5/0/MPU9250REV1.0.pdf我使用过 9250 数据表第 35 页上的“单字节读取序列”: https://cdn.sparkfun.com/assets/learn_tutorials/5/5/0/MPU9250REV1.0.Z437175BA4191210EE004E1D937Z9

And the PIC Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/40001675C.pdf以及 PIC 数据表: http://ww1.microchip.com/downloads/en/DeviceDoc/40001675C.pdf

When debugging, the program gets stuck in the i2cWait() after I send the NACK Bit.调试时,程序在我发送 NACK 位后卡在 i2cWait() 中。 It gets stuck because the ACKEN Bit (Bit 4) of the SSPCON2 register (Page 341 of PIC datasheet) doesn't get cleared, so the program gets stuck in the while().它卡住是因为 SSPCON2 寄存器(PIC 数据表的第 341 页)的 ACKEN 位(位 4)没有被清除,所以程序卡在 while() 中。

Why doesnt the Bit get cleared by hardware?为什么Bit不会被硬件清除?

It looks like you are using 0b1<<0 for "writing" together with the slave address.看起来您正在使用 0b1<<0 与从地址一起“写入”。 However, according to the datasheet of MPU9250REV1.0, it should be 0. Check section 7.4 on page 35.但是,根据 MPU9250REV1.0 的数据表,它应该是 0。请查看第 35 页的第 7.4 节。

Although it might be counter-intuitive to set '0' for writes, it makes sense if you think of the "General Call" that ist initiated with the slave address 0b0000000 and the "write" bit 0.尽管将写入设置为“0”可能违反直觉,但如果您考虑使用从地址 0b0000000 和“写入”位 0 启动的“通用调用”,那么它是有道理的。

This also means to change the "read" bit in your code to 1.这也意味着将代码中的“读取”位更改为 1。

In the current implementation, mixing up read and write bits, leads to the issue being stuck waiting after setting the NACK.在当前实现中,混合读取和写入位会导致设置 NACK 后卡在等待的问题。

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

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