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