零基础STM32入门教程--11-USART/UART 串行通迅

专栏:STM32F103入门教程

环境:Keil‑MDK + STM32F103 标准库3.5版本

一、串行通迅简介

USART 的全称是 Universal Synchronous/Asynchronous Receiver/Transmitter,中文译为通用同步/异步收发器。它是一种广泛用于微控制器(MCU)、微处理器和专用通信芯片中的硬件接口模块,专门负责设备之间的串行数据传输。

串行通信的基本特征是数据逐位顺序依次传输,一次传一个位(bit)。一个字节8个位,再加上起始,停止,校验后一个字节才能传输完成。发送方字节数据转换为串行比特流(一位一位地)发送出去;接收方接收数据时,又将接收到的串行比特流转换字节数据供 CPU 处理。

两大工作模式(USART 与 UART 的核心区别)

两大工作模式

USART 名称中的"Synchronous/Asynchronous"揭示了它最强大的特性------同时支持两种通信模式:

异步模式(UART 模式) :这是最常见的工作模式。发送端和接收端没有共享的时钟信号,双方依靠预先约定好的波特率(Baud Rate)以及起始位和停止位来同步数据。这种模式接线简单(通常只需 TX、RX 和 GND 三根线),应用极其广泛。

同步模式:发送端和接收端共享一条时钟信号线(CLK/SCLK)。数据在时钟信号的边沿进行严格同步。这种模式不需要起始位和停止位,数据传输速率更高且更可靠,但需要额外的时钟线,接线相对复杂。

主要技术特点

现代的 USART 模块通常具备高度灵活的配置能力,主要特点包括:

全双工操作:能够同时独立地进行数据的发送和接收。

可配置的帧格式:支持 5 到 9 位的数据位,以及 1 到 2 位的停止位。

硬件校验:由硬件自动支持奇偶校验位的发生与检验,减轻 CPU 负担。

高精度波特率发生器:独立生成通信所需的时钟频率,不占用系统的定时/计数器资源。

错误检测:硬件层面支持数据溢出、帧错误和校验错误的检测2。

典型应用场景

USART 是嵌入式系统中设备交互的桥梁,常见应用包括:

设备调试:作为嵌入式系统的控制台,将运行日志和变量状态通过串口打印到 PC 端。

模块通信:连接各类外部模块,如 GPS 模块、蓝牙模块、Wi-Fi 模块。

工业控制:结合 RS-232、RS-485 等物理层标准,用于 PLC 通信或传感器数据采集。

固件烧录:作为引导加载程序(Bootloader)的通道,用于给单片机下载和更新程序。

波特率 (Baud rate):

每秒传输的符号(信号变化)个数,UART 异步串口里,基本等价于每秒传输比特数 bit/s。单位:baud,常用:9600、115200。例:115200 = 每秒 115200 个比特。

UART 帧结构:起始位|数据位|停止位|校验位

UART 异步通信,没有时钟线,靠一帧的固定格式让接收方知道:数据什么时候来、什么时候结束。

标准格式:起始位 → 有效数据位 →(可选校验位)→ 停止位

1. 起始位 Start Bit
  • 总线空闲时:TX 线保持高电平 (逻辑 1)
  • 要发送数据时,先拉低电平,输出1 位的低电平(逻辑 0) ,这就是起始位
  • 作用:通知接收方:有数据来了,开始同步采样时钟
  • 接收端检测到电平从高→低的下降沿,就知道一帧开始,后续按照波特率的时间间隔采样后面电平。

关键点:空闲是高;起始位强制拉低。

2. 有效数据位 Data Bit

紧跟起始位之后,就是真正要传的数据。

  • 长度可选:5、6、7、8 位 ;嵌入式几乎全部用 8 位(正好 1 字节)。
  • 传输顺序:低位先行(LSB 先发送)

比如要发送 0x41(ASCII 'A',二进制 0100 0001),先发 bit0,最后发 bit7。

3. 校验位 Parity Bit(可选,可关闭)

紧跟数据位后面,用来做简单错误检测,不是纠错,只能发现出错

