IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> [STM32]DMA+UART串口接收不定长数据 -> 正文阅读

[嵌入式][STM32]DMA+UART串口接收不定长数据

之前写过不使用DMA的串口接收不定长数据:[stm32]UART串口利用空闲中断接收一帧不定长数据
这里记录一下采用DMA+UART串口方式接收不定长数据
同样使用CUBEMX配置好生成代码(省略)

1.使用串口空闲中断+串口DMA中断方式实现,只不过这里的HAL_UART_Receive_IT()变成DMA方式HAL_UART_Receive_DMA()

  __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
  HAL_UART_Receive_DMA(&huart2,USART2_RXBUF,USART2_RX_SIZE);

__HAL_UART_ENABLE_IT()使能了空闲中断,当接收到一帧数据后就会发生中断
HAL_UART_Receive_DMA()使用DMA的方式开始接收指定长度的数据,并且使能了DMA相关中断,主要是半传输和传输完成中断

2.中断处理
这个中断处理函数会在数据半传输完成数据全传输完成中断触发后进入,并调用相对应的半传和全传完成回调函数,这里不需要做其他处理,回调函数也不做处理

void DMA1_Stream6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */

  /* USER CODE END DMA1_Stream6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_tx);
  /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */

  /* USER CODE END DMA1_Stream6_IRQn 1 */
}

在串口中断处理函数中,判断空闲中断的到来后,调用自定义的回调函数APP_UART_DMARxIdleCpltCallback(),这里的中断函数在空闲中断触发后进入,不会因为每接收1个数据而进入一次,因为 HAL_UART_Receive_DMA()函数中没有开启UART_IT_RXNE数据寄存器非空中断,这是与HAL_UART_Receive_IT()不一样的。

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
   if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)!=RESET)
   {  
      APP_UART_DMARxIdleCpltCallback(&huart2,&hdma_usart2_rx,USART2_RXBUF);       
     __HAL_UART_CLEAR_IDLEFLAG(&huart2) ; 
   }
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

3.自定义的空闲中断回调函数

void APP_UART_DMARxIdleCpltCallback(UART_HandleTypeDef*huart,DMA_HandleTypeDef *hdma,uint8_t*buf)
{
   uint8_t len=0;
   if(huart->Instance==USART2)
  {
    HAL_UART_DMAStop(&huart2);//中止DMA
    len = huart2.RxXferSize - hdma_usart2_rx.Instance->NDTR;
    CDC_Transmit_FS(buf,len);
    HAL_UART_Receive_DMA(&huart2,buf,USART2_RX_SIZE);
  }
}

(重点)进入回调函数后,先停止串口DMA,然后计算接收到的数据长度len,其中
huart2.RxXferSize:为要接收的数据大小,在HAL_UART_Receive_DMA()中定义了
hdma_usart2_rx.Instance->NDTR:串口DMA剩余接收数据长度,这里不再使用huart2.RxXferCount,因为这个数没有在HAL_UART_Receive_DMA()中用到,一直为0

最后调用 HAL_UART_Receive_DMA()重新开始接收数据,下次接收的数据又会从buf[0]开始存放(CDC_Transmit_FS(buf,len)为USB回传数据,注释不用)

注意:要保证接收的每帧数据长度小于在HAL_UART_Receive_DMA()函数中定义的接收数据长度

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:45:28  更:2022-03-10 22:46:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:42:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码