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:eUSI_A UART丢失UCTXIFG标志,导致发射器挂起

Guru**** 2595770 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/638950/msp432p401r-eusci_a-uart-losing-the-uctxifg-flag-causing-transmitter-to-hang

部件号:MSP432P401R

我遇到了MSP432 eUSI_A UART丢失UCAxIFG寄存器中的UCTXIFG标志导致发射器挂起的问题。  仅在同时传输和接收字符时出现问题。  如果我没有接收,发射器工作正常,但当它开始接收字符时,UCTXIFG标志停止发出,并且发射器中断不会发生。  (所有这些都是在尝试在微型和PC之间实施数据传输协议时发现的,我在过去的几年中使用各种MSP430s和TIVA芯片多次实施了这种协议,没有遇到任何问题。)  我设法将这归结为一个非常小的演示程序,它可靠地再现了问题。  在此程序中,每次发生EUSCI_A_UART_Transmit_interrupT_flag中断时,我都会发送'c'。  每次发生EUSCI_A_UART_receive中断标志中断时,我都会收到该字符并忽略它。  我连接到PC上的超级终端,并收到一串'c'字符,只要我不尝试将字符键入到微型计算机,这些字符就会继续。  当我将字符键入到微电脑时(有时会占用大量字符),它最终将停止发送。  当我查看该程序正在执行的操作时,我发现UCTXIFG已关闭。  它保持关闭,并且EUSCI_A_UART_Transmit_InterrupT_flag中断未发生。  但它接收到的字符正常。

我正在使用红色MSP432 Launchpad,版本C MSP432和1.50 驱动程序库的00.12 版本。  

要重现此问题:

1.使用00.12 1.50 编译并链接程序,然后将其下载到MSP432启动板。

2.在PC上打开超级终端,并以92.16万波特,8位,无奇偶校验,无流控制的方式连接到Launchpad的用户UART端口。

3.启动公共卫生和社会福利部的方案432。  您应该会在超级终端上看到连续的'c'字符串。

4.在键盘上键入fast to HyperTerminal。  您可能需要在键盘上按几秒钟。  最后,'c'字符将停止。

5.回顾MSP432计划,您将看到UCTXIFG已关闭,不再继续。


该程序还包含我一直使用的变通办法的代码。  如果取消注释"#define KLUDGEY_FIX"语句,则编译变通办法。  然后,代码将尝试使用EUSCI_A_UART_Transmit_Complete_interrupt来检测UCTXIFG的丢失并输出到TXBUF。  这会导致所有中断恢复,并且EUSCI_A_UART_Transmit_InterrupT_flag中断再次开始发生。  使用此代码时,我无法使用超级终端使传输器出现故障。

我尝试过较慢波特率的代码。  我仍然能够使其失败,但需要在超级终端上输入更多内容。

此错误似乎与勘误表(SSLAZ610J)中为Rev C和Rev D处理器报告的许多eUSCI错误相似,但不完全相同。  虽然我的变通办法似乎可以正常工作,但最好能够真正解决问题,因为我正在处理的设备最终将是一种医疗设备,必须符合严格的可靠性标准。




/*
  对于波特率9600和SMCLK =2400万,设置BRDIV=156,UCxBRF=4,UCxBRS=0
  对于波特率11.52万和SMCLK =2400万,设置BRDIV=13,UCxBRF=0,UCxBRS=37
  对于波特率23.04万和SMCLK =2400万,设置BRDIV=6,UCxBRF=8,UCxBRS=32
  对于波特率46.08万和SMCLK =2400万,设置BRDIV=3,UCxBRF=4,UCxBRS=2
  对于波特率92.16万和SMCLK =2400万,设置BRDIV=1,UCxBRF=10,UCxBRS=0
*/
/* DriverLib包括*/
#include "driverlib.h"

/*标准包括*/
#include <stdint.h>

#include <stdbool.h>

#include <string.h>

#Define Launchpad_only

