STM32CubeMX之DMA辅助串口数据接收

1.DMA辅助串口数据接收

1.1 DMA简介

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。

两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

DMA控制器和Cortex™-M3核心共享系统数据总线,执行直接存储器数据传输。当CPU和DMA同时访问相同的目标(RAM或外设)时,DMA请求会暂停CPU访问系统总线达若干个周期,总线

仲裁器执行循环调度,以保证CPU至少可以得到一半的系统总线(存储器或外设)带宽。

1.2 DMA特性

● 12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道。

● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。

● 在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) 。

● 独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。

● 支持循环的缓冲器管理。

● 每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。

● 存储器和存储器间的传输。

● 外设和存储器、存储器和外设之间的传输。

● 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。

● 可编程的数据传输数目:最大为65535。

1.3 串口1接收与DMA1的通道接口

从外设(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、2、3])产生的7个请求,通过逻辑或输入到DMA1控制器,这意味着同时只能有一个请求有效。参见下图的DMA1请求映像。

外设的DMA请求,可以通过设置相应外设寄存器中的控制位,被独立地开启或关闭。

2.串口1接收使能DMA配置

2.1串口基本功能配置

串口1配置:全双工异步通信、波特率为115200、8个数据位、1个停止位、无校验位

打开STM32CbeMX软件,配置串口串口、开启串口中断

优先级分组设置:2位抢占优先级2位副优先级

2.2 串口基本功能配置

配置串口1接收DMA通道

3.代码配置

3.1 修改usart.c文件

1.开启空闲帧中断

c 复制代码
  huart1.Instance->CR1|=1<<4;//开启串口空闲帧中断

2.添加DMA处理代码

c 复制代码
    DMA1_Channel5->CPAR=(uint32_t )&USART1->DR;//外设地址
    DMA1_Channel5->CMAR=(uint32_t )usart1_rx_buff;//存储器地址
    DMA1_Channel5->CCR&=~(1<<0);//关闭通道传输
    DMA1_Channel5->CNDTR=1024;//设置传输数量
    DMA1_Channel5->CCR|=1<<0;//开启通道传输

3.2 修改stm32f1xx.it.c文件

1.DMA数据接收处理:

c 复制代码
extern DMA_HandleTypeDef hdma_usart1_rx;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
uint8_t usart1_rx_buff[1024];//串口1接收数据缓冲区
uint16_t usart1_cnt=0;//保存数组下班
uint8_t usart1_flag;//接收完成标志符
/*************************串口接收数据函数********************/
static void Usart1_Receive_Data(void)
{
	DMA1_Channel5->CCR&=~(1<<0);//关闭通道传输
	usart1_cnt=1024-DMA1_Channel5->CNDTR;//获取接收到是字符长度
	if(usart1_cnt>=1024)usart1_cnt=0;
	DMA1->IFCR|=1<<17;//清除标志位
	DMA1_Channel5->CNDTR=1024;//从新赋值
	DMA1_Channel5->CCR|=1<<0;//开启通道传输
	usart1_flag=1;
}
/* USER CODE END EV */

2.串口中断服务函数

c 复制代码
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  uint8_t c;
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
  {
    c=huart1.Instance->DR;
     c=c;
    Usart1_Receive_Data();
    //huart1.Instance->DR=c;
  }
  /* USER CODE END USART1_IRQn 1 */
}

4.运行示例

c 复制代码
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("初始化完成\r\n");
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
if(usart1_flag && usart1_cnt)
    {
      usart1_rx_buff[usart1_cnt]='\0';
      printf("usart1:%s,%d\r\n",usart1_rx_buff,usart1_cnt);
      //*20230223141731,15

      usart1_flag=0;
    }
  }
  /* USER CODE END 3 */
}

5.工程示例

相关推荐
Caramel_biscuit1 分钟前
STM32 CAN学习
stm32·嵌入式硬件·学习
最后一个bug6 分钟前
教你快速理解linux中的NUMA节点探测是干什么用的?
linux·c语言·开发语言·arm开发·嵌入式硬件
坏柠1 小时前
深入浅出SPI通信协议与STM32实战应用(W25Q128驱动)(理论部分)
stm32·单片机·嵌入式硬件
Invinciblenuonuo3 小时前
STM32八股【5】----- TIM定时器
stm32·单片机·嵌入式硬件
selenia88603 小时前
如何成功点亮LED灯并实现闪烁效果
单片机·嵌入式硬件
禾川兴 132424006884 小时前
国产芯片解析:龙讯HDMI Splitter系列:多屏共享高清
单片机·fpga开发·适配器模式
猫猫的小茶馆6 小时前
【PCB工艺】软件是如何控制硬件的发展过程
开发语言·stm32·单片机·嵌入式硬件·mcu·51单片机·pcb工艺
柒月玖.9 小时前
基于AT89C52单片机的轮胎压力监测系统
单片机·嵌入式硬件·mongodb
多多*10 小时前
Java设计模式 简单工厂模式 工厂方法模式 抽象工厂模式 模版工厂模式 模式对比
java·linux·运维·服务器·stm32·单片机·嵌入式硬件
Android洋芋10 小时前
C语言深度解析:从零到系统级开发的完整指南
c语言·开发语言·stm32·条件语句·循环语句·结构体与联合体·指针基础