两种模式:

  1. 奇校验 ODD:数据位 + 校验位,整体 1 的总个数为奇数。
  2. 偶校验 EVEN:数据位 + 校验位,整体 1 的总个数为偶数。
  3. 无校验 NONE:不发送校验位,现在绝大多数设备用这个。

例子:数据 01000001,里面 1 的数量 = 2;

  • 偶校验:校验位填 0,总和依旧偶数;
  • 奇校验:校验位填 1,总和变成奇数。

缺点:只能检测部分错误;如果同时 2 位电平出错,校验检查不出来。现代嵌入式基本关闭校验,靠上层协议校验 CRC。

4. 停止位 Stop Bit

帧的结束标记,电平强制为高电平逻辑 1

可选长度:1 位、1.5 位、2 位

  • 绝大多数场景:1 停止位
  • 老设备、长距离抗干扰:用 2 停止位。

二、STM32F103 串行设置相关

2.1 USART_InitTypeDef USART 初始化结构体

c 复制代码
/** 
  * @brief  USART Init Structure definition  
  */ 
  
typedef struct
{
  uint32_t USART_BaudRate;            /*!< This member configures the USART communication baud rate.
                                           The baud rate is computed using the following formula:
                                            - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
                                            - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */

  uint16_t USART_WordLength;          /*!< Specifies the number of data bits transmitted or received in a frame.
                                           This parameter can be a value of @ref USART_Word_Length */

  uint16_t USART_StopBits;            /*!< Specifies the number of stop bits transmitted.
                                           This parameter can be a value of @ref USART_Stop_Bits */

  uint16_t USART_Parity;              /*!< Specifies the parity mode.
                                           This parameter can be a value of @ref USART_Parity
                                           @note When parity is enabled, the computed parity is inserted
                                                 at the MSB position of the transmitted data (9th bit when
                                                 the word length is set to 9 data bits; 8th bit when the
                                                 word length is set to 8 data bits). */
 
  uint16_t USART_Mode;                /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.
                                           This parameter can be a value of @ref USART_Mode */

  uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
                                           or disabled.
                                           This parameter can be a value of @ref USART_Hardware_Flow_Control */
} USART_InitTypeDef;
  1. USART_BaudRate uint32_t
    通信波特率,如 9600、115200。
    注释里给出计算公式:硬件会根据 USART 外设时钟 PCLKx,自动计算整数分频 + 小分数分频,生成对应波特率。
    ✅我们只需要填数字,库函数内部自动算分频寄存器,不用自己算。
  2. USART_WordLength 数据位长度
    可选宏:
    USART_WordLength_8b:8 位数据位(最常用)
    USART_WordLength_9b:9 位数据位(一般配合校验位使用)
    对应帧结构里的有效数据位。
    ⚠️开启校验时:校验位会占用最高位;8 位数据模式下,校验位是第 8bit;9 位模式下校验位是第 9bit。
  3. USART_StopBits 停止位
    可选宏:
    USART_StopBits_1:1 位停止位(绝大多数项目)
    USART_StopBits_0_5:0.5 停止位
    USART_StopBits_2:2 位停止位(长距离通信)
    USART_StopBits_1_5:1.5 停止位
    对应帧结构的停止位。
  4. USART_Parity 校验位
    可选宏:
    USART_Parity_No:无校验 NONE(日常默认)
    USART_Parity_Even:偶校验
    USART_Parity_Odd:奇校验
    对应帧结构的校验位。
    注意:开启校验后,有效数据会少 1 位,校验位占用最高 bit。
  5. USART_Mode 收发模式
    开启发送、接收,可以或运算同时打开:
    USART_Mode_Tx:只开启发送
    USART_Mode_Rx:只开启接收
    USART_Mode_Tx | USART_Mode_Rx:收发都打开(最常用)
    决定这个串口是发数据、收数据,还是收发都做。
  6. USART_HardwareFlowControl 硬件流控 RTS/CTS
    硬件流控:额外两根引脚,防止接收方缓冲区满导致丢数据。
    USART_HardwareFlowControl_None:不使用流控(99% 普通项目)
    USART_HardwareFlowControl_RTS
    USART_HardwareFlowControl_CTS
    USART_HardwareFlowControl_RTS_CTS
    普通 TTL 串口、USB‑TTL 调试不用流控,填 None。只有调制解调器、部分工业模块才用 RTS/CTS。

