目录
一、概述
二、串口通信原理
三、串口调试
四、程序实现
(一)阻塞模式
(二)中断模式
五、总结
一、概述
本篇文章我们进入STM32串口收发功能的教学,主要讲解阻塞模式与中断模式两种收发模式,源码将在最后免费提供。
开发工具:STM32CubeMx、STM32开发板(型号不限)
二、串口通信原理
串口通信的本质,是发送者将信号调制之后通过传输介质被接收者接收并解析的过程。
![](https://img-blog.csdnimg.cn/a2fa4b2a454047cf95af69c21abb0431.png)
数据的发送,则是通过高低电平来实现的:
![](https://img-blog.csdnimg.cn/c6af1bb624e14f91a93e7df00deadafd.png)
串口都是往往是三根线实现的,即RX(接收)、TX(发送)、GND(地)。
而波特率(bit/s) 常用的有9600,38400,115200等,代表的是每秒传输的bit位数,比特率越高传输速率越快,出现错码的概率越大。
两个设备必须设置相同的比特率、校验方式、停止位等参数才能正常通信。
三、串口调试
这里的串口调试我们需要用到USB转TTL,使用线连接开发板的TX与RX,并安装好USB转TTL驱动,打开串口即可。
USB转TTL串口驱动
安装完驱动,我们连接好串口,打开串口调试助手,注意波特率等信息需要与程序设置的一致。
![](https://img-blog.csdnimg.cn/53765da2b21e4406b513b39d9bc0179d.png)
四、程序实现
首先打开STM32CubeMx选择对应开发板的芯片:
![](https://img-blog.csdnimg.cn/9812674a866947348e87d432863c05cc.png)
简单做一些基础的配置工作(请以实际开发板电路为准):
![](https://img-blog.csdnimg.cn/19c43fd690ce4d888dc0b9de4a08c32b.png)
![](https://img-blog.csdnimg.cn/d091d1560b724af28ee5d48241df9065.png)
随后我们按照下图配置USART,此处我Mode选择异步、波特率是9600,8位、无校验、停止位1位。
![](https://img-blog.csdnimg.cn/69dbc90fedf147d38efb1de2346ad4c6.png)
随后我们进入GPIO的USART菜单,查看USART端口是否正确,此处我们发现位PA9与PA10。
![](https://img-blog.csdnimg.cn/fee2925aecbc4ae780b26291f779f63c.png)
查看开发板电路图,核对引脚是否正确,发现电路图中引脚为PA9与PA10,引脚正确我们不需要做其他操作。
![](https://img-blog.csdnimg.cn/b8a63280cbb04f4d8d484dd7f5c7f479.png)
至此我们已经完成了工程配置,生成代码并打开:
![](https://img-blog.csdnimg.cn/c1bbd7b341b546febe4f98885bb89953.png)
![](https://img-blog.csdnimg.cn/3cb8b0c9f9cd4ba095460970741c7bc7.png)
(一)阻塞模式
这里我们写一个读取串口信息并发送回来的程序,在主函数中,代码如下:
此处我们使用HAL_UART_Transmit函数,参数分别为串口句柄、数据、数据长度、超时时间。
![](https://img-blog.csdnimg.cn/c0087245b1814f00b1cd729151ffb593.png)
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint8_t receive[10];
HAL_UART_Receive(&huart1,receive,0xFFFF);
HAL_UART_Transmit(&huart1,receive,sizeof(receive),0xFFFF);
}
/* USER CODE END 3 */
至此,编译并烧写程序以后,我们开始调试。
![](https://img-blog.csdnimg.cn/a31295adabeb4e4eb1d9c0665b06e24f.png)
可以发现,程序功能已经实现,我们还可以通过对printf与scanf的重定向来实现功能。
/* USER CODE BEGIN 0 */
#include <stdio.h>
int fputc(int c, FILE* stream)
{
uint8_t ch[]={c};
HAL_UART_Transmit(&huart1,ch,1,0xffff);
return c;
}
int fgetc(FILE * stream)
{
uint8_t ch[1];
HAL_UART_Receive(&huart1,ch,1,0xffff);
return ch[0];
}
/* USER CODE END 0 */
(二)中断模式
返回到STM32CubeMx,在NVIC选项卡中使能USART1的中断。
![](https://img-blog.csdnimg.cn/c2e84d1ed8ae4857958b51241cabfd08.png)
重新编译并生成代码,我们来是实现接收与发送的功能。
/* USER CODE BEGIN WHILE */
uint8_t receive[10];
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_UART_Receive_IT(&huart1,receive,10);//接收函数
HAL_UART_Transmit_IT(&huart1,receive,10);//发送函数
}
/* USER CODE END 3 */
本质上,代码是没有什么区别的,不过发送和接收的函数发生了改变,中断接收函数HAL_UART_Receive_IT在接收完毕之后会调用接收完成的中断处理函数,为了实现刚刚的功能,我们重写此函数并进行相关操作以实现功能。
声明receive为全局变量,在接收完成处理函数中调用发送函数,然后再次进入接收状态。同时在主程序需要调用一次接收函数,使其进入接收状态。
uint8_t receive[10];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit_IT(&huart1,receive,10);//发送函数
HAL_UART_Receive_IT(&huart1,receive,10);//接收函数
}
![](https://img-blog.csdnimg.cn/45ee6ef0d10e43ff8d6c9b9bbe1cc36a.png)
至此,串口中断程序完成。
五、总结
本篇的重点在于阻塞模式与中断模式两种模式的串口通信,需要熟悉并重写中断处理函数,培养编程思维,下次我们将继续介绍DMA相关知识。
源码:STM32串口通信源码-文章配套资源