This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F5529:MSP430 + BNO055;I2C 问题。

Guru**** 2595805 points
Other Parts Discussed in Thread: MSP430F5529

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/783508/msp430f5529-msp430-bno055-i2c-issues

器件型号:MSP430F5529

我需要让 Adafruit 的 BNO055绝对方向模块与 MSP430 (MSP430F5529) Launchpad 协同工作。 目前、我在 I2C 方面遇到了一些问题:

如果我进入、它看起来会进入初始化状态并正确读取器件 ID 0xA0。 但是、如果我只是运行它、它似乎会卡在某个位置。 我猜这与 I2C 通信时序有关。 我 尝试在其中插入延迟、但仍然有相同的问题。 以下是我的 I2C 帮助程序函数:

void i2cSendStartTx (void){

//在发送模式下发送起始条件。
UCB1CTL1 |= UCTR | UCTXSTT;
//等待 START 条件被发送并准备好发送中断。
while (((UCB1CTL1 & UCTXSTT)&&(!(UCB1IFG & UCTXIFG)));
}

void i2cSendStartRx (void){
//在接收模式下发送起始条件。
UCB1CTL1 &=~UCTR;
UCB1CTL1 |= UCTXSTT;
//等待开始条件被发送。
while (UCB1CTL1 & UCTXSTT);
}

void i2cSendStop (void){
//发送停止条件
UCB1CTL1 |= UCTXSTP;
}

void i2cWrite (uint8_t data){
//写入 TX buf。
UCB1TXBUF =数据;
//轮询发送中断标志。
while (!(UCB1IFG & UCTXIFG));
}


uint8_t i2cRead (void){
//等待,直到有要读取的内容。
while (!(UCB1IFG & UCRXIFG));
返回 UCB1RXBUF;
}

下面是我的 BNO055函数:

void bno055WriteReg (uint8_t reg、uint8_t data){
i2cSendStartTx();
i2cWrite (reg);
i2cWrite (data);
i2cSendStop();
//__delay_cycles (5000);
}

uint8_t bno055ReadReg (uint8_t reg){
uint8_t val = 0;
//发送要读取的寄存器的地址。
i2cSendStartTx();
i2cWrite (reg);

//立即读取值。
i2cSendStartRx();
//读取前发送 STOP,因为我们只读取一个字节。
i2cSendStop();

Val = i2cRead ();
返回 val;
}


void bno055SetMode (uint8_t 模式){
bno055WriteReg (BNO055_OPR_MODE_ADDR、MODE);
//_DELAY_CYCLES (5000);
}

void bno055Init (void){
i2cInit (BNO055_address_a);
//设置模式以更改配置。
bno055SetMode (operation_mode_config);

//重置电路板。
bno055WriteReg (BNO055_SYS_TRIGGER_ADDR、0x20);

//确保已启动。
while (bno055ReadReg (BNO055_CHIP_ID_ADDR)!= BNO055_ID);
//_ delay_cycles (5000);

//现在电路板已启动,设置为正常的电源模式。
bno055WriteReg (BNO055_PWR_MODE_ADDR、POWER_MODE_NORMAL);
//_DELAY_CYCLES (2000);

//现在要更改为操作模式 AMG,请更改页 ID
bno055WriteReg (BNO055_PAGE_ID_ADDR、0);
//_ delay_cycles (2000);
bno055SetMode (operation_mode_AMG);
//_delay_cycles (2000);
} 

有人能告诉我我出了什么问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好

    您能否使用断点来查找它停留在何处? 如果波形卡住、那么最好通过逻辑分析来进行分析、就像一条便宜的线。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Gary、

    感谢您的回答。 让我在 bnoO055函数中附加几个示波器截图、其中它会卡住:  
    这个镜头来自我进入函数的时间。 调用  bno055SetMode (operation_mode_config)时、我得到的下图是正确的。 从器件地址、后跟寄存器地址、后跟值(在本例中为0x0)。

    bno055WriteReg (BNO055_SYS_TRIGGER_ADDR、0x20)函数再次生成正确的位模式:   


    3.while (bno055ReadReg (BNO055_CHIP_ID_ADDR)!= BNO055_ID)生成以下正确的模式。



    现在、如果我删除 了 bno055SetMode (operation_mode_config)上的第一个断点、这就是我得到的结果: (我可以看到时钟出现问题、但其余的似乎仍然正常。)

    如果我删除下一个断点 bno055WriteReg (BNO055_SYS_TRIGGER_ADDR、0x20)并运行它直到 while ()之前、我获得 Weirder 输出


    如果我删除 while 的断点并运行到那里、我会再次得到一个不同的帧。  这就是它被卡住的地方、因为我假设它永远不会获得 我在 while 循环中检查的 BNO055_ID (0xA0)。  


    有什么想法吗? 与 I2C 故障有关的问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Gary、为了在上一帖子中进行更新、我在函数调用之间添加了延迟。  

    void bno055Init (void){
    i2cInit (BNO055_address_a);
    //设置模式以更改配置。
    bno055SetMode (operation_mode_config);
    _delay_cycles (30000);
    //重置电路板。
    bno055WriteReg (BNO055_SYS_TRIGGER_ADDR、0x20);
    _delay_cycles (30000);
    
    //确保已启动。
    while (bno055ReadReg (BNO055_CHIP_ID_ADDR)!= BNO055_ID){
    __DELAY_CYCLES (30000);
    }
    _delay_cycles (30000);
    
    //现在电路板已启动,设置为正常的电源模式。
    bno055WriteReg (BNO055_PWR_MODE_ADDR、POWER_MODE_NORMAL);
    _delay_cycles (30000);
    
    //现在要更改为操作模式 AMG,请更改页 ID
    bno055WriteReg (BNO055_PAGE_ID_ADDR、0);
    _delay_cycles (30000);
    bno055SetMode (operation_mode_AMG);
    __DELAY_CYCLES (30000);
    }
    

    现在,如果我在 while ()有一个断点,我将获得正确的输出。 但是,如果我删除该断点并在 while ()之后保留该断点,我仍然会被卡住,并且我看到的帧只是要发送的地址。 没有其他东西。 我在写入地址后尝试进入 while 循环、结果发现它在 while 循环中调用的 bno055ReadReg 函数中的 i2cWrite 函数的"while (!(UCB1IFG & UCTXIFG));"上卡住。 这是什么原因?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好  

    这真的看起来很奇怪、只是需要一个断点来解决这个问题。 我认为主要问题与 i2cSendStartRx()有关; 要解决这个问题,您可以参考我们 的 I2C 主设备多字节 TX/RX 演示代码

    e2e.ti.com/.../MSP430F55xx_5F00_usci_5F00_i2c_5F00_standard_5F00_master.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    增加较高的延迟似乎解决了这一问题。 不过、不确定这是不是正确的方法。