背景:
我的 TM4C129上有专用的 UART6 (RX PP0)、用于从另一个传感器读取串行数据。 就 TM4C 上接收的数据而言、传感器每7ms 发送(n)个帧、每个帧的宽度为32字节。 两侧的波特率均为115200。
目标:
在这种情况下、速度至关重要、因为 TM4C 负责执行其他任务、例如读取编码器和限位开关。
因此、我想采用我的中断驱动方法(见下文)、并尝试查看是否可以利用 DMA 从 UART RX 外设存储器创建一个管道、然后将其放入我自己在 SW 中本地创建的缓冲区。
进度:
我已经修改了基本 UART_echo 示例、但很明显地更改了周围的内容、以便接收到的数据来自传感器、而不是来自用户的手动输入。 然后、当数据在 UART6上传入时、我会在 UART0上打印出来、并可以在串行控制台(RealTerm)中查看数据。
问题:
在读取 DMA 并查看 UDMA_DEMO 示例后、我认为这可能是最佳方法。 但是、我正在努力调整现有代码以使用它。 例如、我看到有大量代码通过 UART TX 发送数据、这是由 DMA 促成的。 但是、我看不到许多让 DMA 简单地从 UART RX 接收数据的示例。
请注意 、UDMA_DEMO 的功能 与 我想要的类似、但我似乎无法连接点。 例如、该示例应用的一个理想特征是它已将 DMA 设置为使用某种乒乓方法。 我阅读了 TivaWare 中的文档、并认为这肯定适用于我的应用、也就是说、当我通过 UART 收集这32个字节的数据时、我可以解析之前收集的帧(32字节)、 并在下一个32字节块出现时执行相应的操作。
我想这是一个很长的提问时间、这是我关于 DMA 如何与 UART RX 有效交互的思考过程(上面提到的外设管道思想)。 如果是、下一步的最佳方法是什么。 在 TivaWare 中是否有任何其他示例可供您考虑、在这种情况下、这些示例可能会有所帮助?
谢谢!
参考代码:
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
uint32_t g_ui32SysClock;
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
void UARTIntHandler(void)
{
uint32_t ui32Status;
ui32Status = ROM_UARTIntStatus(UART6_BASE, true);
/* Clear interrupts */
ROM_UARTIntClear(UART6_BASE, ui32Status);
/* Read data */
while(ROM_UARTCharsAvail(UART6_BASE))
{
/* Should move to blocking charGet() */
ROM_UARTCharPutNonBlocking(UART0_BASE, ROM_UARTCharGetNonBlocking(UART6_BASE));
/* Toggle LED for testing */
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
SysCtlDelay(g_ui32SysClock / (1000 * 3));
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
}
}
int main(void)
{
/* 120Mhz */
g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
/* LED */
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
/* UART 6 */
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
/* UART 0 */
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_IntMasterEnable();
/* Configure As UART 6 on PP0/1 */
GPIOPinConfigure(GPIO_PP0_U6RX);
GPIOPinConfigure(GPIO_PP1_U6TX);
ROM_GPIOPinTypeUART(GPIO_PORTP_BASE, GPIO_PIN_0 | GPIO_PIN_1);
/* Configure As UART 1 on PA0/1 */
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
/* 115200 8-N-1 */
ROM_UARTConfigSetExpClk(UART6_BASE, g_ui32SysClock, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
ROM_UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
/* Enable ISR */
ROM_IntEnable(INT_UART6);
ROM_IntEnable(INT_UART0);
ROM_UARTIntEnable(UART6_BASE, UART_INT_RX | UART_INT_RT);
while(1){}
}