// Launchpad上P2上的RGB LED针脚
#define P2_RED_LED_H GPIO _PIN0
#define P2_BLUE_LED_H GPIO _PIN2
#define P2_GREG_LED_H GPIO _PIN1
#define P2_All_LEDs_H (P2_RED_LED_H|P2_BLUE_LED_H|P2_GREG_LED_H)




//#define KLUDGEY_FIX实现错误的解决方法,其中eUSI_A单元在UCAxIFG寄存器中丢失UCTXIFG标志。
//#定义KLUDGEY_FIX




   
//假定SMCLK =2400万,将波特率设置为92.16万
#define A0_BRDIV 1.
#define A0_UCxBRF 10.
#define A0_UCXBRS 0

const eUSI_UART_Config uartConfig =

       EUSCI_A_UART_CLOCKSOURCE_SMCLK,         // SMCLK时钟源
       A0_BRDIV,                               // BRDIV
       A0_UCxBRF,                              // UCxBRF
       A0_UCxBRS,                              // UCxBRS
       EUSCI_A_UART_NO_PARity                 ,//无奇偶校验
       EUSCI_A_UART_LSB优先,                 // LSB优先
       EUSCI_A_UART_ONE_STOP_BIT              ,//一个停止位
       EUSCI_A_UART_MODE,                      // UART模式
       EUSCI_A_UART_ORTS_Ooversampling_BAUDRATE_generation // Oversampling
};


空InitUart ()

   /*在UART模式下选择WFP 1.2 和WFP 1.3 */
   MAP_GPIO_setAsPeripheralModuleFunctionInputPin (GPIO端口P1,GPIO _PIN2 | GPIO _PIN3,GPIO主要模块功能);

   /*配置UART模块*/
   MAP_UART_INITModule (EUSCI_A0_BASE,&uartConfig);

   /*启用UART模块*/
   MAP_UART_enableModule (EUSCI_A0_BASE);

   /*启用中断*/

#ifdef KLUDGEY_FIX
   MAP_UART_enableInterrupt (EUSCI_A0_BASE,EUSCI_A_UART_receive _interrupt | EUSCI_A_UART_Transmit_interrupt | EUSCI_A_UART_Transmit_Complete_interrupt);
#否则
   MAP_UART_enableInterrupt (EUSCI_A0_BASE,EUSCI_A_UART_receive _interrupt | EUSCI_A_UART_Transmit_interrupt);
#endif
   
   MAP_Interrupt_enableInterrupt (INT_EUSCIA0);
   
   //开始传输字符
   MAP_UART_HESRData(EUSI_A0_base,(uint_fast8_t)'c');
}





   
// ESCI A0 UART接收ISR -将数据回波到PC主机
void EUSCIA0_IRQHandler (void)

   UINT32_t status = MAP_UART_getEnabableInterruptStatus(EUSSCI_A0_base);
   
   MAP_UART_CLEARInterruptFlag (EUSCI_A0_BASE,状态);

   IF (状态和EUSCI_A_UART_receive中断标志)
   {
      //丢弃收到的数据
      MAP_UART_receiveData (EUSCI_A0_BASE);
   }

   IF (状态和EUSCI_A_UART_Transmit_InterrupT_flag)
   {
      //在此处传输下一个字节
      MAP_UART_HESRData(EUSI_A0_base,(uint_fast8_t)'c');
   
   }
   
