stm32 串口中断接收 hal
时间: 2025-01-13 10:43:48 浏览: 35
STM32 HAL库实现串口中断接收
使用DMA和空闲中断处理不定长数据接收
对于STM32F0系列微控制器,在MDK 5.25环境下利用HAL库版本v1.10.0可实现高效的串口通信。通过配置DMA传输并启用UART IDLE线状态检测,能够可靠地捕获不固定长度的数据帧[^1]。
当接收到完整的字符序列后触发IDLE事件,此时CPU被唤醒执行回调函数UartIdleCallback()
来保存已到达的信息片段至缓冲区内存区域。这种方式特别适合于那些消息边界分明的应用场景,比如命令行接口或是协议包交换等场合。
// 初始化 UART 和 DMA 配置部分省略...
void MX_USART1_UART_Init(void){
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600; // 设置波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_IDLEDET_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK){
Error_Handler();
}
}
static void SystemClock_Config(void){ /* ... */ }
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 开启IDLE中断
while(1){}
}
void UartIdleCallback(UART_HandleTypeDef *huart){
uint32_t tmp;
if(huart->Instance==USART1){
HAL_UART_DMAStop(&huart1);
// 获取当前DMA读取位置到缓存指针的距离
tmp= __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
// 计算实际接收到的有效字节数量
RxLen = RXBUFFERSIZE-tmp;
// 处理接收到的数据...
ProcessReceivedData(RxBuff,RxLen);
// 准备下一次接收操作
HAL_UART_DMAResume(&huart1);
}
}
利用环形队列优化数据存储结构
为了提高程序运行效率以及防止溢出错误的发生,推荐采用循环缓冲区(即环形队列)的方式管理输入流中的每一个新到来的比特位或字节单元。每当有新的数据项加入时自动覆盖最早进入的那个元素;而在取出端则总是返回最先进入队列里的成员[^2]。
这种方法不仅简化了内存分配逻辑而且有助于减少因频繁申请释放动态空间所带来的开销问题。同时配合前面提到过的基于DMA加空闲中断机制还可以进一步增强系统的实时响应性能。
相关推荐


















