【STM32Cube笔记】10-异步串口收发USART

【STM32Cube笔记】系列文章目录

1-基于STM32的VSCode入门级教程前言
2-STM32Cube安装教程
3-STM32CubeIDE汉化
4-STM32Cube配置时钟设置
5-跑马灯引脚配置
6-Cortex-M7内核基本配置
7-新建用于储存代码的文件夹以及c/h文件
8-STM32CubeIDE点亮跑马灯
9-STLink调试
10-异步串口收发USART
11-中断控制器NVIC
12-配置外部中断
13-使用定时器产生PWM输出
14-使用定时器捕获上升/下降沿
15-数模转换AD/DA
16-STM32Cube个性化定制


6.1 新建USART工程

6.1.1 新建工程文件
在桌面新建文件夹,命名为“USART_Project”(根据实际需求选择文件夹存放路径和命名,其中路径不能包含中文),用于存放串口实验的工作空间。打开STM32CubeIDE软件,点击“Browse…”按钮,选择 “USART_Project”文件夹路径作为工作空间存放路径,然后点击“Launch”按钮,启动运行STM32CubeIDE。
【STM32Cube笔记】10-异步串口收发USART_第1张图片

点击“Start New STM32 project”按钮。
【STM32Cube笔记】10-异步串口收发USART_第2张图片

在搜索栏中输入需要配置的STM32芯片名称进行搜索,例如本文使用的芯片就输入“STM32H743II”,并单击选择对应封装“ LQFP176”,即可进入下一步。
【STM32Cube笔记】10-异步串口收发USART_第3张图片

在进入芯片详细页面后,可以点击“Block Diagram”或者“Datasheet”对芯片进行概览。在确认芯片信息与手头的芯片一致后,点击Next下一步开始配置芯片。
【STM32Cube笔记】10-异步串口收发USART_第4张图片

输入工程名,其余选型默认,点击“Finish”按钮。操作该步骤前需要保证网络正常,因为STM32CubeIDE需要下载对应芯片的数据包,也可以到STM官网上下载可离线安装的数据包。
【STM32Cube笔记】10-异步串口收发USART_第5张图片

点击“Yes”按钮。

在这里插入图片描述

点击“Project Manager->Code Generator”,将“Generated files”第1和第2选项勾选,其余默认。
【STM32Cube笔记】10-异步串口收发USART_第6张图片

6.1.2 配置芯片晶振
点击“Pinout & Configuration->System Core->RCC”,在“RCC Mode”中将“High Speed Clock(HSC)”设置为“Crystal/Ceramic Resonator”,其余保持默认。
【STM32Cube笔记】10-异步串口收发USART_第7张图片

第一个选项High Speed Clock即为HSE(高速时钟源),因此选择Crystal/Ceramic Resonator(使用晶振/外部陶瓷振荡器)来使用外部晶振。其余选项无特殊需求不用打开。
点击“Clock Configuration”,在“Input Frequency”输入“25”,在“PLL Source Mux”选择“HSE”作为时钟输入,在“System Clock Mux”选择“PLLCLK”作为时钟输入,在“SPI1,2,3 Clock Mux”输入“480”,然后按回车键,其他暂不设置,保持默认。
【STM32Cube笔记】10-异步串口收发USART_第8张图片

6.1.3 配置芯片内核
点击左边菜单栏“System Core”的“CORTEX_M7”进入M7的配置页面。
【STM32Cube笔记】10-异步串口收发USART_第9张图片

CPU ICache:使能I-Cache,用来缓存指令,选择打开。
CPU DCache:使能D-Cache,用来缓存数据,选择打开,其他选项不变。
点击左侧“Trace and Debug”,进入“DEBUG”页面,用自己所用的调试方式,选的是“Serial Wire”。也就是ST-Link常用的SWD模式,下面的选项是外部触发调试,暂且不开。
【STM32Cube笔记】10-异步串口收发USART_第10张图片

6.2 配置串口引脚
接下来我们对串口进行配置,首先在引脚定义中我们需要打开“Connectivity”中的“USART1”来打开串口1的配置菜单。
【STM32Cube笔记】10-异步串口收发USART_第11张图片

在“Mode”一栏中,将“Mode”改为“Asychoronous”异步模式,其他选项不用改动。
可以看到下方会出现串口的详细配置目录,这边选择不改动,使用默认的:
115200HZ波特率,8字符长度,奇偶位None,停止位为1.
【STM32Cube笔记】10-异步串口收发USART_第12张图片

接着点击“NVIC Setting”对串口中断进行配置,打开USART1的中断开关。
【STM32Cube笔记】10-异步串口收发USART_第13张图片

并在“NVIC”总中断控制界面将串口中断的优先度设为“3,3”。
【STM32Cube笔记】10-异步串口收发USART_第14张图片

使用正点原子阿波罗STM32H7开发板的请注意,将串口1更改至PA9和PA10方便通过USB Mini线调用串口。在右下角搜索“PA9”,找到黑色闪烁的PA9引脚,左键点击设置为“USART_RX”。同理将“PA10”设置为“USART_TX”。
【STM32Cube笔记】10-异步串口收发USART_第15张图片

