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.

MSP432P401串口中断发送偶发失效问题请教?

说明条件:

1.MCU为MSP432P401R, 硬件为 TI官方的DEMO板developement kit。

2.串口时钟源为 SMCLK,波特率115200。 SMCLK时钟源为DCO, DCO 配置为3MHz;

3.串口开了EUSCI_A0 和 EUSCI_A2, A0接PC做调试口,A2接模块做应用;

4.串口收发均开启了中断;

问题描述:

串口A2在发送大约14KB的数据量,分包发送,每次发送约950字节,因组包代码耗时 ,等效包间延时约为20ms, 在发送随机的几包后,串口就不进中断了,仿真的时候可以看到,UCTXIFG未置位。串口发送停了。  然后,手动将此位改为1后,串口又能继续发送,直至所有数据发送完毕。 

此情况经常出现在从LPM3级的唤醒后。 不知是否有什么因素导致此问题。  

还请大家帮助一下。或是否有人遇到过这种情况。

附上串口的配置代码如下:

/*==============================================================================
 * Local macro define.
 *============================================================================*/
#define  DEBUG_COM_GPIO_PORT        GPIO_PORT_P1
#define  DEBUG_COM_GPIO_RX_PIN      GPIO_PIN2
#define  DEBUG_COM_GPIO_TX_PIN      GPIO_PIN3
#define  DEBUG_COM_GPIO_UART_FUN    GPIO_PRIMARY_MODULE_FUNCTION

#define  NBIoT_COM_GPIO_PORT        GPIO_PORT_P3
#define  NBIoT_COM_GPIO_RX_PIN      GPIO_PIN2
#define  NBIoT_COM_GPIO_TX_PIN      GPIO_PIN3
#define  NBIoT_COM_GPIO_UART_FUN    GPIO_PRIMARY_MODULE_FUNCTION


#define  DEBUG_COM_PORT_BASE        EUSCI_A0_BASE
#define  NBIoT_COM_PORT_BASE        EUSCI_A2_BASE
#define  DEBUG_COM_PORT_INT         INT_EUSCIA0
#define  NBIoT_PORT_INT             INT_EUSCIA2
#define  DEBUG_PORT_IRQ_HANDLER     EUSCIA0_IRQHandler
#define  NBIoT_PORT_IRQ_HANDLER     EUSCIA2_IRQHandler

global void gvIF_UARTInit( void )
{
/*!< software-dl.ti.com/.../
 *!<        MSP430BaudRateConverter/index.html 
 */
    const eUSCI_UART_Config aceCfg = 
	{
		.selectClockSource	= EUSCI_A_UART_CLOCKSOURCE_SMCLK,
		.clockPrescalar 	= 1,
		.firstModReg 		= 10,
		.secondModReg 		= 0,/*!< 115200 bps */
		.parity 			= EUSCI_A_UART_NO_PARITY,
		.msborLsbFirst 		= EUSCI_A_UART_LSB_FIRST,
		.numberofStopBits 	= EUSCI_A_UART_ONE_STOP_BIT,
		.uartMode 			= EUSCI_A_UART_MODE,
		.overSampling 		= EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION,
	};
	
	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin( DEBUG_COM_GPIO_PORT, 
                         (DEBUG_COM_GPIO_RX_PIN | DEBUG_COM_GPIO_TX_PIN), DEBUG_COM_GPIO_UART_FUN );
	MAP_UART_initModule( DEBUG_COM_PORT_BASE, &aceCfg );
    MAP_Interrupt_setPriority(DEBUG_COM_PORT_INT, 0x20);
	MAP_UART_enableModule(DEBUG_COM_PORT_BASE);
    /* Enabling interrupts */
    MAP_UART_enableInterrupt(DEBUG_COM_PORT_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT
                             /* + EUSCI_A_UART_TRANSMIT_INTERRUPT*/);
    MAP_UART_registerInterrupt(DEBUG_COM_PORT_BASE, DEBUG_PORT_IRQ_HANDLER);
    MAP_Interrupt_enableInterrupt(DEBUG_COM_PORT_INT);
    
    
    /*!< To configure USCI_A2_BASE as UART to communicate with NB-IoT. */
	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin( NBIoT_COM_GPIO_PORT, 
				         (NBIoT_COM_GPIO_RX_PIN | NBIoT_COM_GPIO_TX_PIN), NBIoT_COM_GPIO_UART_FUN );
	MAP_UART_initModule( NBIoT_COM_PORT_BASE, &aceCfg );
    MAP_Interrupt_setPriority(NBIoT_PORT_INT, 0x1F);
	MAP_UART_enableModule(NBIoT_COM_PORT_BASE);
    /* Enabling interrupts */
    MAP_UART_enableInterrupt(NBIoT_COM_PORT_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT
                            + EUSCI_A_UART_TRANSMIT_INTERRUPT);
    MAP_UART_registerInterrupt(NBIoT_COM_PORT_BASE, NBIoT_PORT_IRQ_HANDLER);
    MAP_Interrupt_enableInterrupt(NBIoT_PORT_INT);
    
    lvIF_NBIoTGpioConfigure();

    gwRxdIndex     = 0;
    lbTxBusy       = eUSCI_Idle;
}

