【STM32のHAL库开发】用DMA中断来接收串口数据

您所在的位置:网站首页 hal库开发流程 【STM32のHAL库开发】用DMA中断来接收串口数据

【STM32のHAL库开发】用DMA中断来接收串口数据

2023-11-27 13:03| 来源: 网络整理| 查看: 265

需求:

只有一个串口USART1,与以往用DMA+IDLE中断接收数据不同,这个串口在不停地发送数据(25bytes * 100Hz),因此IDLE中断不仅仅由接收事件产生,也在不停地由发送事件产生;此外还有一些其它的问题。正好从没用过DMA接收中断函数,遂决定尝试通过DMA传输完成中断(DMA_IT_TC)中接收数据,结果意外地好使。

CubeMX配置:

用的单片机是F070F6P6,一个很便宜很好焊的TSSOP20单片机;HAL库是通用的,串口DMA配置如下:在这里插入图片描述

main函数初始化

在程序初始化时开启DMA接受(用usart1,接收到uint8_t RX_BUFF[]数组中,接收数据包长度固定为64);开启DMA接收完成中断;关闭DMA发送完成中断:

HAL_UART_Receive_DMA(&huart1, RX_BUFF, 64); __HAL_DMA_ENABLE_IT(&hdma_usart1_rx, DMA_IT_TC); __HAL_DMA_DISABLE_IT(&hdma_usart1_tx, DMA_IT_TC); DMA中断函数

串口1接收挂在DMA1通道3上。以下函数逐行注释:

/** * @brief This function handles DMA1 channel 2 and 3 interrupts. */ void DMA1_Channel2_3_IRQHandler(void) { int data; /* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */ if(__HAL_DMA_GET_FLAG(&hdma_usart1_rx, DMA_FLAG_TC3)){ //清串口状态寄存器 data = USART1->ISR; data = USART1->RDR; if(RX_BUFF[0]==0xd1&&RX_BUFF[63]==0xd1){ //帧校验通过 //我在TIM16定时器中断中发送S.BUS数据,这里先停掉定时器 TIM16->CR1 &= ~0x01; //等待DMA发送完成 while(__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2)){} __HAL_DMA_CLEAR_FLAG(&hdma_usart1_tx, DMA_FLAG_TC2); //停掉DMA。只有停掉DMA才能重新启动下一次接收。 HAL_UART_DMAStop(&huart1); //此处处理接收到的数据 //使用普通方式发送一些数据作为应答 HAL_UART_Transmit(&huart1, (uint8_t *)(&RXer), 64, 99); //发送完成了,重启定时器 TIM16->CR1 |= 0x01; } //清空接收缓存 memset(RX_BUFF, 0, DMA_SIZE); //清中断 __HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx, DMA_FLAG_TC3); //重启一次接收 HAL_UART_Receive_DMA(&huart1, RX_BUFF, 64); } /* USER CODE END DMA1_Channel2_3_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_usart1_tx); HAL_DMA_IRQHandler(&hdma_usart1_rx); /* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */ /* USER CODE END DMA1_Channel2_3_IRQn 1 */ }

记得清中断并重启发送。

XCOM测试结果:

乱码是串口一直在发的16进制数据,文本 report cfg file 209.\r\n 则表明它每次发送都正常进了中断;再次进也没有问题。 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3