stm32 uart dma 同时发送接收程序
时间: 2023-08-06 11:08:29 浏览: 104
stm32用dma和usart发送数据
以下是一个简单的示例程序,展示了如何使用DMA同时实现STM32的UART发送和接收:
```c
#include "stm32f4xx.h"
#define UART_BUFFER_SIZE 32
uint8_t tx_buffer[UART_BUFFER_SIZE];
uint8_t rx_buffer[UART_BUFFER_SIZE];
void uart_init(void)
{
GPIO_InitTypeDef gpio_init;
USART_InitTypeDef usart_init;
DMA_InitTypeDef dma_init;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
gpio_init.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
gpio_init.GPIO_Mode = GPIO_Mode_AF;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_OType = GPIO_OType_PP;
gpio_init.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
usart_init.USART_BaudRate = 115200;
usart_init.USART_WordLength = USART_WordLength_8b;
usart_init.USART_StopBits = USART_StopBits_1;
usart_init.USART_Parity = USART_Parity_No;
usart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usart_init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &usart_init);
dma_init.DMA_Channel = DMA_Channel_4;
dma_init.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
dma_init.DMA_Memory0BaseAddr = (uint32_t)tx_buffer;
dma_init.DMA_DIR = DMA_DIR_MemoryToPeripheral;
dma_init.DMA_BufferSize = UART_BUFFER_SIZE;
dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_init.DMA_Mode = DMA_Mode_Normal;
dma_init.DMA_Priority = DMA_Priority_Medium;
dma_init.DMA_FIFOMode = DMA_FIFOMode_Disable;
dma_init.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
dma_init.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma_init.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6, &dma_init);
dma_init.DMA_Channel = DMA_Channel_4;
dma_init.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
dma_init.DMA_Memory0BaseAddr = (uint32_t)rx_buffer;
dma_init.DMA_DIR = DMA_DIR_PeripheralToMemory;
dma_init.DMA_BufferSize = UART_BUFFER_SIZE;
dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_init.DMA_Mode = DMA_Mode_Normal;
dma_init.DMA_Priority = DMA_Priority_Medium;
dma_init.DMA_FIFOMode = DMA_FIFOMode_Disable;
dma_init.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
dma_init.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma_init.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream5, &dma_init);
USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Stream6, DISABLE);
DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Stream5, DISABLE);
DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void uart_send(uint8_t *buffer, uint16_t size)
{
while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);
DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_TCIF6);
memcpy(tx_buffer, buffer, size);
DMA_SetCurrDataCounter(DMA1_Stream6, size);
DMA_Cmd(DMA1_Stream6, ENABLE);
}
void uart_receive(uint8_t *buffer, uint16_t size)
{
while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);
DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5);
DMA_SetCurrDataCounter(DMA1_Stream5, size);
DMA_Cmd(DMA1_Stream5, ENABLE);
while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);
memcpy(buffer, rx_buffer, size);
}
int main(void)
{
uint8_t buffer[UART_BUFFER_SIZE];
uart_init();
while (1)
{
// 从UART接收数据
uart_receive(buffer, UART_BUFFER_SIZE);
// 处理接收到的数据
// 发送数据到UART
uart_send(buffer, UART_BUFFER_SIZE);
}
}
```
该程序使用了DMA来传输数据,因此发送和接收过程都是异步的。在主函数中,我们可以反复调用“uart_receive”和“uart_send”函数,以便在UART上进行无缝通信。请注意,这只是一个简单的示例程序,您可能需要进行一些修改才能满足您的特定需求。
阅读全文