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.

[参考译文] MSP430FR5969:UART 问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1167077/msp430fr5969-issues-with-uart

器件型号:MSP430FR5969

我在电路板上使用 MSP430FR5969。 我的 UART 配置为:

// Setting for 16 MHz clock (230400)
EUSCI_A_UART_initParam param = {0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 4;
param.firstModReg = 5;
param.secondModReg = 0x55;
param.parity = EUSCI_A_UART_NO_PARITY;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
if (STATUS_FAIL == EUSCI_A_UART_init(EUSCI_A0_BASE, &param))
        return;
EUSCI_A_UART_enable(EUSCI_A0_BASE);
EUSCI_A_UART_clearInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
// Enable USCI_A0 RX interrupt
EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt

我在 UART RX 上没有封包大小、因此我首先要使用处于中断模式的 UART 来接收第一个字节、然后在接收完所有字节之前禁用中断。 我不能讨论我正在使用的帧技术、但我认为它是有效的。  

接收到完整的数据包后、我再次启用 UART 中断。 用于轮询我正在使用的 UART 数据  

inline char UART_getChar (void)
{
    while (!(UCA0IFG&UCRXIFG));     // RX buffer got data ?
    return UCA0RXBUF;
}

MSP 每1秒获取一次数据包 我遇到的问题是、随机(可能是10个数据包或2000个以上的数据包)代码在 while 循环 中卡住并旋转(!(UCA0IFG&UCRXIFG);   // RX 缓冲区有数据? "。 我知道、电路板每秒都会连续接收数据包。 我检查  了 UCA0IFG、它卡在0。 您能帮助解决此问题吗?  代码是否有问题或这是否是微处理器的问题? 我无法共享我的完整代码。 TIA

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

    当 RXBUF 有数据可用时、RXIFG 将一直被置位。 因此、它未被置位表明未接收到任何数据。

    这样的阻止接收不是很可靠、如果发生错误、程序将会卡住。 强烈建议包含某种超时机制。

    ISR 可能会启用(和清除) RXIFG 中断、这样您的自旋环路就不会看到它。 具体取决于您拒绝显示的代码。 问题几乎肯定出在您的代码上。

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

    尊敬的 Atma:

    您还可以考虑检查如何启用和禁用中断。 我们在 UART 上有代码、可在 TI 资源浏览器中为您提供帮助。 是一个 UART 示例、左侧目录中还有3个其他示例。

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

    我的 ISR

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_A0_VECTOR)))
    #endif
    void USCI_A0_ISR(void)
    {
      switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
      {
        case USCI_NONE: break;
        case USCI_UART_UCRXIFG:
            startFlag = UCA0RXBUF; // Global variable
            readBytes();
    
          break;
        case USCI_UART_UCTXIFG: break;
        case USCI_UART_UCSTTIFG: break;
        case USCI_UART_UCTXCPTIFG: break;
      }
    }

    以下是我的 readBytes 函数:

    inline char UART_getChar (void)
    {
        while (!(UCA0IFG & UCRXIFG));     // RX buffer got data ?
        return UCA0RXBUF;
    }
    
    
    void readBytes(void){
    
        int i;
    
        EUSCI_A_UART_disableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Disable interrupt
        if (startFlag == <startFrame Char>)
        {
            for (i = 0; i <16; i++)
            {
                packet[i] = UART_getChar();
            }
            UART_getChar(); // ignore end of frame char
    
            // Do something here
            
            EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt
            
        }
        else // Not startFrame char
            EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt
    }

    我不确定如果 UART 中断被禁用、ISR 如何清除 RXIFG。 由于数据包每隔1秒发送(验证)一次、因此它应该会看到 UCA0IFG 的变化。  

    不使用纯 ISR 或基于 DMA (每个 DMA 中断1个字节)的 UART 的原因是我看到随机丢弃的字节。 至于超时、我也尝试过、似乎它会丢失数据包-我无法松开任何数据包。 有什么想法吗?

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

    是的。

    禁用接收中断实际上不会执行任何操作。 您从 ISR 内调用 readBytes()。 当响应任何中断时、GIE 被硬件清零、所以在你设置 GIE 或从 ISR 返回之前、不会发生中断。

    从 ISR 内部接收其余字节是一种很糟糕的做法、因为在该过程完成时不会发生任何其他情况。

    当循环挂起等待 RXIFG 时、程序状态到底是什么? 缓冲区中是否有数据? 是否无错误?

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

    当代码挂起时- UCA0RXBUF 中的数据为0x0005CC (I 不发送0xCC CHAR)、UCA0IFG 为0x0005DC。 其他寄存器包括:

    UCA0IE = 0x0005DA

    UCA0IV = 0x0005DE

    UCA0STATW = 0x0005CA

    UCA0CTLW1 = 0x0005C2

    UCA0CTLW1 = 0x0005C0

    UCA0BRW = 0x0005C6

    UCA0MCTLW = 0x0005C8

    也许这会使人有所了解

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

    您好、Atma、让我仔细看一下这个、然后返回给您。

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

    您确实需要清除 ISR 中的中断。 您可以尝试在主循环中禁用和启用中断吗?