当前位置: 首页 > news >正文

二十九、STM32的USART (串口发送)

前言:在 STM32 的开发过程中,串口通信(USART) 是我们最常接触的外设之一。
它不仅是调试信息输出的“窗口”,更是 MCU 与外部模块(如蓝牙、GPS、WiFi 模块等)进行数据交换的主要方式。本篇文章将带你从 初始化 USART 外设 开始,逐步讲解 STM32C8T6 串口发送的完整实现过程,包括底层函数封装、常用接口说明以及 printf 的重定向方法,帮助你全面掌握串口发送的核心原理与应用。

目录

一、USART 外设的基本介绍

二、接线图

三、串口发送初始化过程

四、串口发送函数的封装

五、printf 的重定向与串口打印

六、完整测试程序

七、总结


一、USART 外设的基本介绍

USART(Universal Synchronous Asynchronous Receiver Transmitter,通用同步/异步收发器)是 STM32 内部的重要通信外设。
它可以在 异步模式 下实现经典的 UART 通信,也能在 同步模式 下通过时钟信号实现精确同步。

本文重点讲解 USART 的发送部分,即 MCU 如何将数据从寄存器中输出到 TX 引脚上。

在 STM32 标准外设库中,USART 模块提供了丰富的配置接口,例如:

这些函数由 标准外设库(stm32f10x_usart.c) 提供,能帮助我们快速完成串口初始化与发送配置。

二、接线图

三、串口发送初始化过程

在 STM32 中使用串口发送前,需要完成以下几个步骤:

  1. 开启外设时钟

    • 开启 GPIOA 与 USART1 的时钟。

  2. 配置引脚功能

    • 将 TX 引脚(PA9)设置为复用推挽输出。

  3. 配置 USART 参数

    • 设置波特率、数据位、停止位、校验位、模式等。

  4. 使能 USART 外设

对应的初始化函数如下:

void Serial_Init(void)
{/* 开启时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 开启USART1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 开启GPIOA时钟/* GPIO 初始化 */GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        // 复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;              // TX引脚:PA9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* USART 参数配置 */USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;             // 波特率9600USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx;         // 仅发送模式USART_InitStructure.USART_Parity = USART_Parity_No;     // 无校验USART_InitStructure.USART_StopBits = USART_StopBits_1;  // 1位停止位USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位数据位USART_Init(USART1, &USART_InitStructure);/* USART 使能 */USART_Cmd(USART1, ENABLE);
}

此时,USART1 已经完成初始化,可以正式进行数据发送。

四、串口发送函数的封装

为了让串口发送更加方便,我们对标准库函数进行了进一步封装。

1. 发送一个字节

void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte); // 将数据写入数据寄存器while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

解释:

  • USART_SendData() 会把一个字节写入发送数据寄存器。

  • USART 会自动将该字节按时序输出到 TX 引脚。

  • USART_FLAG_TXE 表示发送寄存器为空,等待其置位表示当前字节已发送完成。

2. 发送数组

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{for (uint16_t i = 0; i < Length; i++)Serial_SendByte(Array[i]);
}

适用于一次性发送多个连续数据,如传感器数据或帧结构。

3. 发送字符串

void Serial_SendString(char *String)
{for (uint8_t i = 0; String[i] != '\0'; i++)Serial_SendByte(String[i]);
}

通过检测 '\0'(字符串结束符)来决定发送停止位置。

4. 发送数字

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{for (uint8_t i = 0; i < Length; i++)Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
}

用于直接发送整数值,内部将数字转换为对应的 ASCII 字符。

五、printf 的重定向与串口打印

在 C 语言中,printf() 默认输出到标准输出(如电脑终端),
而在嵌入式环境中,我们可以通过重定向函数 fputc() 把它改为通过串口发送。

1. 重定向 printf()

int fputc(int ch, FILE *f)
{Serial_SendByte(ch); // 将字符通过串口发送return ch;
}

只需实现该函数,之后 printf("Hello STM32!"); 的输出就会从串口发出。

2. 封装自定义 Serial_Printf()

#include <stdarg.h>
void Serial_Printf(char *format, ...)
{char String[100];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String);
}

这样即可在任意位置方便地打印格式化字符串:

Serial_Printf("\r\nTemp=%d C, Humidity=%d%%", 25, 60);

六、完整测试程序

int main(void)
{OLED_Init();       Serial_Init();      Serial_SendByte(0x41);             // 发送单字节数据uint8_t MyArray[] = {0x42, 0x43, 0x44, 0x45};Serial_SendArray(MyArray, 4);      // 发送数组Serial_SendString("\r\nNum1=");    Serial_SendNumber(111, 3);         // 发送数字printf("\r\nNum2=%d", 222);        // 方法1:标准printf重定向char String[100];sprintf(String, "\r\nNum3=%d", 333);Serial_SendString(String);         // 方法2:sprintf + SendStringSerial_Printf("\r\nNum4=%d", 444); // 方法3:自定义封装while (1);
}

运行后可以在串口调试助手中依次看到发送的数据,验证 USART 发送功能是否正常。

七、总结

通过本篇内容,我们完成了 STM32C8T6 串口发送的完整流程:

  • 了解了 USART 外设的基本接口函数;

  • 完成了串口的初始化与配置;

  • 封装了多种发送函数(字节、数组、字符串、数字);

  • 实现了 printf() 的重定向与自定义打印。

在嵌入式开发中,USART 是最基础也最实用的通信外设。
掌握串口发送后,你可以轻松实现调试输出、设备通信、数据上报等功能,为后续学习接收与中断通信打下坚实基础。

http://www.dtcms.com/a/606857.html

相关文章:

  • dw做网站链接数据库渭南 网站建设
  • 站长工具查询网站信息1 建设网站目的是什么意思
  • 企业网站开发课程的能力应用图片直链在线生成网站
  • 设计模式学习(3)-行为型模式
  • Angular 2 架构:深度解析与最佳实践
  • 09-微服务原理篇(XXLJOB-幂等-MySQL)
  • 代码随想录训练营打卡Day45| 动态规划part12
  • 网站开发要考什么证wordpress xy 变装
  • 已知两个端点的位置、切矢量和曲率,构造一条五阶Bézier 曲线实现 G² 连续的方法
  • 显示 Markdown 的文件
  • 算法学习入门---模拟(C++)
  • 列表网做优化网站怎么样成都网站注册
  • 文库网站开发教程wordpress 绑定熊掌号
  • C语言在线编译器网站 | 提供快速、便捷的在线编程与调试平台
  • 免费高清视频素材网站品牌网站建设定制
  • 个人做的卖货网站团购网站开发
  • C++---const关键字 编译期约束保证数据的 只读性
  • 算法基础入门第一章
  • 家用除湿机方案开发,除湿机MCU控制方案设计
  • 搜狗推广做网站要钱吗wordpress首页调用指定文章
  • wordpress使用人数宁波seo在线优化公司
  • YOLO系列发展史与应用现状:从开山之作到实时目标检测的基石
  • 【电商微服务日志处理全方案】从MySQL瓶颈到大数据架构的实战转型
  • 蔬菜配送网站建设网络系统脆弱性的不安全因素
  • 常州想做个企业的网站找谁做注册公司需要交多少税
  • 反编译易语言程序 | 如何安全有效地进行易语言程序的反编译操作
  • 刺猬猫网站维护wordpress $post->id
  • 商城网站开发项目描述嘉兴建站公司
  • 从爆款到厂牌:解读游戏工业化的业务持续增长道路
  • 深度学习:学习率衰减(Learning Rate Decay)