2.2 USART_SendData 串口发送

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);USARTx为要发送的串口,USARTx为要发送的数据。调用这个函数后,会把Data写到相应串口的数据寄存器准备发送,硬件外设自动完成。

2.3 USART_ReceiveData串口接收

uint16_t USART_ReceiveData(USART_TypeDef* USARTx); USARTx为要接收数据的串口,调用此函数可以得到数据寄存器的值。

细心的你会发现,串口发送和接收都是USARTx->DR,其实硬件内部接收和发送是两套数据寄存器,否则会冲突!

坑点:一定要判断标志位是否接收到数据,否则读到的是上一次的数据。

2.4 串行通迅中断标志位

中断宏 名称 触发条件 常用程度

USART_IT_CTS CTS 变化中断 硬件流控 CTS 引脚电平发生变化 很少用

USART_IT_LBD LIN 总线断开检测中断 检测到 LIN 总线 break 帧 极少,LIN 总线专用

USART_IT_TXE 发送数据寄存器空中断 发送数据寄存器 DR 为空,可以填入下一个待发字节 中等

USART_IT_TC 发送完成中断 一帧数据全部移位发送完毕(移位寄存器也空) 中等

USART_IT_RXNE 接收寄存器非空中断 收到 1 字节,DR 寄存器有新数据 ⭐非常常用

USART_IT_IDLE 总线空闲中断 检测到总线空闲(收到一帧之后,总线持续空闲) ⭐常用,不定长接收

USART_IT_ORE 溢出错误中断 旧字节还没读走,又收到新字节,数据丢失 错误中断

USART_IT_NE 噪声错误中断 采样收到噪声干扰 错误中断

USART_IT_FE 帧错误中断 没有检测到合法停止位(波特率错、干扰) 错误中断

USART_IT_PE 校验错误中断 开启校验位时,校验结果不匹配 错误中断

三、硬件接线

LED灯接线参考 零基础STM32入门教程--06-点灯实战

https://blog.csdn.net/oshan2012/article/details/163905246?spm=1011.2415.3001.5331

这里的串行通迅用的还是WCH-LINK,烧录和USB串口功能集成在一起。

STM32F103C8T6核心板---GND <----------> GND---WCH-LINK

STM32F103C8T6核心板---SWCLK <----------> SWCLK---WCH-LINK

STM32F103C8T6核心板---SWDIO <----------> SWDIO---WCH-LINK

STM32F103C8T6核心板---3V3 <----------> 3V3---WCH-LINK

STM32F103C8T6核心板---PA9 <----------> RX---WCH-LINK

STM32F103C8T6核心板---PA10 <----------> TX---WCH-LINK

串行通迅的发送和接收是交叉的,TX接对方的RX。

四、工程与程序编写

4.1工程复制

复制PWM工程文件夹为UART文件夹,PWM.uvprojx复制为UART.uvprojx。

4.2 添加驱动文件

  1. 直接在原usart.c文件里面添加,usart.h 不变。
c 复制代码
#include "stdio.h"
#include "usart.h"
#include "led.h"


// MicroLIB 只需要实现这一个函数
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t)ch);
    //等待发送寄存器为空,防止丢字符
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    return ch;
}




