关于STM32H7的串口DMA的使用

关于STM32H7的串口DMA的使用:

最近在使用H743做项目,想用RT-THREAD来做,但是目前(2022/5/10)之前,RT对于H7系列的支持,特别是DMA的使用可以说完全没有适配,所以现在先裸机开发各个外设的DMA,到时候再做移植


前言

h743用的人属实不多,相关教程少,特别是一些教程的例子,都难以直接上手,于是决定自己写一篇,关于如何快速开发,用使用h7系列的串口DMA

本篇教程的目的在于如何最快的上手进行开发,并不会深入底层进行分析,所提供的方法并非性能最好的

一、环境准备

keil5.30及以上版本、cubemx(其中h7系列的支持包为1.9.1),

二、cubemx配置

时钟配置等请自行配置,实在做不到就照抄正点原子时钟初始化部分
在这里插入图片描述打开串口设备1,所有配置默认
在这里插入图片描述打开串口1的dma通道,打开fifo,其他设置全部默认
在这里插入图片描述注意记得打开DMA以及串口1中断
串口1中断cubemx默认不打开,一定要手动打开
在这里插入图片描述到NVIC确认中断打开情况
在这里插入图片描述点开code generation把这几个中断初始化都勾上,免得后面自己写

三、修改代码

HAL库开发虽然很快,但是如果不熟悉的话,有好多东西很难去找到。
有好多博主的教程,对于h7的dma与cache的处理,将缓存数组存在axi ram里,这毋庸置疑是高性能的写法,但是对于我们快速开发来讲,串口的速度根本用不着如此大动干戈,优化的再好波特率也只有那么多,实在不必将精力用在这里

更新一下:之前看了st官方的NUCLEO-H743ZI例程,其中的Projects\NUCLEO-H743ZI\Examples\UART\UART_TwoBoards_ComDMA下演示了两块32通过串口DMA通信,加入了MPU保护,再调用SCB_InvalidateDCache_by_Addr()函数,简单有效,下面代码重新更新一下

定义MPU

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */
  HAL_MPU_Disable();

  /* Configure the MPU as Strongly ordered for not defined regions */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x00;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0x87;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

实际上是对所有地址进行MPU保护

首先是定义接收和发送缓存

uint8_t uattbuff[20]={"hello\n"};
uint8_t uattbuffdma[20]={"hello from DMA\n"};
uint8_t uatrbuffdma[128]={0};

定义了三个数组,分别用于普通模式的串口传输,DMA传输,以及DMA接收

在开始处

int main(void)
{
  /* USER CODE BEGIN 1 */
		MPU_Config();
  /* USER CODE END 1 */

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();

  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();
  /* MCU Configuration--------------------------------------------------------*/

加入MPU_Config配置

然后在主循环处

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	HAL_UART_Receive_DMA(&huart1,uatrbuffdma,5);
  while (1)
  {
		HAL_Delay(2000);
		HAL_UART_Transmit(&huart1,uattbuff,strlen(uattbuff)0xff);
		HAL_Delay(1);
		HAL_UART_Transmit_DMA(&huart1,uattbuffdma,strlen(uattbuffdma));
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
  }
  /* USER CODE END 3 */

循环发送
此时将程序烧录进32,已经可以看到输出了
在这里插入图片描述

接下来是接收中断函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		SCB_InvalidateDCache_by_Addr ((uint32_t *)uatrbuffdma, 128);
		HAL_UART_Transmit(&huart1,uattbuffdma,5);
		HAL_UART_Receive_DMA(&huart1,uatrbuffdma,5);
	}
}

重点在于SCB_InvalidateDCache();函数,原因就是内存一致性,此处不展开叙述,如果有需要的可自行搜索。
此处用到SCB_InvalidateDCache_by_Addr()函数,稍微优化了一下
此时再次将代码下载到32里
在这里插入图片描述
可以看到串口DMA的收发操作都实现了

四、总结

