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:UART 通信因发送字符后 UCTXIFG 清零而停止。

Guru**** 2589275 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/622597/msp432p401r-uart-comms-stalls-because-uctxifg-is-clear-after-a-character-is-sent

器件型号:MSP432P401R

大家好、

我们现在有几种不同的情况、在这种情况下、我们的 UART 驱动程序将会偶尔停止、因为发送字符后 UCTXIFG 保持清零(UCBUSY = 0)。

我们在以57.6kBaud 运行的端口的基于中断的 UART 驱动程序和以2MBaud 运行的另一个端口的基于 DMA 的驱动程序中观察到了这种行为。  

对于 DMA 驱动程序、我们似乎只在 DMA 突发结束时得到 UCTXIFG 问题-由于这个问题、我们没有提前观察到 DMA 突发停止。

我们正在通过检测 UCTXIFG 何时应清零来解决该问题、并将其设置为(在启动 DMA 突发之前、在基于中断的 UART 的计时器上)。

两个 UART 都来自 SMCLK、我们不会轮询 UCTXIFG、因此我认为勘误表 USCI44不适用。   

对于我们为什么会看到这种效果以及是否有更好的解决方案、您有什么建议吗?

谢谢

Julian

 

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

    Julian、

     您能否发送一个代码片段来可靠地处理您所看到的问题?

    此致、

     Bob Landers。

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

    G'Day Bob、

    下面的代码是 Simplelink 附带的 UART_LOOP_24MHz_brclk 示例的修改版本、经过修改后显示了我所描述的问题。  

    启动 CCS、在 MSP432 Launchpad 上运行程序。  打开终端程序并连接到 Launchpad 上的第二个串行端口、您应该会看到字符以 ASCII 顺序显示。  现在、在终端程序中、用锤子敲击键盘。  快速命中大量密钥。  可能需要一分钟左右的时间、但最终您将看到 Launchpad 停止的输出。  现在暂停调试器中的执行并查看寄存器 EUSCI_A0 UCTXIFG。  它将在不应该出现时处于低电平。  将其设置回高电平、 字符将再次开始传输。

    //为简洁起见,请摘略 TI 免责声明。
    
    /* DriverLib 包括*/
    #include 
    
    /*标准包括*/
    #include 
    #include 
    #include 
    
    /* UART 配置参数。 这些是配置参数
    、*使 eUSCI 成为 UART 模块以115200波特率运行。 这些
    *值是使用 TI 提供的在线计算器计算的*
    网址
    为:* software-dl.ti.com/.../index.html
    *
    / const eUSCI_UART_Config uartConfig =
    {
    EUSCI_A_UART_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
    13、 // BRDIV = 13
    0、 // UCxBRF = 0
    37、 // UCxBRS = 37
    EUSCI_A_UART_NO_奇 偶校验、 //无奇偶校验
    EUSCI_A_UART_LSB_FIRST、 // MSB 优先
    EUSCI_A_UART_One_stop_bit、 //一个停止位
    EUSCI_A_UART_MODE、 // UART 模式
    eUSCI_A_UART_oversampling_BAUDRATE_generation //过采样
    };
    
    RingBuf_Object ringbuf_hndl;
    uint8_t txChar_u8 = 0;
    uint8_t rxBuff_u8;
    
    int main (void)
    {
    /*停止 WDT */
    MAP_WDT_A_HOLDTimer();
    
    /*在 UART 模式下选择 P1.2和 P1.3并将 P1.0作为输出(LED)*/
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P1、
    GPIO_PIN2 | GPIO_PIN3、GPIO_PRIMARY_MODULE_FUNCTION);
    MAP_GPIO_setAsOutputPin (GPIO_PORT_P1、GPIO_PIN0);
    MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P1、GPIO_PIN0);
    
    /*将 DCO 设置为24MHz (升级 Vcore)*/
    FlashCtl_setWaitState (FLASH_BANK0、2);
    FlashCtl_setWaitState (FLASH_BANK1、2);
    MAP_PCM_setCoreVoltageLevel (PCM_VCORE1);
    CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY 24);
    
    /*配置 UART 模块*/
    MAP_UART_initModule (EUSCI_A0_BASE、uartConfig);
    
    /*启用 UART 模块*/
    MAP_UART_enableModule (EUSCI_A0_BASE);
    
    /*启用中断*/
    MAP_UART_enableInterrupt (EUSCI_A0_BASE、EUSCI_A_UART_receive_interrupt);
    MAP_UART_enableInterrupt (EUSCI_A0_BASE、EUSCI_A_UART_Transmit 中断);
    MAP_Interrupt_enableInterrupt (INT_EUSCIA0);
    MAP_Interrupt_enableSlepOnIsrExit();
    
    //对 Tx 泵进行灌注。 一旦这个字符被发送、UCTXIFG 中断
    //将保持字符流动。
    MAP_UART_transmitData (EUSCI_A0_BASE、"A");
    
    while (1)
    {
    }
    }
    
    
    空 EUSCIA0_IRQHandler (空)
    {
    UINT_fast8_t STATUS_u8 = MAP_UART_getEnabableInterruptStatus (EUSCI_A0_BASE);
    uint_fast8_t flags_u8;
    uint8_t rx_char_u8;
    
    IF (STATUS_u8和 EUSCI_A_UART_receive_interrupt_FLAG)
    {
    MAP_UART_clearInterruptFlag (EUSCI_A0_BASE、EUSCI_A_UART_receive_interrupt);
    
    flags_u8 = MAP_UART_queryStatusFlags (EUSCI_A0_BASE、EUSCI_A_UART_组 帧错误+ EUSCI_A_UART_over_error + EUSCI_A_UART_parquiation_error + EUSCI_A_UART_break_detect + EUSCI_A_UART_receive_error);
    RX_char_u8 = MAP_UART_receiveData (EUSCI_A0_BASE);
    
    如果(!flags_u8)
    {
    //将接收到的字符放入缓冲区,以便在其他位置进行处理
    rxBuff_u8 = rx_char_u8;
    }
    }
    
    
    IF (STATUS_u8和 EUSCI_A_UART_Transmit _INTERRUPT)
    {
    //不要在此处清除 Tx 中断标志! 它的硬件控制。
    MAP_UART_transmitData (EUSCI_A0_BASE、txChar_u8++);
    }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Julian、
    谢谢。 当我更好地理解这一点时、我会查看并返回给您。
    -Bob
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    G'Day Bob、

    只需办理入住手续。 是否有任何进展?

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

    有新消息吗?

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

    重新签入。
    很高兴知道是否有任何进展!

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

    > MAP_UART_clearInterruptFlag (EUSCI_A0_BASE、EUSCI_A_UART_receive_interrupt);

    我建议您不要这样做。

    由于读取 RXBUF (几行后)会将 RXIFG (原子)清零、因此完全没有必要。

    它所做的是邀请一个可清除 TXIFG 的读取-修改-写入竞态。

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

    删除该行似乎可以解决问题。

    谢谢
    Julian