void usart1_init(uint32_t baud)
{
	
	GPIO_InitTypeDef gpio_init_struct;								//GPIO端口设置
	USART_InitTypeDef usart_init_structure;
	NVIC_InitTypeDef nvic_init_structure;								//嵌套向量中断控制器初始化结构体
		 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
	gpio_init_struct.GPIO_Pin = GPIO_Pin_9; //PA.9
	gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
	gpio_init_struct.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &gpio_init_struct);//初始化GPIOA.9
   
	//USART1_RX	  GPIOA.10初始化
	gpio_init_struct.GPIO_Pin = GPIO_Pin_10;//PA10
	gpio_init_struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &gpio_init_struct);//初始化GPIOA.10  
		  
	//USART 初始化设置
	usart_init_structure.USART_BaudRate = baud;					//串口波特率
	usart_init_structure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	usart_init_structure.USART_StopBits = USART_StopBits_1;		//一个停止位
	usart_init_structure.USART_Parity = USART_Parity_No;		//无奇偶校验位
	usart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	usart_init_structure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;	//发送和接收模式
	USART_Init(USART1, &usart_init_structure); //初始化串口1	
			
	//Usart1 NVIC 配置
	nvic_init_structure.NVIC_IRQChannel = USART1_IRQn;
	nvic_init_structure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
	nvic_init_structure.NVIC_IRQChannelSubPriority =0;		//子优先级0
	nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&nvic_init_structure);	//根据指定的参数初始化VIC寄存器
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口1接受中断
	USART_Cmd(USART1, ENABLE);                    //使能串口1 
	
}


void USART1_IRQHandler(void)                	//串口1中断服务程序
{	
	uint8_t res;	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
	{
		res =USART_ReceiveData(USART1);	//读取接收到的数据	
		if (res == 0xf0){
			led_on();
		}else if(res == 0xf1){
			led_off();
		}else{
			printf(" error \r\n");
		}
    } 
	 
}

main.c

c 复制代码
#include "stm32f10x.h"  
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "exti.h"
#include "time.h"
#include <stdio.h>


int main(void)
{	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);// 设置中断优先级分组4
	led_init();
	delay_init();
	usart1_init(115200);
	//key_init();
	//exit_init();	
	//time2_init(20000-1, 3600-1);
	//time2_ch2_pwm_init(1000-1,72-1);
		
	while(1)
	{				
		
		
	}
	
}

4.3 编译烧录

串口助手设置的参数要和程序里面一致,选择串口要正确(插拨一下看电脑里面的设置管理器里面的端口)。

下发F0 LED点亮,下发 F1 LED熄灭,下发其它会打印error

发送数据格式要选择HEX,程序里面是接收一个字节判断的。

如果使用蓝牙模块用手机app或小程序控制的效果是一样的,如果要更多的控制和参数设置,通常要编写自定义的协议来实现。

资料下载

参考资料网盘 :

链接 : https://pan.baidu.com/s/1BrH0JbUY6z7j7gAihTa4Dw

提取码: qnws

本节课完整工程例程网盘:

链接: https://pan.baidu.com/s/1rl6EIqi9m6kQ1JFjuSqINg

提取码: bumc

相关推荐
BW.SU1 小时前
RUI Studio--嵌入式 UI 开发新范式
单片机·ui·嵌入式开发
集芯微电科技有限公司1 小时前
700V/17A高频开关低导通阻GaN HEMT驱动器适用于快充,LLC,PFC功率校正
人工智能·嵌入式硬件·深度学习·神经网络·机器学习·生成对抗网络·计算机外设
恒锐丰小瑞2 小时前
率能SS6285M 33V/5.5A/单通道直流电机驱动IC,低待机功耗与多重保护,用于电子锁/玩具/机器人
stm32·单片机·嵌入式硬件·机器人
天空'之城2 小时前
单片机基础核心知识点汇总(二十一)
单片机·嵌入式硬件
恒锐丰科技林技术员3 小时前
SS6286L:大电流双向有刷电机驱动芯片,赋能电机控制多元场景
经验分享·嵌入式硬件·硬件工程
意法半导体STM323 小时前
【官方原创】LAT1695转换STM32CubeIDE工程到STM32CubeIDE for Visual Studio Code
vscode·stm32·单片机·嵌入式硬件
Zhang.Yi3 小时前
STM32-DMA
stm32·单片机·嵌入式硬件
Jaixln_HRF4 小时前
率能SS8837T 单通道1.8A/12V H桥电机驱动芯片,低功耗睡眠模式120nA,用于摄像机/玩具/机器人
驱动开发·嵌入式硬件·机器人·硬件工程
小鱼儿电子4 小时前
62-基于STM32的多功能水壶控制系统设计
stm32·单片机·嵌入式硬件·多功能水壶·智能水壶