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.

[参考译文] TM4C129XNCZAD:UART 在调用 UARTConfigSetExpClk ()后报告中断和组帧错误

Guru**** 2422790 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/681484/tm4c129xnczad-uart-reports-break-and-framing-errors-after-calling-uartconfigsetexpclk

器件型号:TM4C129XNCZAD

我在这个论坛上看到其他几篇文章提到了类似的问题,但在任何地方都找不到明确的答案。

我的 UART 初始化代码如下所示:

//注意:我使用哪种 UART 无关紧要。 我尝试了0到7、它们都做了同样的事情。
#define PC_UART_SYSCTL SYSCTL_PERIPH_UART3
#define PC_UART_base UART3_base

SysCtlPeripheralEnable (PC_UART_SYSCTL);
while (!SysCtlPeripheralReady (PC_UART_SYSCTL))
{
}

UARTDisable (PC_UART_base);
UARTConfigSetExpClk (PC_UART_base、getSystemClockFreqHz ()、PC_UART_BAUD_RATE、
( UART_CONFIG_WLEN_8
| UART_CONFIG_STOP_ONE
| UART_CONFIG_PAR_NONE)); 

这似乎与 TivaWare 手册的编程示例部分中的代码相匹配。

稍后、我对 UART 执行环回测试:

bool 传递= true;

//必须在更改设置之前禁用
UARTDisable (PC_UART_base);

//将 UART 置于环回模式
PlaceUARToopback (PC_UART_base、1);

//清除任何挂起的 Rx 错误
UARTIntClear (PC_UART_base、0xffffffffff);
UARTRxErrorClear (PC_UART_base);

UARTEnable (PC_UART_base);
UARTCharPut (PC_UART_base、0x5a);
Value = UARTCharGet (PC_UART_base);
传递=(值= 0x5a);

如果(传递)
为{
*puStatus &=~post_UART_loopback;
}
否则
{
*puStatus |= POST_UART_LOOPACK;
}

UARTDisable (PC_UART_base);
PlaceUART环 回(PC_UART_base、0);

回送测试通常会失败(尽管会间歇性通过)。

如果我使用 CCS 调试器单步执行初始化代码、我会看到在调用 UARTConfigSetExpClk ()之后 、UART 的 RX 错误状态寄存器显示了一个中断和一个组帧错误、并且数据寄存器的内容为0x0500。 如果我继续步进、几条指令后、错误会被清除、DR 会进入0x0000。

但是、如果我没有  单步执行就只运行到环回测试、则错误仍然会被置位、并且 DR 仍然包含0x0500。 即使在环回测试代码中调用 UARTRxErrorClear ()后,错误位仍保持置位,导致测试失败。

我还发现、如果我在调用回送测试之前添加了100ms 的延迟、那么一切正常。

在 UART 控制寄存器的内容到达正确状态之前、似乎存在某种时间滞后。 在设置 UART 时、我是否忽略了一些操作?

此致、

Dave

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    UARTDisable()函数允许传输的字符完整。 您可能需要在调用 UARTBusy()时进行循环,以确保 UART 在调用 PlaceUARToopback ()之前完成了最后一个字符的传输。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Bob、

    在运行回送测试之前、我不发送/接收任何字符。 不过、根据您的建议、我将测试代码的开头更改为:

    UARTDisable (PC_UART_base);
    while (UARTBusy (PC_UART_base))



    //将 UART 置于环回模式
    PlaceUARTLoopback (PC_UART_base、1);

    但是、我仍然看到中断和帧错误。 我不明白为什么在发送字符之前显式清除 Rx 错误实际上不会清除 RSR 中的值。

    此外、如果我在执行读取操作之前设置一个断点、它会起作用。

    此致、

    Dave
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在启用 UART 并输入字符之前添加了延迟、我发现1ms 延迟足以使回送测试通过。 不过,不知道为什么有必要这样做。

    此致、

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

    修改 EK-TM4C129XL Booster Pack 的"Hello"示例以执行环回测试时、我没有遇到任何问题。 不需要 UARTEnable 和 UARTDisable、但添加后不会导致问题。 您的 PlaceUARToopback ()函数有什么作用?

    int
    main (void)
    {
    unsigned char 值;
    unsigned int divider;
    //
    //从 PLL 以120MHz 运行。
    //
    G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480)、120000000);
    
    //
    //配置器件引脚。
    //
    PinoutSet (false、false);
    
    //
    //为 LED D1 (PN1)启用 GPIO 引脚。
    //
    ROM_GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_1);
    
    //
    //初始化 UART。
    //
    ConfigureUART();
    
    //
    //您好!
    //
    UARTprintf ("Hello、world!\n");
    
    //确保 UART 已完成
    while (UARTBusy (UART0_BASE))
    {
    }
    UARTDisable (UART0_BASE);
    UARTLoopbackEnable (UART0_BASE);
    UARTEnable (UART0_BASE);
    UARTCharPut (UART0_BASE、0x5A);
    值= UARTCharGet (UART0_BASE);
    如果(0x5A =值)
    {
    分频器= 64U;//快速闪烁
    }
    其他
    {
    分频器= 16U;//缓慢闪烁
    }
    //
    //我们已完成。 在闪烁的 D1周围挂起。
    //
    while (1)
    {
    //
    //打开 D1。
    //
    LEDWrite (CLP_D1、1);
    
    //
    //延迟一位。
    //
    SysCtlDelay (g_ui32SysClock /分频器);
    
    //
    //关闭 D1。
    //
    LEDWrite (CLP_D1、0);
    
    //
    //延迟一位。
    //
    SysCtlDelay (g_ui32SysClock / divider);
    }
    }
    

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

    PlaceUARToopback ()代码为:

    void PlaceUARTLoopback (无符号长整型 ulBase、无符号长整型环回)

    //
    //检查参数。
    //
    assert (UARTBaseValid (ulBase));


    //
    //为 UART 启用或禁用回送
    //

    if (环回){
    HWREG (ulBase + UART_O_CTL)|= UART_CTL_LBE;

    否则{
    HWREG (ulBase + UART_O_CTL)&=(~UART_CTL_LBE);



    我想原始工程师从 TivaWare UARTLOopbackEnable()代码中获得了这一点,但是由于他需要禁用环回(奇怪的是,TivaWare 库似乎没有配置),所以他创建了一个同时执行这两个操作的新函数。

    此致、

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

    我在几周内忽略了这个问题之后,又重新讨论了这个问题。 在执行回送测试之前、我通过添加外设复位来获得通过测试的机会。 感谢 CB1的推荐(在我遇到 SSI 外设问题的另一个线程中)。

    //对 UART 外设执行完全复位以保证一个干净的状态
    SysCtlPeripheralReset (PC_UART_SYSCTL);
    while (!SysCtlPeripheralReady (PC_UART_SYSCTL))



    此致、

    Dave