#ifdef KLUDGEY_FIX
   
   否则
   {
      //尝试缓解UCTXIFG标志丢失的问题。  当您以高波特率传输时,似乎会发生这种情况
      //同时也接收字节。  该错误似乎与一些USC144等USCI勘误表项目类似,但在本例中,我们是
      //正在使用与MCLK同步的时钟源。  在此修复程序中,我们尝试使用UCTXCPTIFG (传输完成)来检测时间
      //我们可以在丢失UCTXIFG标志后发送下一个字符。  勘误表项目USGI42表明,这也可能存在问题,
      //但到目前为止的测试表明此修复程序有效。
      UINT_fast8_t intEnabled;
      
      // UART_getEnabledInterruptStatus将仅返回EUSCI_A_UART_receive中断标志或EUSCI_A_UART_Transmit_InterrupT_flag SO
      //我们必须以这种方式获得EUSCI_A_UART_Transmit_complete_interrupT_flag。
      状态= UART_getInterruptStatus (EUSCI_A0_BASE,EUSCI_A_UART_Transmit_Complete_Interrupt_flag);
      intEnabled = EUSCI_A_CMSIS (EUSSCI_A0_base)->IE;
      
      IF (未启用和状态)
      {
         UART_clearInterruptFlag (EUSCI_A0_BASE,EUSCI_A_UART_Transmit_Complete_InterrupT_flag);
         
         //在没有设置TXIFG的情况下不可能完成传输,但当发射器挂起时,我们就能做到这一点
         如果(!BISTBAND_PERI(EUSI_A_CMIS(EUSSCI_A0_base)->IFG, EUSCI_A_IFG_TXIFG_OFS))
            EUSCI_A_CMSIS (EUSI_A0_base)->TXBUF ='X';      //尝试重新启动发射器
      }
   }
   
#endif   // KLUDGEY_FIX
   
}







内部主(无效)

   /*停止监视程序*/
   MAP_WDT_A_HoldTimer();
      
       //设置核心电压和闪存等待状态以支持以48 MHz运行
   MAP_PCM_setPowerState(PCM_AM_DCC_VCORE1);
   MAP_FlashCTL_setWaitState(FLASH_BANK0, 1);
   MAP_FlashCTL_setWaitState(FLASH_Bank1, 1);
       
   /*将GPIO配置为输出*/
   MAP_GPIO_setAsOutputPin (GPIO端口P1,GPIO _PIN0);

#ifdef Launchpad_only   //设置RGB LED输出引脚
   MAP_GPIO_setAsOutputPin (GPIO端口P2,P2_All_LEDs_H);
   MAP_GPIO_setOutputLowOnPin (GPIO端口P2,P2_All_LEDs_H);
#endif
   
   //将ACLK设置为VLOCLK (9.4 kHz)
   MAP_CS_INITClockSignal (CS_ACLK,CS_VLOCLK_SELECT,CS_CLock_diver_1);

   /*将DCO设置为48MHz */
   MAP_CS_setDCOCenteredFrequency (CS_DCO_Frequency_48);

   //将DCO用于MCLK和SMCLK
   MAP_CS_INITClockSignal (CS_MCLK,CS_DCOCLK_SELECT,CS_CLock_diver_1);
   MAP_CS_INITClockSignal (CS_SMCLK,CS_DCOCLK_SELECT,CS_CLock_DICROLOR_2);
   
   /*启用FPU并启用堆栈(用于ISR)*/
   MAP_FPU_enableModule();
   MAP_FPU_enableLazyStacking();

   //初始化UART并传输第一个字符
   InitUart();
   
   /*启用主中断*/
   MAP_Interrupt_enableMaster();  

   //所有操作现在都处于中断级别
   while (true)(对)
      MAP_PCM_GotoLPM0();
}





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

    我建议你不要这样做。 这是完全没有必要的,因为读取RXBUF或写入TXBUF (几行后)将自动(并在原子上)清除RXIFG/TXIFG。 [如果您没有任何东西要放入TXBUF,您应该关闭TXIE --您仍然不应该清除TXIFG。]

    它所做的是邀请一个读-修改-写竞赛,该竞赛可能会清除一个新生的TXIFG。 这可能在任何比特率下发生,但在较高速度下更有可能发生。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Bruce:

    感谢您的回复。  这似乎已经解决了问题。  我很惊讶,因为在我遇到问题的早期,我尝试取消对UART_clearInterruptFlag的呼叫,但问题没有消失。  可能是当时我在做的其他事情。  TI示例程序(如“UART_PC_ECHO_12MHz_brclk.c”)确实调用了UART_clearInterruptFlag,这就是我将其放在首位的原因。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢Chuck。 我提交了一个错误,要求删除这些说明。

    此致,
    Chris