stm32dma串口数据收发
时间: 2023-08-28 14:06:39 浏览: 155
在STM32上使用DMA(直接内存访问)来实现串口数据的收发可以大幅度提高数据传输效率,减少CPU的负担。以下是一个基本的示例:
```c
#include "stm32f10x.h"
#define USART_RX_BUFFER_SIZE 256
volatile uint8_t usart_rx_buffer[USART_RX_BUFFER_SIZE];
volatile uint16_t usart_rx_write_index = 0;
volatile uint16_t usart_rx_read_index = 0;
void usart_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 配置USART1的GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
// 配置DMA
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)usart_rx_buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = USART_RX_BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, ENABLE);
// 配置USART1的DMA接收
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
}
void usart_rx_handler(void)
{
uint16_t rx_write_index = USART_RX_BUFFER_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5);
while (rx_write_index != usart_rx_write_index) {
uint8_t data = usart_rx_buffer[usart_rx_read_index];
usart_rx_read_index = (usart_rx_read_index + 1) % USART_RX_BUFFER_SIZE;
// 处理接收到的数据
// ...
if (usart_rx_read_index == usart_rx_write_index) {
break;
}
}
}
int main(void)
{
usart_init();
while (1) {
usart_rx_handler();
}
}
```
在上述代码中,我们使用了DMA1通道5来实现USART1的接收,使用了循环模式,这意味着当DMA传输完成时,它将从USART1的数据寄存器中读取数据,并将其存储到usart_rx_buffer中。同时,我们使用了一个循环缓冲区来存储接收到的数据,然后在usart_rx_handler中处理接收到的数据。需要注意的是,在处理数据时,我们只能处理已经接收到的数据,而不能处理正在接收的数据。
阅读全文