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:如何读取 I2C 上的寄存器地址?

Guru**** 2595805 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/648418/msp430f5529-how-to-read-from-a-register-address-on-i2c

器件型号:MSP430F5529

您好!

我能够从 I2C 总线上的从器件读取数据。 我的代码如下所示:

//为 I2C
P3SEL 选择引脚|= BIT0 + BIT1;
//启用 SW 复位、中止 I2C 总线并使用 SMCLK
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// I2C 主控、同步模式
UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC;
// UCB0BR1的高字节分频
器= UCB0CTL0;//
//时钟= SMCLK / 10 = 100KHz
UCB0BR0 = 10;
//清除 SW 复位,恢复操作
UCB0CTL1 &=~UCSWRST;
//启用 STT、STP、RX 和 TX 中断
UCB0IE |= UCNACKIE + UCSTPIE + UCRXIE + UCTXIE;
//
UCB0IE =从地址设置
//确保在
(UCB0CTL1 & UCTXSTP)期间发送停止条件;
//进入读取模式
UCB0CTL1 &=~UCTR;
// I2C 开始条件
UCB0CTL1 |= UCTXSTT; 

如何指定寄存器地址? 上面的代码似乎默认为寄存器地址0。

我在发送起始位后尝试写入寄存器地址:

UCB0TXBUF = REGISTER_ADDRESS;

但它不会产生影响。 返回的值相同。

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

    通常、对于 I2C 通信、如果要从从从器件读取寄存器、作为主器件、您需要首先将寄存器地址传输到从器件。 然后、您发出重复启动并将主器件切换到 RX 模式。 然后、当它计时时、从器件将发送寄存器的内容、或者与前一条命令相关的任何操作/数据。 具体工作方式取决于所连接的从设备。

    有关 I2C 通信的更多调试技巧、请参阅应用手册。 http://www.ti.com/lit/slaa734
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已更改代码以在从器件地址之后发送寄存器地址、如下所示:

    while (UCB0CTL1 & UCTXSTP);//确保发送停止条件
    UCB0I2CSA = SLAVE_ADDRESS; //设置从地址
    UCB0CTL1 |= UCTR + UCTXSTT;//进入写入模式并发送启动
    while (UCB0CTL1 & UCTXSTT);
    UCB0TXBUF = register_address;//发送寄存器地址
    while (UCB0IFG & UCTXIFG); //等待 TX 缓冲区清空
    UCB0CTL1 &=~UCTR; //进入读取模式
    UCB0CTL1 |= UCTXSTT; // I2C 启动条件
    while (UCB0CTL1 & UCTXSTT); 

    但这并没有什么不同!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不应等待 UCTXSTT 标志;通常情况下、应使用 RXIFG 和 TXIFG 标志。

    如果您启用了中断、那么等待是毫无意义的。 您实际上是否有中断处理程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我启用了中断。

    我已将我的代码更改为以下代码、这样做效果更好:

    UCB0I2CSA = SLAVE_ADDRESS; //设置从地址
    UCB0CTL1 |= UCTR + UCTXSTT;//进入写入模式并发送启动
    UCB0TXBUF = register_address;//发送寄存器地址
    同时(UCB0IFG & UCTXIFG); //等待 TX 缓冲
    区为空,同时(((UCB0CTL1 & UCTXSTT)!= 0);//等待开始发送
    UCB0CTL1 &=~UCTR; //进入读取模式
    UCB0CTL1 |= UCTXSTT; // I2C 启动条件 

    这会写入寄存器地址、但用于其他每次写入。 我无法理解为什么写操作会交替发生、至少这是我 Beagle 所说的、我倾向于相信它。

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

    我开始工作了!

    下面是启动读取的完整函数:

    void ReadFromI2CSlave (const uint8_t slave_address、const uint8_t register_address、const uint8_t size)
    {
    rxMasterSize =大小;
    rxMasterCount = rxMasterSize;
    pRxMasterData = rxMasterData;
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0CTL1 |= UCTR + UCTXSTT;//进入写入模式并发送启动
    UCB0TXBUF = REGISTER_ADDRESS;//发送寄存器地址
    while (UCB0IFG 和 UCTXIFG); //等待 TX 缓冲区为空
    UCB0IFG &=~UCTXIFG;
    while (UCB0CTL1 & UCTXSTT);
    UCB0CTL1 &=~UCTR; //进入读取模式
    UCB0CTL1 |= UCTXSTT; // I2C 开始条件
    } 

    这里是我的中断处理程序:

    // USCI_B0数据 ISR -这是 PMU <->从器件
    #if define (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)的中断服务例程
    #pragma vector = USCI_B0_vector
    _interrupt void USCI_B0_ISR (void)
    #elif defined (__GNU__)
    void __attribute__((interrupt (USCI_B0_vector))) USCI_B0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch (__evo_in_range (UCB0IV、12))
    {
    情况0:中断; //向量0:无中断
    案例2:中断; //向量2:ALIFG
    案例4:中断; //向量4:NACKIFG
    案例6:中断; //向量6:STTIFG
    案例8:中断; //向量8:STPIFG
    案例10: //向量10:RXIFG
    {
    if (rxMasterSize = 1)
    {
    if (rxMasterCount >0)
    {
    *pRxMasterData = UCB0RXBUF; //将最终 RX 数据移动到 PRxData
    UCB0CTL1 |= UCTXSTP; //生成 I2C 停止条件
    --rxMasterCount;
    }
    其他
    {
    __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出活动 CPU
    }
    }
    其他
    {
    --rxMasterCount;
    
    if (rxMasterCount)
    {
    *pRxMasterData++= UCB0RXBUF; //将 RX 数据移动到地址 PRxData
    if (rxMasterCount = 1) //只剩下一个字节?
    {
    UCB0CTL1 |= UCTXSTP; //生成 I2C 停止条件
    }
    }
    其他
    {
    *pRxMasterData = UCB0RXBUF; //将最终 RX 数据移动到 PRxData
    __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出活动 CPU
    }
    }
    
    中断;
    }
    情况12: //向量12:TXIFG
    {
    if (txMasterCount < txMasterSize) //检查 TX 字节计数器
    {
    UCB0TXBUF = txMasterData[txMasterCount++];//加载 TX 缓冲区并递增 TX 字节计数
    器}
    其他
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    UCB0IFG &=~UCTXIFG; //清除 USCI_B0 TX int 标志
    __BIC_SR_REGISTER_ON_EXIT (LPM0_Bits + GIE);//退出 LPM0
    }
    中断;
    }
    默认值:break;
    }
    }