可以看到HAL库+cubemx搭配的开发效率有多快,当然前提是对HAL的代码结构有基础的了解。

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: STM32H7系列微控制器具有DMA(Direct Memory Access)功能,可以通过DMA实现高效的串口通信。DMA超时中断是指当通过DMA进行串口数据传输时,如果在设定的超时时间内未能完成传输,则会触发DMA超时中断。 在STM32H7中,可以通过以下步骤来配置串口DMA超时中断: 1. 首先,要确保已经正确配置了串口DMA。通过使能对应的串口DMA时钟,并进行相应的GPIO配置。 2. 在DMA控制器寄存器中配置DMA的通道、传输方向、传输数据的大小等参数。可以使用HAL库提供的DMA初始化函数来进行配置。 3. 在串口寄存器中配置串口的工作模式、波特率和数据位数等参数。同样可以使用HAL库提供的串口初始化函数来进行配置。 4. 在DMA配置完成后,需要配置DMA的超时功能。可以通过设置DMA的超时周期和超时中断标志来实现。通过设置超时周期,可以确定DMA在指定时间内未完成数据传输时触发中断。同时,需要设置超时标志以启用超时中断功能。 5. 最后,启用DMA串口,开始数据传输。可以通过使能DMA串口传输完成中断来进行数据传输的管理。 在发生超时中断时,可以在中断服务函数中进行相应的处理操作,例如重启DMA传输、重新发送数据等。 总而言之,STM32H7串口DMA超时中断可以通过正确配置串口DMADMA超时功能来实现。在触发超时中断时,可以在中断服务函数中进行相应的处理操作,确保数据传输的稳定性和可靠性。 ### 回答2: STM32H7系列微控制器使用DMA(Direct Memory Access,直接内存访问)和串口来实现高效的数据传输。DMA超时中断是指在进行串口数据传输时,如果DMA传输超时(即传输时间超过预设的时间),则会触发超时中断,以便及时处理异常情况。 在STM32H7中,DMA超时中断可以通过以下步骤来实现:首先,需要设置串口的超时时间,通过设置USART_CR2寄存器的TO字段,将超时时间设置为一个适当的值。接下来,打开串口的超时中断使能位,通过设置USART_CR1寄存器的TOIE字段为1,使能超时中断。然后,通过STM32H7DMA控制器设置DMA的传输时间,以确保在设置超时时间后,如果DMA传输的时间超过了设定的超时时间,就会触发超时中断。 当DMA超时中断发生时,CPU会跳转到相应的中断处理函数进行处理。在中断处理函数中,我们可以根据具体的需求进行处理,例如关闭UART的DMA传输,重启传输等。同时,还可以通过读取USART_SR寄存器的TO字段来清除超时中断标志位。 总之,STM32H7系列微控制器提供了灵活的串口DMA超时中断功能,可以帮助我们实现高效可靠的数据传输,提高系统的稳定性和可靠性。在使用过程中,需要根据具体的应用需求进行合理的设置和处理。 ### 回答3: STM32H7系列的MCU支持串口DMA超时中断功能。串口DMA超时中断是一种特殊的DMA传输模式,用于在数据传输超时时触发中断。 在串口DMA超时中断模式下,通过设置串口的超时模式和超时值来配置。超时模式可以选择基于帧错误或空闲线路的超时,并且可以配置超时值来指定超时时间。 当数据传输超时时,串口DMA控制器会触发超时中断,并执行相应的中断服务程序。在中断服务程序中,可以采取适当的措施来处理超时情况,例如重新启动DMA传输或向主控制器报告超时错误等。 使用串口DMA超时中断功能可以大幅度提高串口通信的可靠性和稳定性。它可以帮助检测和处理数据传输的异常情况,例如数据丢失或传输错误,从而减少了数据传输的风险。 需要注意的是,在使用串口DMA超时中断功能时,需要正确配置串口的超时模式和超时值,以及相应的中断服务程序。此外,还需要确保其他相关的串口DMA和时钟设置也正确,并根据实际需求进行适当的调试和优化。 总之,STM32H7系列的MCU支持串口DMA超时中断功能,它是一种有效的机制来处理串口通信中的传输超时情况,提高串口通信的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值