接着重新回到“USART”设置中点击“GPIO Settings”,确认串口1所占用的引脚定义。
【STM32Cube笔记】10-异步串口收发USART_第16张图片

可以看到系统已经自动配置了“PB9”和“PB10”分别为RX和TX作为串口使用了,可以在下方的GPIO配置中更改串口引脚的高低速等配置,这边不做改动。
接着我们点击保存来生成代码至工程文件。
【STM32Cube笔记】10-异步串口收发USART_第17张图片

6.3 配置串口程序
接下来我们对程序进行设置。在左边资源管理器中,右键点击工程文件新建一个资源文件夹“HARDWAVE”来存放我们自己的.c代码。
【STM32Cube笔记】10-异步串口收发USART_第18张图片

【STM32Cube笔记】10-异步串口收发USART_第19张图片

同时在“HARDWAVE”资源文件夹下创建“Inc”和“Src”的文件夹 ,分别来存放我们自己编写的c和h文件。再在Inc和Src文件夹中右键新建.c/.h文件。h文件 建在“Inc”中,c文件 建在“Src”中,方便后续对其进行调用。
注意给文件备注.c/.h备注后缀,否则生成的文件将不带有c文件属性。
在Inc和Snc文件夹分别新建名为“USART1.h”和“USART1.c”的文件。
【STM32Cube笔记】10-异步串口收发USART_第20张图片

单单建好文件夹和文件还不能让工程文件识别到你的代码,我们还需在工程文件属性下对文件夹路径进行配置。右键工程文件点击最下方打开工程属性。接着按顺序点开“Paths and Symbols”的路径设置,“ADD”c工程文件启动的头文件。
【STM32Cube笔记】10-异步串口收发USART_第21张图片
【STM32Cube笔记】10-异步串口收发USART_第22张图片

在弹出的新建路径对话框中,点击“file system”添加本地路径。
【STM32Cube笔记】10-异步串口收发USART_第23张图片

选择我们新添加的文件夹“HARDWAVE”中存放h文件的“Inc”文件夹。
【STM32Cube笔记】10-异步串口收发USART_第24张图片

选择“apply”并退出, c和h文件夹路径就建好了,可以在main中调用了。

6.4 更改串口代码
6.4.1 串口函数一览
STM32比较常用的就是用HAL库中集成函数直接实现一些基本操作。HAL库的函数定义可在“Core”-“Src”-“system_stm32h7xx.c”中找到。以下为HAL库中串口函数:

//发送数据
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size, uint32_t Timeout);
//接收数据
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size, uint32_t Timeout);
//发送中断
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
//接收中断
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData
, uint16_t Size);
//使用DMA发送
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
//使用DMA接收
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *
pData, uint16_t Size);
//DMA暂停
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
//DMA恢复
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
//DMA停止
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);

接着我们打开软件自动生成的“usart.c”文件确认串口配置。
【STM32Cube笔记】10-异步串口收发USART_第25张图片

6.4.2 串口输出Printf函数
在串口调试中,直接用printf输出char格式是非常方便的,点开主函数“main.c”文件,在开头调用,并在“USER CODE”中添加printf的重定义代码。
注意在main文件中操作时要将代码放在“USER CODE”中。
【STM32Cube笔记】10-异步串口收发USART_第26张图片

【STM32Cube笔记】10-异步串口收发USART_第27张图片

// 重定向printf start
//_write函數在syscalls.c中, 使用__weak定义以可以直接在其他文件中定義_write函數
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
	 if(HAL_UART_Transmit(&huart1,ptr,len,0xffff) != HAL_OK)
	 {
		 Error_Handler();
	 }
}
// 重定向printf end

HAL_UART_Transmit的作用就是把printf的内容以char形式输出至串口1,具体的使用后面会讲。
另附上目前主流的信息printf格式:
//例: [info] main.c : init ok!
//例: [debug] adc.c : adc_getvalue -> 3.3v

6.4.3 串口输出
之前我们在系统生成的“usart.c”中确认了串口1的结构体名称为“huart1”,接下来就可以准备对其进行调用。
首先打开“USART1.h”,对“main.h”函数以及系统生成的“usart.h”进行调用,并声明变量和函数名。
【STM32Cube笔记】10-异步串口收发USART_第28张图片

/* Includes ----------------------------------------------------*/
#include "main.h"
#include "usart.h"						//调用系统生成的串口函数以防出错

void USART1_Test_Init(void);			//定义串口中断初始化函数
void USART1_Test(void);					//定义串口主函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle);
										//定义串口中断回调函数

接着我们需要打开系统预设的“stm32h7xx_hal_uart.c”确认串口中断回调函数是怎么运行的,右键点击“HAL_UART_RxCpltCallback”跳转到其定义。选择第一个位置在“stm32h7xx_hal_Drive”文件夹下的定义并确认。
【STM32Cube笔记】10-异步串口收发USART_第29张图片

【STM32Cube笔记】10-异步串口收发USART_第30张图片

可以看到,该串口中断函数只需要开启中断后,在被需要时,就会跳转到这个中断函数中执行其中的命令。
【STM32Cube笔记】10-异步串口收发USART_第31张图片