/*!< interruption routine service. */
/* EUSCI A2 UART ISR - interaction with NB module. */
global void EUSCIA2_IRQHandler(void)
{
    uint8_t  abRcv;
    uint32_t adwStatus = MAP_UART_getEnabledInterruptStatus(NBIoT_COM_PORT_BASE);  

    MAP_UART_clearInterruptFlag(NBIoT_COM_PORT_BASE, adwStatus);

    if(adwStatus & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
    {
        abRcv = MAP_UART_receiveData(NBIoT_COM_PORT_BASE);
        if( gwRxdIndex < EUSCI_UART_RXD_BUFF_MAX )
        {
            lbRxdBuff[gwRxdIndex++] = abRcv;
        }
        else
        {
            gwRxdIndex = 0;
            lbRxdBuff[gwRxdIndex++] = abRcv;
        }
    }

    
    if(adwStatus & EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG)
    {
        if( lwTxdIndex < lwBufferedBytesTxd )
        {
            MAP_UART_transmitData(NBIoT_COM_PORT_BASE, lbTxdBuff[lwTxdIndex]);
            lwTxdIndex++;
        }
        
        if( lwTxdIndex >= lwBufferedBytesTxd )
        {
            if( lwRemainBytesTxd > EUSCI_UART_TXD_BUFF_MAX )
            {
                memcpy( lbTxdBuff, (void*)lpbRemain, EUSCI_UART_TXD_BUFF_MAX );                    
                lwRemainBytesTxd -= EUSCI_UART_TXD_BUFF_MAX;
                lpbRemain += EUSCI_UART_TXD_BUFF_MAX;
                lwTxdIndex = 0;
                lwBufferedBytesTxd = EUSCI_UART_TXD_BUFF_MAX;
            }
            else if( lwRemainBytesTxd > 0 )
            {
                memcpy( lbTxdBuff, (void*)lpbRemain, lwRemainBytesTxd );
                lwTxdIndex = 0;
                lwBufferedBytesTxd = lwRemainBytesTxd;
                lwRemainBytesTxd = 0U;
            } 
            else 
            { 
                lpbRemain = NULL; 
                lwRemainBytesTxd = 0; 
                lbTxBusy = eUSCI_Idle; 
            } 
        } 
    } 
}

  • 您现在发生UCTXIFG未置位的概率大约是多少?

    建议您分步调试,

    1 先屏蔽到串口EUSCI_A0 ,只使用 EUSCI_A2,以排除EUSCI_A0 对其的影响

    2 对EUSCI_A2修改不同波特率以及时钟源试试

    3 参考simplelink_msp432p4_sdk内的例程

    C:\ti\simplelink_msp432p4_sdk_3_10_00_08\examples\nortos\MSP_EXP432P401R\registerLevel
  • 每次唤醒后的发送中,都会有失效 ,只是每次失效时比较随机,比如 ,有次是发了7包,有次是发了10包,有次是发了14包后。
    另外,你说的A0对A2的影响,这有点不通理论吧, A0和A2是独立的,各有各的寄存器阵列,各接各的外设,仅是时钟源是共源于SMCLK。
    SDK内的例程无法模拟我目前复杂应用,数据量也不大,常规应用的示例性强,复合应用(连续的收发,多中断源等)情形的示例性弱。
  • 问题似乎是因为A2发送的数据会同时被自己接收到。 导致串口错误了。 有时会有UCOE置位。 但是我的问题依旧没有解决啊。
  • 问题根源没清楚,不过,也算是绕道解决了,公示一下解决办法。原理就是在接收中加入了OVERRUN_ERROR 的判断,并处理;在发送中加入了TXIFG和TXCPTIFG位的判断,因为出问题的时个,TXIFG没有置位,而TXCPTIFG却是置位了的。

    附上串口的中断函数。主要的修改点也是这里。

    global void EUSCIA2_IRQHandler(void)
    {
        uint8_t  abRcv;
        uint32_t adwStatus;
        
        adwStatus = EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->IFG & 
       (EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG + EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG +
        EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG);  
        MAP_UART_clearInterruptFlag(BLE_COM_PORT_BASE, adwStatus);
    
        if(adwStatus & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
        {
            if(EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->STATW 
               & EUSCI_A_UART_OVERRUN_ERROR)
            {
                if( gwRxdIndex < EUSCI_UART_RXD_BUFF_MAX )
                {
                    abRcv = EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->RXBUF;
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }            
                else
                {
                    gwRxdIndex = 0;
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }
            }
            else
            {
                abRcv = EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->RXBUF;
                if( gwRxdIndex < EUSCI_UART_RXD_BUFF_MAX )
                {
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }
                else
                {
                    gwRxdIndex = 0;
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }
            }
            if(EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->STATW 
               & EUSCI_A_UART_OVERRUN_ERROR)
            {
                if( gwRxdIndex < EUSCI_UART_RXD_BUFF_MAX )
                {
                    abRcv = EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->RXBUF;
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }            
                else
                {
                    gwRxdIndex = 0;
                    lbRxdBuff[gwRxdIndex++] = abRcv;
                }
            }
        }
    
        
        if(adwStatus & (EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG +
                        EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG))
        {
            if( lwTxdIndex < lwBufferedBytesTxd )
            {
                EUSCI_A_CMSIS(BLE_COM_PORT_BASE)->TXBUF = lbTxdBuff[lwTxdIndex];
                lwTxdIndex++;
            }
            else
            {
                lwTxdIndex = 0;
                lwBufferedBytesTxd = 0;
                lbTxBusy = eUSCI_Idle;
            }
        }
    }