DMA实验3-外设到内存搬运

发布时间:2023年12月20日
实验要求
?
使用 DMA 的方式将串口接收缓存寄存器的值搬运到内存中,同时闪烁 LED1
CubeMX 配置
DMA 配置:

?

串口中断配置

?

?代码实现

如何判断串口接收是否完成?如何知道串口收到数据的长度?
  • 使用串口空闲中断IDLE)!
  • 串口空闲时,触发空闲中断;
空闲中断标志位由硬件置 1 ,软件清零
利用串口空闲中断,可以用如下流程实现 DMA 控制的任意长数据接收:
1. 使能 IDLE 空闲中断;
2. 使能 DMA 接收中断;
3. 收到串口接收中断, DMA 不断传输数据到缓冲区;
4. 一帧数据接收完毕,串口暂时空闲,触发串口空闲中断;
5. 在中断服务函数中,清除中断标志位,关闭 DMA 传输(防止干扰);
6. 计算刚才收到了多少个字节的数据。
7. 处理缓冲区数据,开启 DMA 传输,开始下一帧接收。??
有三个文件需要修改
main.c
  1. rcvBuf:用于存储接收到数据的缓冲区数组。
  2. rcvLen:记录接收到的一帧数据的长度。
  3. __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE):启用UART1的IDLE(空闲)中断,用于检测接收完成。
  4. HAL_UART_Receive_DMA(&huart1, rcvBuf, 100):通过DMA方式使能UART1的接收中断,将接收到的数据存储到rcvBuf中,每次接收100个字节。
  5. while (1):一个无限循环,在循环体内通过定时器操作,每300毫秒切换GPIOB的引脚状态,用于示例,可以理解为一个简单的心跳或指示灯。while(1) 循环内的点灯操作主要是为了说明在数据通过DMA传输的同时,CPU仍然可以继续执行其他任务。点灯操作是一个简单的示例,用于演示在数据传输的间隙里,CPU可以执行其他任务而不会阻塞。在实际应用中,这个循环内可能包含更复杂的逻辑、任务或者状态管理。
main.h

?

stm32f1xx_it.c

?

  1. USART1_IRQHandler:UART1的中断服务函数。
  2. __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) == SET:检查IDLE标志位是否被置位,即检测是否接收完成。
  3. __HAL_UART_CLEAR_IDLEFLAG(&huart1):清除IDLE标志位。
  4. HAL_UART_DMAStop(&huart1):停止DMA传输,防止DMA传输干扰。
  5. __HAL_DMA_GET_COUNTER(&hdma_usart1_rx):获取DMA传输的计数器信息,即还有多少数据未被传输。
  6. rcvLen = BUF_SIZE - temp:计算接收到的数据长度。
  7. HAL_UART_Transmit_DMA(&huart1, rcvBuf, rcvLen):通过DMA发送接收到的数据。
  8. HAL_UART_Receive_DMA(&huart1, rcvBuf, BUF_SIZE):重新启动DMA接收,准备接收下一帧数据。

这段代码实现了当UART1接收到一帧完整的数据后,通过DMA将接收到的数据传输到缓冲区,并进行相应的处理。

文章来源:https://blog.csdn.net/qq_61391875/article/details/135106110
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。