STM32标准库串口DMA空闲中断接收

1.DMA配置(USART配置在USART中已实现,不再重复叙述)

需要使用标准库头文件“stm32f10x_dma.h”

    DMA_InitTypeDef Usart_DMA;//定义DMA结构体
	DMA_DeInit(DMA1_Channel5);//初始化DMA通道
	Usart_DMA.DMA_BufferSize = 256;//定义DMA缓存区大小
	Usart_DMA.DMA_DIR = DMA_DIR_PeripheralSRC;//定义DMA传输方向
	Usart_DMA.DMA_M2M = DMA_M2M_Disable;//定义DMA是否用于内存到内存传输
	Usart_DMA.DMA_MemoryBaseAddr = (uint32_t)usart1Recdata;//定义DMA内存指向地址
	Usart_DMA.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//定义DMA内存每一帧数据大小
	Usart_DMA.DMA_MemoryInc = DMA_MemoryInc_Enable;//定义DMA内存是否递增
	Usart_DMA.DMA_Mode = DMA_Mode_Normal;//定义DMA传输模式
	Usart_DMA.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);//定义DMA外设地址
	Usart_DMA.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//定义DMA外设每一帧数据大小
	Usart_DMA.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//定义DMA外设是否递增
	Usart_DMA.DMA_Priority = DMA_Priority_High;//定义DMA优先级
	DMA_Init( DMA1_Channel5,&Usart_DMA);//将DMA结构体载入到指定DMA通道
	USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);//使能DMA接收
	DMA_Cmd(DMA1_Channel5,ENABLE);//开启DMA通道

2.DMA空闲中断接收配置

void USART1_IRQHandler(void)
{
	uint8_t temp[256] = {0};
	if(USART_GetITStatus(USART1,USART_IT_IDLE) !=RESET){//检查空闲中断标志量
		DMA_Cmd(DMA1_Channel5,DISABLE);//关闭DMA通道,防止数据丢失
		memcpy(temp,usart1Recdata,256);
		USART_SendString(USART1,temp);
		USART_SendByte(USART1,'\n');
		memset(usart1Recdata,0,sizeof(usart1Recdata));
		memset(temp,0,sizeof(temp));
		USART_ClearITPendingBit(USART1,USART_IT_IDLE);//清除空闲中断标志量
		DMA_SetCurrDataCounter( DMA1_Channel5, 256 );//设置DMA计数器
		DMA_Cmd(DMA1_Channel5,ENABLE);//开启DMA通道
		USART_ReceiveData(USART1);//清除串口中断
	}
}
要使用F405标准库实现串口DMA接收,需要按照以下步骤进行操作: 1. 配置串口GPIO引脚,设置串口参数(波特率、数据位、停止位、校验位等)。 2. 配置DMA,设置DMA通道和流,以及DMA传输方向和传输数据长度。 3. 使能DMA串口接收中断,并设置中断优先级。 4. 在中断服务函数中处理DMA传输完成和串口接收中断,并将接收到的数据存储到缓冲区中。 以下是一个简单的代码示例,供参考: ```c #include "stm32f4xx_gpio.h" #include "stm32f4xx_usart.h" #include "stm32f4xx_dma.h" #include "misc.h" #define RX_BUFFER_SIZE 256 volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; volatile uint32_t rx_index = 0; void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); 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(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE); } void DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); DMA_DeInit(DMA1_Stream5); DMA_InitStructure.DMA_Channel = DMA_Channel_4; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rx_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 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_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream5, &DMA_InitStructure); USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); DMA_Cmd(DMA1_Stream5, ENABLE); } void NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void DMA1_Stream5_IRQHandler(void) { if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5) != RESET) { DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5); } } void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_RXNE); if (rx_index < RX_BUFFER_SIZE) { rx_buffer[rx_index++] = USART_ReceiveData(USART2); } else { rx_index = 0; } } } int main(void) { USART_Config(); DMA_Config(); NVIC_Config(); while (1) { // Do something } } ``` 在上述代码中,串口使用的是USART2,DMA使用的是DMA1的第5个流。接收到的数据存储在rx_buffer数组中,rx_index变量表示当前存储的数据位置。DMA传输完成和串口接收中断分别在DMA1_Stream5_IRQHandler和USART2_IRQHandler中处理。需要注意的是,当接收到的数据长度超过了缓冲区长度时,需要将rx_index变量重置为0,以便下一次接收
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值