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.

[参考译文] MSP432P401R:I2C传输中断未触发?

Guru**** 2587345 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/617087/msp432p401r-i2c-transmit-interrupt-is-not-triggered

部件号:MSP432P401R

您好! 我正在使用带有 MSP-EXP432P401R 修订版2.1 Launchpad的燃油箱MKII电池增强器包插件模块。

我要修改MSP432 Simplelink 1.40 .1.00 (bootxl_batpakmkie_footaugauer_MSP_EXP432P401R_nortos_CCS),以使用I2C传输中断,使进入休眠状态,直到缓冲区可用于传输。 我附上了我的项目,并提到根据 此论坛帖子,它是示例的修改版本

问题是从未生成TX中断(尽管已启用),因此我的标志(i2cTxFlag)未设置,程序挂起(请参见HAL_I2C.c中的I2C_read16())。

有人知道我做错了什么吗? 缓冲区为空或传输后是否生成I2C TX中断?

e2e.ti.com/.../boostxl_5F00_batpakmkii_5F00_fuelgauge_5F00_MSP_5F00_EXP432P401R_5F00_nortos_5F00_ccs.zip

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

    我将为您查看您的帖子,请允许我花些时间来了解此事。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    克里斯蒂安

      对于第二个问题,TX中断与将TXBUF加载到移位寄存器相关。  当从RESET释放eUSCI (通信外围设备名称)时,将自动设置TX IFG。  如果要加载TX缓冲区,则TX IFG将被清除一段时间,因为值被移动到移位寄存器中,TX缓冲区现在为空,并且可以写入另一个字节。

    此致,

    Chris  

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

    为了给您提供更新,当我查看您在IRQ处理程序中时状态变量返回的内容时,您的代码似乎正在尝试发送EUSCI_B_I2C_Transmit_INTERRUPT1上的中断。 我想弄清楚为什么它会这么做。 我会在我了解更多信息后尽快向您提供最新信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    基督教,

    我想我们已经发现了这个问题。 据我所知,在I2C_read16函数内,您正在检查待设置的TX标志,然后再发送启动命令。 生成启动条件时,将设置UCTXIFG0位,并且第一个要传输的数据可以写入UCBxTXBUF。

    在您的情况下,由于您未发送启动条件,因此您永远不会看到TX标志已设置。 driverlib函数I2C_masterSendSingleByteWithTimeout为您处理所有这些问题。 但是,您似乎正在尝试摆脱这种情况,手动编写自己的驱动程序?

    如果是这样,您需要使用以下行来触发启动命令

       //发送启动条件。
       EUSCI_B_CMSIS (moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
               + EUSCI_B_CTLW0_TXSTT;

    默认情况下,您还将i2cTxFlag设置为true。 我相信您的意图是虚假的?


    在while循环中,您还需要在进入睡眠状态之前设置map_Interrupt_enableMaster(),否则它将永远不会离开睡眠状态。

    while (i2cTxFlag == false)
    {
    MAP_Interrupt_enableMaster();
    MAP_PCM_GotoLPM0InterruptSafe ();
    } 

    从那里,为了摆脱I2C driverlib调用,您还需要处理I2C预期的其余条件,例如在ISR处理TXIFG0之后手动传输指针字节和停止条件。

    e2e.ti.com/.../5315.HAL_5F00_I2C.c
    I2C_masterSendSingleByteWithTimeout()函数的来源是一个很好的参考,如下所示

    Bool I2C_masterSendSingleByteWithTimeout(UINT32_t moduleInstance,
    UINT8_t txData,UINT32_t超时)
    {
    uINT_FAST16_t txieStatus;
    uINT32_t timeout2 =超时;
    
    断言(超时> 0);
    
    //存储当前TXIE状态
    txieStatus = EUSCI_B_CMSIS (moduleInstance)->IE & EUSCI_B_IE_TXIE0;
    
    //禁用传输中断启用
    BITBAND_PERI(EUSICI_B_CMSIS (moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)=0;
    
    //发送启动条件。
    EUSCI_B_CMSIS (moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
    + EUSCI_B_CTLW0_TXSTT;
    
    //传送中断标志轮询。
    while ((!(EUSSCI_B_CMSIS (moduleInstance)->IFG & EUSCI_B_IFG_TXIFG))
    &&--超时)
    ;
    
    //检查传输是否超时
    如果(超时== 0)
    返回false;
    
    //发送单字节数据。
    EUSCI_B_CMSIS (moduleInstance -->TXBUF = txData;
    
    //传送中断标志轮询。
    同时(!BISTAND_PERI(EUSI_B_CMIS(moduleInstance)->IFG,
    EUSCI_B_IFG_TXIFG0_OFS)和--timeout2)
    ;
    
    //检查传输是否超时
    IF (超时2 == 0)
    返回false;
    
    //发送停止条件。
    BITBAND_PERI(EUSCI_B_CMSIS (moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS)=
    1;
    
    //在再次启用中断之前清除传输中断标志
    BITBAND_PERI(EUSI_B_CMSIS (moduleInstance)->IFG,EUSCI_B_IFG_TXIFG0_OFS)=
    0;
    
    //恢复传输中断启用
    EUSCI_B_CMSIS (moduleInstance)->IE |= txieStatus;
    
    返回true;
    } 

    您还应该小心地构造代码,使其遵循MSP432技术参考手册的24.3 .4.2 .1节中定义的顺序。

    附加后,您可以看到我们对您的代码所做的一些更改。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常感谢你的帮助。 我现在更清楚了。 我想用TX中断来取代轮询I2C传输标志,以便通过允许CPU在准备就绪之前处于休眠状态来优化能源使用。 我现在知道,我可以使用I2C_masterSendSingleByteWithTimeout()的源代码,并将while循环替换为循环,在循环中CPU进入休眠状态,直到清除标志。