要在STM32F411微控制器上使用标准库开启串口1的DMA接收完成中断,并在DMA空闲中断程序中处理数据,可以按照以下步骤进行操作:
首先,确保你已经正确配置了串口1(USART1)和相应的DMA通道。
在代码中包含相应的头文件:
#include "stm32f4xx.h"
初始化串口1的接收功能和DMA:
void UART_DMA_Init(void) { // 使能串口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitTypeDef USART_InitStructure; // 配置串口参数 USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 初始化串口 USART_Init(USART1, &USART_InitStructure); // 使能串口接收中断 USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 使能DMA时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitTypeDef DMA_InitStructure; // 配置DMA通道参数 DMA_DeInit(DMA2_Stream5); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_4; // 使用DMA2,通道4与UART1 RX关联 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; // 外设地址为串口数据寄存器地址 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)yourBuffer; // 接收缓冲区地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // 从外设到内存 DMA_InitStructure.DMA_BufferSize = yourBufferSize; // 缓冲区大小 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通道 DMA_Init(DMA2_Stream5, &DMA_InitStructure); // 开启DMA传输完成中断,也可以选择禁用,根据具体需求而定。 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // 使能DMA传输完成中断 DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE); // 使能DMA通道 DMA_Cmd(DMA2_Stream5, ENABLE); // 使能串口 USART_Cmd(USART1, ENABLE); }
实现串口1的空闲中断处理函数:
void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { // 清除空闲中断标志位 volatile uint32_t tmp = USART1->SR; tmp = USART1->DR; (void)tmp; // 禁止DMA通道,避免冲突 DMA_Cmd(DMA2_Stream5, DISABLE); // 获取接收到的数据数量 uint32_t dataLength = yourBufferSize - DMA_GetCurrDataCounter(DMA2_Stream5); // 添加你的处理代码,例如打印接收到的数据等。 for (uint32_t i = 0; i < dataLength; ++i) { printf("%c", yourBuffer[i]); } // 处理完后重新配置DMA相关寄存器 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)yourBuffer; // 接收缓冲区地址 DMA_InitStructure.DMA_BufferSize = yourBufferSize; // 缓冲区大小 DMA_Init(DMA2_Stream5, &DMA_InitStructure); // 清除DMA传输完成中断标志位 DMA_ClearITPendingBit(DMA2_Stream5, DMA_IT_TC); // 使能DMA通道 DMA_Cmd(DMA2_Stream5, ENABLE); } }
这样就可以通过DMA和串口1实现接收完成中断,并在DMA空闲中断处理函数里进行数据处理了。当一帧数据接收完毕后,会触发串口的空闲中断,然后在该中断处理函数里可以对接收到的数据进行相应的操作。请根据你的具体需求进行相应的配置和处理。
内容由零声教学AI助手提供,问题来源于学员提问