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.

[参考译文] TM4C129ENCPDT:如何在从深度睡眠模式唤醒时快速接收 UART 字节?

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1398667/tm4c129encpdt-how-to-receive-uart-bytes-quickly-when-waking-from-deep-sleep

器件型号:TM4C129ENCPDT

工具与软件:

我目前正在使用 TM4C129ENCPDT 微控制器上的 FreeRTOS。 为了省电、我在空闲挂钩中使用深度睡眠、如下所示:

void vApplicationIdleHook( void ) {
    SysCtlDeepSleep();
}

我的 UART 配置为:波特57600、UART 时钟为16MHz 的 PIOSC。

SysCtlPeripheralEnable(UART0_BASE);
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTConfigSetExpClk(UART0_BASE, 16000000, 57600,
    (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |
     UART_CONFIG_WLEN_8));
UARTEnable(UART0_BASE);

IntEnable(INT_UART0);
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

在 UART 中断处理程序中、我将复制接收到的字节到 FreeRTOS 队列中(另一个任务将处理该队列):

void UARTIntHandler(void)
{
    // Get the interrupt status.
    uint32_t status = UARTIntStatus(UART0_BASE, true);

    // Clear the asserted interrupts.
    UARTIntClear(UART0_BASE, status);

    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    while(UARTCharsAvail(UART0_BASE)) {
        char c = UARTCharGetNonBlocking(UART0_BASE);
        // Read the next character from the UART and write it into the UART buffer
        xQueueSendFromISR(UARTBytesQueue, &c, &xHigherPriorityTaskWoken);
    }
    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

我的问题是:当我向 MCU 发送一条超过16个字节的消息时、只有前16个字节被正确接收。 我怀疑这是由于内部 UART FIFO 缓冲区是16个字节、并且我的代码从深度睡眠模式中唤醒需要太长的时间、因此 UART FIFO 缓冲区会填满并导致后续字节丢失。 如果我使用 SysCtlSleep ()而不是 SysCtlDeepSleep ()、则不会出现问题。

是否有办法增大 UART FIFO 缓冲区大小? 如果没有、如何解决该问题、以确保在 MCU 唤醒时从 UART 接收到的字节不会丢失? 我想在处理器空闲时进入深度睡眠模式、但似乎我无法在 UART FIFO 填满之前足够快地从深度睡眠模式中唤醒。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="614797" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1398667/tm4c129encpdt-how-to-receive-uart-bytes-quickly-when-waking-from-deep-sleep "]

    我的问题是:当我向 MCU 发送一条超过16个字节的消息时、只有前16个字节被正确接收。 我怀疑这是由于内部 UART FIFO 缓冲区是16个字节、并且我的代码从深度睡眠模式中唤醒需要太长的时间、因此 UART FIFO 缓冲区会填满并导致后续字节丢失。 如果我使用 SysCtlSleep ()而不是 SysCtlDeepSleep ()、则不会出现问题。

    是否有办法增大 UART FIFO 缓冲区大小? 如果没有、如何解决该问题、以确保在 MCU 唤醒时从 UART 接收到的字节不会丢失? 我想在处理器空闲时进入深度睡眠模式、但似乎我无法在 UART FIFO 填满之前足够快地从深度睡眠模式中唤醒。

    [报价]

    如果发生溢出、则将对 UARTRSR 寄存器中的 OE 位进行置位。 请确认是否是这种情况。 如果 OE 标志确实被设置、那么您当前只通过输入 SysCtlSleep 进行的操作是最佳选择。 硬件 FIFO 只有16入口深度。 没有其他方法可以改变。 一种可以尝试的方法是将 RXIFOSEL 更改为生成中断的最小阈值。 通过将 RXIFLSEL 配置为0、您将在2个字节到达时生成中断。 这将为 FIFO 提供更多的时间来在处理器唤醒时缓冲后续数据。 如果仍导致溢出、则您无需进入 DEEPSLEEP 模式、因为唤醒时间比数据进入 FIFO 的速度更长。  

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

    谢谢。 我确认 UART 缓冲区确实发生了溢出。

    遗憾的是、将 UARTIFLS 设置 为最小阈值 似乎无法解决问题。 如果我希望收到 UART 消息、则不进入深度睡眠状态来解决此问题。

    顺便说一下、 UARTIFLS 的偏移量在数据表中记录为0x0034、但在我使用的 SDK 中、偏移量在 inc/hw_types.h 中为0x38 我正在使用 TivaWare_C_Series-2.2.0.295、请参阅 www.ti.com/.../spms441b.pdf 的第1316页。

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

    Eric、您好!

    顺便说一句、 UARTIFLS 的偏移量在数据表中记录为0x0034、但在我使用的 SDK 中、inc/hw_types.h
    中的偏移量是0x38

    请使用经过验证的 API 来配置 RX 或 TX FIFO 阈值级别。