嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > 基于stm32使用usart发送实现HAL库DMA方式

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

基于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的的实时性,同时我这里使用逻辑分析仪简单的抓取了发送的数据,可以观察到每发送一个数据都附带一个时钟,同步模式就是就是带有时钟,异步发送模式不带时钟,逻辑分析仪也正确解析出了我们发送的数据,本次实验验证成功。