标准库STM32F1_USART2_DMA接收发送数据源码分享直接复制能用
STM32的DMA通道表:
现有一个小需求,使用STM32F1系列单片机做串口2的收发数据的功能,通过PC上的串口调试助手给单片机发一串数据,单片机收到数据后再给PC的串口调试助手发回去。
本次使用的是串口DMA方式接收数据,和DMA方式发送数据。
STM32使用USART2,对应单片机的PA1控制方向,PA2发送,PA3接收。
代码如下:
main.c
#include "stm32f10x.h"
#include <string.h>
#define LEN_DMA_RECV_BUF 256
u16 len_dma_recv;
u8 dma_recv_buf[LEN_DMA_RECV_BUF];
u8 usart2_cache[LEN_DMA_RECV_BUF];
u8 dma_send_buf[LEN_DMA_RECV_BUF];
void init_hardware_usart2_dma(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
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(USART2, &USART_InitStructure);
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)dma_recv_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = LEN_DMA_RECV_BUF;
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_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel6, ENABLE);
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)dma_send_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
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_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel7, DISABLE);
DMA_ClearFlag(DMA1_FLAG_GL7);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
USART_Cmd(USART2, ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
}
void func_usart2_dma_send_bytes(u8 *bytes, u8 bytes_len)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
DMA_Cmd(DMA1_Channel7, DISABLE);
memcpy(dma_send_buf, bytes, bytes_len);
DMA_SetCurrDataCounter(DMA1_Channel7, bytes_len);
DMA_Cmd(DMA1_Channel7, ENABLE);
while(DMA_GetCurrDataCounter(DMA1_Channel7));
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) != SET);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
int main()
{
init_hardware_usart2_dma(9600);
while(1)
{
if(USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)
{
USART_ReceiveData(USART2);
DMA_Cmd(DMA1_Channel6, DISABLE);
len_dma_recv = LEN_DMA_RECV_BUF - DMA_GetCurrDataCounter(DMA1_Channel6);
memcpy(usart2_cache, dma_recv_buf, len_dma_recv);
memset(dma_recv_buf, 0, len_dma_recv);
DMA_SetCurrDataCounter(DMA1_Channel6, LEN_DMA_RECV_BUF);
USART_ClearFlag(USART2, USART_FLAG_IDLE);
DMA_Cmd(DMA1_Channel6, ENABLE);
func_usart2_dma_send_bytes(usart2_cache, len_dma_recv);
}
}
}