基于stm32使用usart发送实现HAL库DMA方式


本文目标:基于HAL库的stm32实现usart的发送实验

按照本文的描述,应该可以跑通实验并举一反三。

先决条件:装有编译和集成的开发环境,比如:Keil uVision5、STM32CubeMX

使用外设:USART1、GPIO

缘起

这篇文章是在网上看博客时发现别人有一些有意思的验证,于是想在自己所处的平台也进行验证一下,顺便给一些初学者一些启发。

实验目的

基于stm32平台使用HAL库方式实现usart的同步模式发送实验,顺便测试一下使用DMA方式的发送方式会不会影响cpu的实时性。在本实验过程中,我们将涉及 STM32 的 GPIO 端口配置、USART1等。

关于DMA的描述

在这里插入图片描述

功能框图:

在这里插入图片描述

按照我自己的理解,就是大致是个cpu的助手,可以辅助帮助做cpu一些事情。

搭建工程

使用STM32CubeMX配置stm32的基本配置。基本的配置如下:开启swd调试,开启外部时钟。

在这里插入图片描述

在这里插入图片描述

  • 配置USART1,用于printf调试

在这里插入图片描述

  • 配置USART2的同步模式,用于本次实验的测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 时钟界面选项卡:

在这里插入图片描述

  • 工程选项卡:

在这里插入图片描述

在这里插入图片描述

点击右上角的的生成代码:

在这里插入图片描述

使用keil打开工程,编译工程,一切都是ok

在这里插入图片描述

编写代码实现需求

开始编写代码,首先要把串口的打印映射好,使用下面的代码片段可用正常使用printf打印

int fputc( int ch, FILE *f )
{
	USART_TypeDef* USARTx = USART1;
	while ((USARTx->SR & (1<<7)) == 0);
	USARTx->DR = ch;
	return ch;
}

接下来定义一个超大数组并进行赋予初始值

#define SEND_LENS 18*1024

// 定义一个超大的测试的数据
uint8_t test_send_data[SEND_LENS] = {0};

for (int i = 0; i < SEND_LENS; i++) 
{
	test_send_data[i] = 't'; // 给每个元素赋值为 't'
}

在main函数中简单进行测试一下

while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_USART_Transmit_DMA(&husart2, test_send_data, SEND_LENS);
    printf("每500ms打印一次\r\n");
    HAL_Delay(500);
}

这个HAL_USART_Transmit_DMA函数在相应的头文件进行寻找,我这里用的串口的同步模式,所以在stm32f1xx_hal_usart.h中寻找,用异步模式的话要在stm32f1xx_hal_uart.h中寻找相对应的api。同步就是多个时钟信号,异步就没有时钟信号。

在这里插入图片描述

main.c中的编写的代码片段

在这里插入图片描述

实验现象

在这里插入图片描述

在这里插入图片描述

总结:

可以看到在main函数中使用DMA发送一大串数据正常使用,不影响cpu的的实时性,同时我这里使用逻辑分析仪简单的抓取了发送的数据,可以观察到每发送一个数据都附带一个时钟,同步模式就是就是带有时钟,异步发送模式不带时钟,逻辑分析仪也正确解析出了我们发送的数据,本次实验验证成功。

本文中使用的测试工程

https://download.csdn.net/download/weixin_44317448/88191659

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