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.

[参考译文] MSP432E401Y:UART 中断未触发

Guru**** 2524550 points
Other Parts Discussed in Thread: MSP-EXP432E401Y

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1017319/msp432e401y-uart-interrupts-not-firing

器件型号:MSP432E401Y
主题中讨论的其他器件:MSP-EXP432E401Y

您好!

我正在 MSP-EXP432E401Y 开发板上开发 MSP432E401。  我正在尝试让一个简单的 UART 工作、但我似乎无法启动 ISR。  我已经从 SimpleLink SDK 运行了 UART_echo 演示、它可以按预期工作、但我的代码不能正常工作。  该项目基于 SDK 中的空示例、我已经将项目中的启动文件与 UART_echo 中的启动文件进行了比较、重要的是相同的。  如果我将 UART_ECHO.c 文件复制到我的项目中、并将其调整为在 UART5上运行(并排除我自己的 main.c)、演示代码将按预期工作- ISR 将按预期触发以回显接收到的字符。  

我使用的是 DriverLib、SimpleLink v4.20.00.12。  我的代码如下所示:

#include <stdint.h>
#include <stdbool.h>

#include "ti/devices/msp432e4/driverlib/driverlib.h"

#define UART_BUF_SIZE 32
volatile unsigned char uartBuf[UART_BUF_SIZE] = "System Test\n";
volatile unsigned char uartHead = 12, uartTail = 0, uartCount = 12;

void UART5_IRQHandler(void)
{
    uint32_t ui32Status = UARTIntStatus(UART5_BASE, true);
    UARTIntClear(UART5_BASE, ui32Status);

    if ((ui32Status & UART_INT_TX) && uartCount)
    {
        UARTCharPutNonBlocking(UART5_BASE, uartBuf[uartTail]);
        uartTail = (uartTail + 1) % UART_BUF_SIZE;
        uartCount--;
    }
}

int main(void)
{
    uint32_t SysClock;

    // running from PLL at 120 MHz
    SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    // enable main interrupts
    IntMasterEnable();

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    GPIOPinConfigure(GPIO_PC6_U5RX);
    GPIOPinConfigure(GPIO_PC7_U5TX);
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    UARTConfigSetExpClk(UART5_BASE, SysClock, 115200,
                          (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                           UART_CONFIG_PAR_NONE));

    IntEnable(INT_UART5);
    UARTIntEnable(UART5_BASE, UART_INT_RX | UART_INT_RT | UART_INT_TX);

    // start TX
    uartTail = 1;
    uartCount--;
    UARTCharPutNonBlocking(UART5_BASE, uartBuf[0]);

    while (1)
    {
    
    }
}

在连接到 PC5和 PC7的终端上、我可以看到第一个字符、但不再显示。  调试中、UART5 ISR 从未触发-看起来 TX 中断从未触发。  我已经按照这个示例和文档进行了操作、我不确定我在这里缺少什么-有人能不能建议我做的真正明显的错误、请回答?

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

    您好!

    您的代码看起来类似于 UART_ECHO 代码。 您是否曾尝试在代码中使用 UART0而不是 UART5?

    此致、

    现金 Hao

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

    今天早上、我用新鲜的眼光来看待这个问题、我发现了这个问题。  问题是 DriverLib 代码意外启用 FIFO 作为副作用。

    该链如下所示:

    1. 对 UARTConfigSetExpClk 的调用会禁用 UART、进行配置、然后重新启用 UART。  通过调用 UARTDisable 和 UARTEnable 来完成禁用和启用
    2. UARTEnable 还会启用 FIFO、而不管之前是否启用了 FIFO 等等
    3. 由于 FIFO 尚未设置、因此默认为1/2满或8字节
    4. 这意味着启用的中断不会触发、因为代码需要单字节硬件缓冲区

    根本的问题是 UARTEnable 也启用 FIFO。  我建议这种行为是一个错误(尽管在 API 文档中列出、现在我知道要查找什么)、因为它会引入不需要的副作用。  如果用户希望使用 FIFO、则应显式启用 FIFO、而不是通用外设启用、前提是您始终需要 FIFO (需要用户对 UARTDisableFIFO 进行额外调用以清理状态)。

    同样、从不使用 TX IRQ、而是依赖 RT 而不是 RX IRQ 来接收字节、样本代码也无法方便地解决问题。  实际上、它具有未记录的副作用、即启动消息的传输方式依赖于 TX FIFO 被启用、否则您将丢失字节(并且永远不知道)。  如果您尝试使用 UARTSend 函数在 UART 超时前发送 FIFO 中超过的数据值、则还存在竞争条件(CPU 的运行速度比 UART 快很多); 这可以作为简单功能演示的副作用来接受、但文档应明确说明发生了什么、否则您只需为不谨慎行为留下陷阱。

    要回答以下问题、无论您使用哪种 UART、如果您使用 DriverLib、该错误都会产生。