我们回到“USART1.c”中准备对其进行初始化,首先我们需要调用“USART1.h”,并新建一些变量来储存串口收到的数据。
【STM32Cube笔记】10-异步串口收发USART_第32张图片

接下来我们需要编写串口中断的初始化命令,使中断能在main的主循环开始前被调用。
【STM32Cube笔记】10-异步串口收发USART_第33张图片

接着我们需要编写串口命令的主函数,使其在main的主循环中等待中断函数回调数据给它。注意这边的小黄色感叹号warning是printf重定义的问题,不用去管。
【STM32Cube笔记】10-异步串口收发USART_第34张图片

最后我们需要在串口中断回调函数中将串口接收的值幅给串口输出的缓冲数组。
HAL_UART_Transmit(串口名,输出内容,长度,超时时间)即为标准的串口输出函数。
HAL_UART_Receive_IT(串口名,接收内容,长度,超时时间)即为标准的串口接收函数。
在这里插入图片描述

接下来返回到main函数中,先在/USER CODE BEGIN2/中添加中断开启函数“USART1_Test_Init”,再在/USER CODE BEGIN2/中添加“USART1_Test”调用串口主函数。

【STM32Cube笔记】10-异步串口收发USART_第35张图片

/* Includes ------------------------------------------*/
#include "USART1.h"
/** Configure pins
     PB10   ------> USART1_TX
     PB9   ------> USART1_RX
*/
//变量定义
uint8_t aRxBuffer[1];//串口数据储存数组
uint8_t Usart1_flag=0;//串口中断标志位
void USART1_Test_Init(){
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
    //HAL库中接收中断函数,内部开启了中断,并将数据存储在aRxBuffer,
    //现在在aRxBuffer就缓存一个Byte,该函数只有接收完才会调用回调函数
	HAL_Delay(50);
	printf("[info]main.c:Connect Sucess!\r\n");
    }
void USART1_Test(){
	if(Usart1_flag==1){
	printf("\r\n");
	printf("[info]USART.c:Resend Your Message!\r\n");		Usart1_flag=0;
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 1,0xFFFF);
    HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1);
    Usart1_flag=1;
}

6.4.4 烧录程序
在确认程序一致之后,我们需要将程序编译并烧录至单片机中。在确认ST-Link连接至电脑和单片机后,点击调试按钮。

【STM32Cube笔记】10-异步串口收发USART_第36张图片

第一次运行时会弹出DEBUG配置确认设置,无需改动点击“运行”即可。
【STM32Cube笔记】10-异步串口收发USART_第37张图片

在等待Download完成后,我们需要连接串口USB来对串口进行调试
在这里插入图片描述

推荐使用两根USB MINI对单片机开发板串口进行调试,如果没有两根线,只有单根USB Mini线请按以下流程操作,否则开发板串口会丢失:
1.确认USB MINI连接ST-Link并连接至开发板,点击烧录按钮,完成烧录操作。
在这里插入图片描述

2.在保持USB MINI连接在ST-Link下载器的情况下,手动对单片机进行复位。
【STM32Cube笔记】10-异步串口收发USART_第38张图片

3.在保持开发板通电的情况下,将USB MINI线直接插入角落的USB口(此时复位会丢失串口)。
【STM32Cube笔记】10-异步串口收发USART_第39张图片

4.打开串口软件,连接至串口。
【STM32Cube笔记】10-异步串口收发USART_第40张图片

	5.输入数据并点击发送,即可在接收区域内得到数据

【STM32Cube笔记】10-异步串口收发USART_第41张图片

6.4.5 串口DMA配置
DMA,全称Direct Memory Access,即直接存储器访问。
DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。
我们知道CPU有转移数据、计算、控制程序转移等很多功能,系统运作的核心就是CPU,
CPU无时不刻的在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?
因此转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B 不经过CPU的处理,无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
在这里插入图片描述

那么该如何配置DMA呢,我们需要重新回到USART1的引脚定义去开启DMA设置:
【STM32Cube笔记】10-异步串口收发USART_第42张图片

点击“ADD”添加TX以及RX的引脚设置。
【STM32Cube笔记】10-异步串口收发USART_第43张图片

Mode有两种模式,一种是普通模式,使用一次发送语句就发一次,另一种是循环模式,使用一次发送会一直发送。这里发送我选择普通模式,接收选择循环模式。
【STM32Cube笔记】10-异步串口收发USART_第44张图片

【STM32Cube笔记】10-异步串口收发USART_第45张图片

接着点击保存并生成代码。
【STM32Cube笔记】10-异步串口收发USART_第46张图片

接着,只需要在“USART1.c”文件中将“HAL_UART_Receive_IT”改为
“HAL_UART_Receive_DMA”即可调用串口接收的DMA模式了。
【STM32Cube笔记】10-异步串口收发USART_第47张图片

可以看到,串口收发还是运作正常,只不过开启了DMA模式,节省了内存空间。
【STM32Cube笔记】10-异步串口收发USART_第48张图片

你可能感兴趣的:(STM32入门级使用心得,单片机,stm32,嵌入式硬件)