UART(Universal Asynchronous Receiver-Transmitter)是一种常见的串行通信接口,用于在两个设备之间传输数据。TIVA C系列单片机基于ARM Cortex-M4内核,提供了多个UART模块,支持全双工通信。UART通信的基本原理如下:
UART通信是一种异步通信方式,这意味着发送方和接收方之间没有共享的时钟信号。每个字符的传输都由起始位和停止位来标记,以确保数据的正确传输。
UART数据帧通常由以下几个部分组成:
起始位:表示数据传输的开始,通常为一个低电平位。
数据位:实际传输的数据,通常为5到8位。
奇偶校验位:可选,用于检测数据传输错误。
停止位:表示数据传输的结束,通常为一个或多个高电平位。
波特率是UART通信中的一个重要参数,表示每秒传输的位数。发送方和接收方必须使用相同的波特率,以确保数据的正确传输。TIVA C系列单片机可以通过配置寄存器来设置UART的波特率。
为了提高系统的效率,TIVA C系列单片机支持UART中断和DMA(Direct Memory Access)传输。中断可以在数据接收或发送完成时触发,而DMA可以用于大批量数据的传输,减轻CPU的负担。
TIVA C系列单片机提供了多个UART模块,每个模块都可以独立配置和使用。这些UART模块通常包括以下功能:
全双工通信:可以同时发送和接收数据。
可配置的波特率:支持多种波特率设置。
奇偶校验:可以选择启用或禁用奇偶校验。
数据长度:可以设置为5到8位。
停止位:可以选择1或2个停止位。
中断支持:支持多种中断类型,包括接收完成、发送完成、错误检测等。
DMA支持:可以使用DMA进行高效的数据传输。
TIVA C系列单片机的UART模块有多个寄存器,用于配置和控制UART通信。主要的寄存器包括:
UARTCTL
:控制寄存器,用于启用或禁用UART模块。
UARTIBRD
和 UARTFBRD
:波特率寄存器,用于设置UART的波特率。
UARTLCRH
:线路控制寄存器,用于设置数据位、停止位和奇偶校验位。
UARTCR
:时钟控制寄存器,用于配置UART的时钟。
UARTDR
:数据寄存器,用于读取接收到的数据或写入要发送的数据。
UARTFR
:标志寄存器,用于检查UART的状态,如接收缓冲区满、发送缓冲区空等。
UARTIM
和 UARTRIS
:中断使能寄存器和中断状态寄存器,用于配置和检查中断。
在使用UART模块之前,需要进行一系列的配置步骤,包括设置波特率、数据位、奇偶校验位和停止位等。以下是一个详细的配置步骤示例:
波特率的设置通过UARTIBRD
和UARTFBRD
两个寄存器来完成。以下是一个设置波特率为115200的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
通过UARTLCRH
寄存器可以设置数据位、停止位和奇偶校验位。以下是一个设置8位数据位、1个停止位和无奇偶校验的示例代码:
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
UART模块支持多种中断类型,可以通过UARTIM
和UARTRIS
寄存器来配置和检查中断。以下是一个配置接收完成中断的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
void UARTIntHandler(void) {
// 清除UART中断标志
UARTIntClear(UART0_BASE, UARTIntStatus(UART0_BASE, true));
// 读取接收到的数据
uint8_t data = UARTCharGet(UART0_BASE);
// 处理接收到的数据
// 例如,将数据发送回发送方
UARTCharPut(UART0_BASE, data);
}
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART中断
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
// 注册UART中断处理函数
IntEnable(INT_UART0);
UARTIntRegister(UART0_BASE, UARTIntHandler);
// 启用UART0模块
UARTEnable(UART0_BASE);
}
DMA(Direct Memory Access)可以用于高效的数据传输,减少CPU的负担。以下是一个配置UART0模块使用DMA进行数据传输的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/dma.h"
#include "driverlib/gpio.h"
#define UART_DMA_TX_CHANNEL 0
#define UART_DMA_RX_CHANNEL 1
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 使能DMA控制器的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 配置UART0模块的DMA通道
uDMAChannelAssign(UART_DMA_TX_CHANNEL);
uDMAChannelAssign(UART_DMA_RX_CHANNEL);
// 配置DMA传输
uDMAChannelAttributeEnable(UART_DMA_TX_CHANNEL, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
uDMAChannelAttributeEnable(UART_DMA_RX_CHANNEL, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
uDMAChannelControlSet(UART_DMA_TX_CHANNEL, UDMA_SIZE_8 | UDMA_SRC_INCREMENT | UDMA_DST_NO_CHANGE | UDMA_ARB_1);
uDMAChannelControlSet(UART_DMA_RX_CHANNEL, UDMA_SIZE_8 | UDMA_SRC_NO_CHANGE | UDMA_DST_INCREMENT | UDMA_ARB_1);
uDMAChannelModeSet(UART_DMA_TX_CHANNEL, UDMA_MODE_PERIPHERAL_TO_MEMORY);
uDMAChannelModeSet(UART_DMA_RX_CHANNEL, UDMA_MODE_MEMORY_TO_PERIPHERAL);
// 启用UART0模块的DMA请求
UARTDMARxEnable(UART0_BASE);
UARTDMATxEnable(UART0_BASE);
// 启用UART0模块
UARTEnable(UART0_BASE);
}
void UARTDMA_TX(uint8_t *pData, uint32_t length) {
// 配置DMA传输数据
uDMAChannelTransferSet(UART_DMA_TX_CHANNEL, UDMA_MODE_PERIPHERAL_TO_MEMORY, (void *)pData, length);
// 启用DMA传输
uDMAChannelEnable(UART_DMA_TX_CHANNEL);
}
void UARTDMA_RX(uint8_t *pData, uint32_t length) {
// 配置DMA接收数据
uDMAChannelTransferSet(UART_DMA_RX_CHANNEL, UDMA_MODE_MEMORY_TO_PERIPHERAL, (void *)pData, length);
// 启用DMA接收
uDMAChannelEnable(UART_DMA_RX_CHANNEL);
}
通过UARTCharPut
函数可以发送单个字符,通过UARTCharPutNonBlocking
函数可以非阻塞地发送字符。以下是一个发送字符串的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
void sendString(const char *str) {
while (*str) {
UARTCharPut(UART0_BASE, *str++);
}
}
int main(void) {
configure UART();
// 发送字符串
sendString("Hello, UART!");
while (1) {
// 主循环
}
}
通过UARTCharGet
函数可以接收单个字符,通过UARTCharGetNonBlocking
函数可以非阻塞地接收字符。以下是一个接收字符串的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
void configure UART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
void receiveString(char *buffer, uint32_t maxLength) {
uint32_t i = 0;
char c;
while (i < maxLength - 1) {
c = UARTCharGet(UART0_BASE);
if (c == '\r' || c == '\n') {
buffer[i] = '\0';
break;
}
buffer[i++] = c;
}
buffer[i] = '\0';
}
int main(void) {
configure UART();
char buffer[32];
// 接收字符串
receiveString(buffer, sizeof(buffer));
// 发送接收到的字符串
sendString(buffer);
while (1) {
// 主循环
}
}
在实际应用中,TIVA C系列单片机经常与PC进行通信。以下是一个使用UART与PC通信的示例代码,包括发送和接收数据的功能:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
#include "utils/uartstdio.h"
// 配置UART模块
void configureUART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
// 发送字符串
void sendString(const char *str) {
while (*str) {
UARTCharPut(UART0_BASE, *str++);
}
}
// 接收字符串
void receiveString(char *buffer, uint32_t maxLength) {
uint32_t i = 0;
char c;
while (i < maxLength - 1) {
c = UARTCharGet(UART0_BASE);
if (c == '\r' || c == '\n') {
buffer[i] = '\0';
break;
}
buffer[i++] = c;
}
buffer[i] = '\0';
}
int main(void) {
char buffer[32];
// 配置UART模块
configureUART();
// 发送初始化信息
sendString("UART Communication with PC Initialized\r\n");
while (1) {
// 接收字符串
receiveString(buffer, sizeof(buffer));
// 发送接收到的字符串
sendString("Received: ");
sendString(buffer);
sendString("\r\n");
}
}
除了与PC通信,TIVA C系列单片机还可以与其他外部设备进行通信。以下是一个使用UART与一个外部传感器通信的示例代码,包括发送命令和接收传感器数据的功能:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"
#include "utils/uartstdio.h"
// 配置UART模块
void configureUART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART0模块
UARTEnable(UART0_BASE);
}
// 发送命令
void sendCommand(const char *command) {
while (*command) {
UARTCharPut(UART0_BASE, *command++);
}
}
// 接收传感器数据
void receiveSensorData(char *buffer, uint32_t maxLength) {
uint32_t i = 0;
char c;
while (i < maxLength - 1) {
c = UARTCharGet(UART0_BASE);
if (c == '\r' || c == '\n') {
buffer[i] = '\0';
break;
}
buffer[i++] = c;
}
buffer[i] = '\0';
}
int main(void) {
char buffer[32];
const char *sensorCommand = "READ_SENSOR";
// 配置UART模块
configureUART();
// 发送初始化信息
sendString("UART Communication with Sensor Initialized\r\n");
while (1) {
// 发送命令给传感器
sendCommand(sensorCommand);
sendString("Command sent: ");
sendString(sensorCommand);
sendString("\r\n");
// 接收传感器数据
receiveSensorData(buffer, sizeof(buffer));
sendString("Received sensor data: ");
sendString(buffer);
sendString("\r\n");
// 延时一段时间
SysCtlDelay(SysCtlClockGet() / 3); // 大约1秒的延时
}
}
在实际应用中,使用中断处理UART数据可以提高系统的响应速度和效率。以下是一个使用中断处理UART数据的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
// UART中断处理函数
void UARTIntHandler(void) {
// 清除UART中断标志
UARTIntClear(UART0_BASE, UARTIntStatus(UART0_BASE, true));
// 读取接收到的数据
uint8_t data = UARTCharGet(UART0_BASE);
// 处理接收到的数据
// 例如,将数据发送回发送方
UARTCharPut(UART0_BASE, data);
}
// 配置UART模块
void configureUART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 启用UART中断
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
// 注册UART中断处理函数
IntEnable(INT_UART0);
UARTIntRegister(UART0_BASE, UARTIntHandler);
// 启用UART0模块
UARTEnable(UART0_BASE);
}
int main(void) {
// 配置UART模块
configureUART();
// 发送初始化信息
UARTCharPut(UART0_BASE, 'H');
UARTCharPut(UART0_BASE, 'e');
UARTCharPut(UART0_BASE, 'l');
UARTCharPut(UART0_BASE, 'l');
UARTCharPut(UART0_BASE, 'o');
UARTCharPut(UART0_BASE, ',');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'U');
UARTCharPut(UART0_BASE, 'A');
UARTCharPut(UART0_BASE, 'R');
UARTCharPut(UART0_BASE, 'T');
UARTCharPut(UART0_BASE, '!');
UARTCharPut(UART0_BASE, '\r');
UARTCharPut(UART0_BASE, '\n');
while (1) {
// 主循环
}
}
DMA(Direct Memory Access)可以用于高效的数据传输,减少CPU的负担。以下是一个配置UART0模块使用DMA进行数据传输的示例代码:
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/dma.h"
#include "driverlib/gpio.h"
#define UART_DMA_TX_CHANNEL 0
#define UART_DMA_RX_CHANNEL 1
// 配置UART模块
void configureUART(void) {
// 设置系统时钟为50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
// 使能UART0模块的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
// 使能GPIO端口A的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// 使能DMA控制器的时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
// 配置GPIO引脚为UART功能
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
// 设置波特率为115200
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, SysCtlClockGet());
// 配置数据位、停止位和奇偶校验位
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
// 配置UART0模块的DMA通道
uDMAChannelAssign(UART_DMA_TX_CHANNEL);
uDMAChannelAssign(UART_DMA_RX_CHANNEL);
// 配置DMA传输
uDMAChannelAttributeEnable(UART_DMA_TX_CHANNEL, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
uDMAChannelAttributeEnable(UART_DMA_RX_CHANNEL, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
uDMAChannelControlSet(UART_DMA_TX_CHANNEL, UDMA_SIZE_8 | UDMA_SRC_INCREMENT | UDMA_DST_NO_CHANGE | UDMA_ARB_1);
uDMAChannelControlSet(UART_DMA_RX_CHANNEL, UDMA_SIZE_8 | UDMA_SRC_NO_CHANGE | UDMA_DST_INCREMENT | UDMA_ARB_1);
uDMAChannelModeSet(UART_DMA_TX_CHANNEL, UDMA_MODE_PERIPHERAL_TO_MEMORY);
uDMAChannelModeSet(UART_DMA_RX_CHANNEL, UDMA_MODE_MEMORY_TO_PERIPHERAL);
// 启用UART0模块的DMA请求
UARTDMARxEnable(UART0_BASE);
UARTDMATxEnable(UART0_BASE);
// 启用UART0模块
UARTEnable(UART0_BASE);
}
// 使用DMA发送数据
void UARTDMATx(uint8_t *pData, uint32_t length) {
// 配置DMA传输数据
uDMAChannelTransferSet(UART_DMA_TX_CHANNEL, UDMA_MODE_PERIPHERAL_TO_MEMORY, (void *)pData, length);
// 启用DMA传输
uDMAChannelEnable(UART_DMA_TX_CHANNEL);
}
// 使用DMA接收数据
void UARTDMARx(uint8_t *pData, uint32_t length) {
// 配置DMA接收数据
uDMAChannelTransferSet(UART_DMA_RX_CHANNEL, UDMA_MODE_MEMORY_TO_PERIPHERAL, (void *)pData, length);
// 启用DMA接收
uDMAChannelEnable(UART_DMA_RX_CHANNEL);
}
int main(void) {
char txBuffer[32] = "Hello, UART DMA!";
char rxBuffer[32];
// 配置UART模块
configureUART();
// 发送字符串
UARTDMATx((uint8_t *)txBuffer, sizeof(txBuffer));
// 接收字符串
UARTDMARx((uint8_t *)rxBuffer, sizeof(rxBuffer));
while (1) {
// 主循环
}
}
通过上述示例,我们可以看到TIVA C系列单片机的UART模块在各种应用场景中都非常灵活和强大。无论是简单的字符发送和接收,还是复杂的中断和DMA处理,TIVA C系列单片机的UART模块都能提供高效的解决方案。在实际开发中,可以根据具体需求选择合适的配置方法,以实现最佳的通信效果。