前言
本篇文章对串口Usart进行讲解,为后面的esp8266和语音模块控制打好基础。
1.串口USART
USART(Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步 / 异步收发器) 是一种常见的串行通信接口,广泛应用于嵌入式系统、单片机、传感器、通信设备等领域,主要用于设备之间的数据传输。
它的核心功能和作用可以从以下几个方面理解:
1.1.实现设备间的串行通信
串行通信:数据通过一根或几根信号线逐位传输(与并行通信的多线同时传输相比),节省硬件引脚资源,适合远距离或低成本的数据交换。
连接场景:例如单片机(如 STM32)与传感器、蓝牙模块(如 HC-05)、Wi-Fi 模块(如 ESP8266)、上位机(如电脑)等设备之间的通信,通常通过 USART 接口连接。
1.2. 支持同步和异步两种通信模式
USART 的 “同步 / 异步” 特性使其灵活性很高:
异步模式(最常用):不需要专用的时钟线,双方通过预先约定的波特率(数据传输速率,如 9600bps、115200bps)同步数据,仅通过TX(发送线) 和RX(接收线) 传输数据。例如:电脑通过 USB 转 TTL 模块与 ESP8266 的通信,就是用异步模式,通过串口助手发送 AT 指令。
同步模式:需要额外的时钟线(SCK)来同步数据传输,适合对时序要求严格的场景(如与某些传感器或外设的高速通信)。
1.3. 数据传输的基本原理
数据以 “帧” 为单位传输,每一帧包含:起始位(标志数据开始)、数据位(实际传输的 8 位或 9 位数据)、校验位(可选,用于验证数据正确性)、停止位(标志数据结束)。
双方需约定相同的波特率(如 9600、115200)、数据位、校验位、停止位(称为 “串口参数”),否则会出现数据传输错误。
1.4. 在嵌入式开发中的典型应用
指令控制:通过 USART 发送 AT 指令配置模块(如 ESP8266 的 Wi-Fi 连接、蓝牙模块的配对)。
数据采集:传感器(如温湿度传感器、GPS 模块)通过 USART 向上位机或单片机发送采集到的数据。
调试输出:单片机通过 USART 向上位机(如电脑)发送调试信息(如打印变量值、程序运行状态),方便开发调试。
设备联动:多个单片机或模块通过 USART 组成通信网络,实现数据共享或协同控制(如智能家居中多个设备的联动)。
1.5. 与 UART 的区别
UART(Universal Asynchronous Receiver/Transmitter) 仅支持异步通信,没有同步模式。
USART 是 UART 的增强版,既支持异步通信,也支持同步通信,功能更全面。在实际应用中,若无需同步模式,USART 通常也以异步模式使用,此时可视为 UART。
总之,USART 是嵌入式系统中设备间 “对话” 的重要桥梁,通过简单的硬件连接(通常只需 TX、RX、GND 三根线)和软件配置,即可实现稳定的数据传输,是物联网、智能家居、工业控制等领域的基础通信接口。
1.6.硬件介绍

2.代码实现
2.1.STM32Cubemx配置
我们这里以输出调试信息所用到的USART串口1为例。PA9为串口1的TXD、PA10为串口1的RXD。

我们将串口UART1配置为异步功能,Mode选择为Asynchronous,与PC端的通讯波特率为115200 Bit/s。

因为我们只是向PC端发送一些调试信息,无需接收PC端的数据,所以我们无需打开中断功能。
2.2.fputc重定向支持printf
在 STM32 开发中,标准库函数(如printf())默认输出到控制台(如电脑终端),但在嵌入式系统中,通常需要将输出重定向到串口。通过重写fputc()函数,可以实现以下功能:
- 使用printf()调试:将调试信息通过串口发送到电脑,方便开发时查看。
- 与外部设备通信:通过串口向其他设备发送数据。
该函数的作用是将字符ch,通过 USART1 串口发送出去,并等待发送完成。
int fputc(int ch, FILE *f)
{//USART1->SR:USART1 的状态寄存器,其中第 6 位(TXE)表示发送缓冲区是否为空。//0x40:二进制为0100 0000,用于检查TXE位。//循环等待:直到TXE位被置 1(发送缓冲区为空),才继续执行下一步。while( (USART1->SR & 0x40) == 0 );//USART1->DR:USART1 的数据寄存器,写入此寄存器将触发串口发送。//(uint8_t) ch:将字符转换为无符号 8 位整数后发送。USART1->DR = (uint8_t) ch;//返回发送的字符(作为整数),表示操作成功。return ch;
}
2.3.printf使用
int main()
{printf("Demo run!!!\n"); delay_ms(1000);
}