Texas Instruments (TI) 系列:TIVA C 系列 (基于 ARM Cortex-M4)_(7).TIVA C系列UART通信

TIVA C系列UART通信

1. UART通信原理

UART(Universal Asynchronous Receiver-Transmitter)是一种常见的串行通信接口,用于在两个设备之间传输数据。TIVA C系列单片机基于ARM Cortex-M4内核,提供了多个UART模块,支持全双工通信。UART通信的基本原理如下:

在这里插入图片描述

1.1 异步通信

UART通信是一种异步通信方式,这意味着发送方和接收方之间没有共享的时钟信号。每个字符的传输都由起始位和停止位来标记,以确保数据的正确传输。

1.2 数据帧格式

UART数据帧通常由以下几个部分组成:

  • 起始位:表示数据传输的开始,通常为一个低电平位。

  • 数据位:实际传输的数据,通常为5到8位。

  • 奇偶校验位:可选,用于检测数据传输错误。

  • 停止位:表示数据传输的结束,通常为一个或多个高电平位。

1.3 波特率

波特率是UART通信中的一个重要参数,表示每秒传输的位数。发送方和接收方必须使用相同的波特率,以确保数据的正确传输。TIVA C系列单片机可以通过配置寄存器来设置UART的波特率。

1.4 中断和DMA

为了提高系统的效率,TIVA C系列单片机支持UART中断和DMA(Direct Memory Access)传输。中断可以在数据接收或发送完成时触发,而DMA可以用于大批量数据的传输,减轻CPU的负担。

2. TIVA C系列UART模块概述

TIVA C系列单片机提供了多个UART模块,每个模块都可以独立配置和使用。这些UART模块通常包括以下功能:

  • 全双工通信:可以同时发送和接收数据。

  • 可配置的波特率:支持多种波特率设置。

  • 奇偶校验:可以选择启用或禁用奇偶校验。

  • 数据长度:可以设置为5到8位。

  • 停止位:可以选择1或2个停止位。

  • 中断支持:支持多种中断类型,包括接收完成、发送完成、错误检测等。

  • DMA支持:可以使用DMA进行高效的数据传输。

2.1 UART模块寄存器

TIVA C系列单片机的UART模块有多个寄存器,用于配置和控制UART通信。主要的寄存器包括:

  • UARTCTL:控制寄存器,用于启用或禁用UART模块。

  • UARTIBRDUARTFBRD:波特率寄存器,用于设置UART的波特率。

  • UARTLCRH:线路控制寄存器,用于设置数据位、停止位和奇偶校验位。

  • UARTCR:时钟控制寄存器,用于配置UART的时钟。

  • UARTDR:数据寄存器,用于读取接收到的数据或写入要发送的数据。

  • UARTFR:标志寄存器,用于检查UART的状态,如接收缓冲区满、发送缓冲区空等。

  • UARTIMUARTRIS:中断使能寄存器和中断状态寄存器,用于配置和检查中断。

3. 配置UART模块

在使用UART模块之前,需要进行一系列的配置步骤,包括设置波特率、数据位、奇偶校验位和停止位等。以下是一个详细的配置步骤示例:

3.1 配置波特率

波特率的设置通过UARTIBRDUARTFBRD两个寄存器来完成。以下是一个设置波特率为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);

}

3.2 配置数据位、停止位和奇偶校验位

通过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);

}

3.3 配置中断

UART模块支持多种中断类型,可以通过UARTIMUARTRIS寄存器来配置和检查中断。以下是一个配置接收完成中断的示例代码:


#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);

}

3.4 配置DMA

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);

}

4. 使用UART进行数据传输

4.1 发送数据

通过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) {

        // 主循环

    }

}

4.2 接收数据

通过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) {

        // 主循环

    }

}

5. UART通信应用实例

5.1 与PC通信

在实际应用中,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");

    }

}

5.2 与外部设备通信

除了与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秒的延时

    }

}

5.3 使用中断处理数据

在实际应用中,使用中断处理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) {

        // 主循环

    }

}

5.4 使用DMA进行数据传输

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) {

        // 主循环

    }

}

5.5 总结

通过上述示例,我们可以看到TIVA C系列单片机的UART模块在各种应用场景中都非常灵活和强大。无论是简单的字符发送和接收,还是复杂的中断和DMA处理,TIVA C系列单片机的UART模块都能提供高效的解决方案。在实际开发中,可以根据具体需求选择合适的配置方法,以实现最佳的通信效果。

你可能感兴趣的:(单片机开发,c语言,arm开发,开发语言,嵌入式硬件,单片机)