细说MCU串口函数及使用printf函数实现串口发送数据的方法
目录
1、硬件及工程
2、串口相关的库函数
(1)串口中断服务函数:
(2)串口接收回调函数:
(3)串口接收中断配置函数:
(4)非中断发送:
(5)中断发送:
3、使用printf函数串口发送数据
(1)包含头文件
(2)修改发送字符函数putchar()
(3)修改3
(4)修改4
4、下载运行
1、硬件及工程
文章依赖的硬件及工程配置同本文作者的其他文章:细说ARM MCU的串口接收数据的实现过程-CSDN博客 https://wenchm.blog.csdn.net/article/details/139541112
2、串口相关的库函数
MCU串口通讯用到的HAL库函数有下面几个:
(1)串口中断服务函数:
HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
(2)串口接收回调函数:
HAL_UART_R×CpltCallback(UART_HandleTypeDef *huart)
(3)串口接收中断配置函数:
HAL_UART_Receive_IT(UART_HandleTypeDef *huart,uint8_t *pData,uint16_t Size)
(4)非中断发送:
HAL_UART_Transmit(*huart,pData,Size,Timeout)
(5)中断发送:
HAL_UART_Transmit_IT(*huart,pData,Size)
3、使用printf函数串口发送数据
在MCU中,可以利用printf函数将信息送到MCU的外设上。比较常用的场合就是通过串口发送数据。
(1)包含头文件
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
(2)修改发送字符函数putchar()
由于STM32CubeIDE使用的是GNU C/C++编译器,所以printf使用的底层函数是putchar函数,具体来说就是__io_putchar(int ch)。
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{CommFlag = 1;HAL_UART_Receive_IT(&huart2,(uint8_t *)RxBuffer,RXBUFFERSIZE);
}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{HAL_GPIO_WritePin(BUZ_GPIO_Port,BUZ_Pin,GPIO_PIN_RESET);HAL_Delay(100); //延时HAL_GPIO_WritePin(BUZ_GPIO_Port,BUZ_Pin,GPIO_PIN_SET);for(uint8_t i = 0; i < RXBUFFERSIZE; i++){printf(" RxBuffer[%d] = 0x%02x\r\n",i,RxBuffer[i]);}
}int __io_putchar(int ch) //putchar实现
{HAL_UART_Transmit(&huart2,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */
需要把上面的实现代码放到注释对中。可以放到注释对/*USER CODEBEGIN 4*/和/*USER CODE END 4 */之间。与前面介绍的两个回调函数HAL_UART_RxCpltCallback()和HAL_GPIO_ EXTI_Callback()放到一起。
在上面putchar函数的定义中,串口发送函数使用的是库函数HAL_UART_Transmit(),每次发送1字节的数据。
完成上面的工作后,就可以使用printf函数通过串口发送数据了。
(3)修改3
/* USER CODE BEGIN PV */
uint8_t CommOkMessage[] = "Everything is OK\r\n";
uint8_t CommErrMessage[] = "Received Error Data\r\n";
uint8_t CommFlag =0;
uint8_t RxBuffer[RXBUFFERSIZE] = {0};
/* USER CODE END PV */
(4)修改4
本文例子实现如下功能:程序执行后,MCU首先通过串口发送提示字符串“Please Enter Data:”;随后,等待接收数据;MCU通过中断接收到3字节数据后,会将它们存储到RxBuffer数组中;最后,利用按键B1来查看送来的数据,即在按下B1键后,通过串口送出RxBuffer数组中接收到的数据。
要实现上述功能,首先要在while(1)循环前使用printf函数通过串口送出提示输入数据的信息:
/* Infinite loop *//* USER CODE BEGIN WHILE */printf("Please Enter Data:\r\n");while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if ((RxBuffer[0] == 0x53) && (RxBuffer[2] == 0x45) && (CommFlag == 1)){CommFlag = 0;printf("Everything is OK!:\r\n");if(RxBuffer[1] == 0x10){HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);//HAL_UART_Transmit(&huart2,CommOkMessage,19,1000);}else{HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);//HAL_UART_Transmit_IT(&huart2,CommErrMessage,22);}}}/* USER CODE END 3 */
然后,修改按键中断处理的回调函数HAL_GPIO_EXTI_Callback(),加入串口发送数据的代码。具体实现如上面第(2)步。
4、下载运行
在printf函数中,%d是按整型数据输出,%x是按十六进制格式输出,%02x中的02表示位宽为2,不够的话前边补0。
编译、下载、运行程序后,在串口助手的接收区,会看到提示输入数据的字符“Please Enter Data:”。通过串口助手按十六进制格式送出数据53 10 45后,串口助手会接收到字符“Everything is OK”,表示数据已经正确收到。如果想查看具体收到的是什么数据,可以按一下NUCLEO-G474RE板上的B1键,在串口助手上就会显示所接收到的数据。
准备就绪,会收到消息“Please Enter Data:”

连续发送3次数据53 10 45 ,会收到3次数据正确的消息“Everything is OK”
连续发送4次数据53 10 45 ,会收到4次数据正确的消息“Everything is OK” ,并不是程序写错了,而是程序没写判断数据的对错,程序只是判断数据是否准备妥当了。妥当了,就OK。
按下B1键,看看MCU接收到了什么数据并显示到串口助手上,按一下B1显示一次。

相关文章:
细说MCU串口函数及使用printf函数实现串口发送数据的方法
目录 1、硬件及工程 2、串口相关的库函数 (1)串口中断服务函数: (2)串口接收回调函数: (3)串口接收中断配置函数: (4)非中断发送ÿ…...
PBox iOS端的应用隐藏、图片视频加密软件
哈喽,大家下午好!相信大家的手机中一定存在很多的私密内容,比如软件、照片、视频或者文档文件,很多都是不方便让外人看到的,此时就需要一款隐藏工具,市面上这类软件大部分都是收费的,应大家的需…...
【QT5】<总览五> QT多线程、TCP/UDP
文章目录 前言 一、QThread多线程 二、QT中的TCP编程 1. TCP简介 2. 服务端程序编写 3. 客户端程序编写 4. 服务端与客户端测试 三、QT中的UDP编程 1. UDP简介 2. UDP单播与广播程序 前言 承接【QT5】<总览四> QT常见绘图、图表及动画。若存在…...
fastadmin/thinkPHPQueue消息队列详细教程
thinkphp-queue 是thinkphp 官方提供的一个消息队列服务,它支持消息队列的一些基本特性: 消息的发布,获取,执行,删除,重发,失败处理,延迟执行,超时控制等队列的多队列, 内存限制 ,启动,停止,守护等消息队列可降级为同步执行1、通过composer安装thinkPHP消息队列 …...
社区新标准发布!龙蜥社区标准化 SIG MeetUp 圆满结束
5 月 31 日,「龙蜥社区“走进系列”」第 9 期之走进阿里云于北京圆满结束。来自阿里云、浪潮信息、红旗软件、中兴通讯|中兴新支点、中科曙光、中科方德、统信软件、麒麟软件、万里红、普华基础软件、飞腾信息、凝思、申威、新华三等公司的 30 余位专家出席会议。会…...
快速开始一个go程序(极简-快速入门)
一、 实验介绍 1.1 实验简介 为了能更高效地使用语言进行编码,Go 语言有自己的哲学和编程习惯。Go 语言的设计者们从编程效率出发设计了这门语言,但又不会丢掉访问底层程序结构的能力。设计者们通过一组最少的关键字、内置的方法和语法,最终…...
HTTPS缺失?如何轻松解决IP地址访问时的“不安全”警告
一、问题现象 如果访问网站时出现以下任何一种情况,则说明该网站需要立即整改: 1.浏览器地址栏那里出现“不安全”字样; 2.小锁标志被红叉()、斜线(\)等标志为不可用;…...
验证码识别接口、多种样式验证码识别接口、中英文验证码识别接口
验证码识别接口、多种样式验证码识别接口、中英文验证码识别接口 本文提供一个基于OCR和机器学习的验证码识别接口,能够识别较复杂的中文、英文验证码,在OCR的基础上针对验证码进行算法优化。本接口是收费的(最低0.5分1次调用,试…...
测试bert_base不同并行方式下的推理性能
测试bert_base不同并行方式下的推理性能 一.测试数据二.测试步骤1.生成bert配置文件2.安装依赖3.deepspeed 4卡tp并行4.FSDP 4卡并行5.手动将权值平均拆到4张卡,单进程多卡推理6.手动切分成4份,基于NCCL实现pipeline并行 本文测试了bert_base模型在不同并行方式下的推理性能 约…...
FFMpeg解复用流程
文章目录 解复用流程图复用器与解复用器小结 解复用流程图 流程图,如上图所示。 复用器与解复用器 复用器,就是视频流,音频流,字幕流,其他成分,按照一定规则组合成视频文件,视频文件可以是mp4…...
438. 找到字符串中所有字母异位词
题目 给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词指由相同字母重排列形成的字符串(包括相同的字符串)。 示例 1: 输入: s "cbaebabacd", p &q…...
【Qt 快速入门(三)】- Qt信号和槽
目录 Qt 快速入门(三)- Qt信号和槽Qt信号和槽详解信号和槽的基本概念信号槽连接 信号和槽的声明与定义连接信号和槽信号和槽的高级特性自动参数匹配信号与信号连接lambda 表达式作为槽自定义信号和槽 信号和槽的线程支持跨线程连接 信号和槽的生命周期管…...
Debain12 离线安装docker
官网教程:https://docs.docker.com/engine/install/debian/ 步骤 1. 解压 docker-deb.7z 安装包并上传Linux (资源在PC端文章顶部) 2. 安装 .deb 包 sudo dpkg -i ./containerd.io_<version>_<arch>.deb \./docker-ce_<vers…...
C++day5
思维导图 搭建一个货币的场景,创建一个名为 RMB 的类,该类具有整型私有成员变量 yuan(元)、jiao(角)和 fen(分),并且具有以下功能: (1)重载算术运算符 和 -…...
SHELL脚本学习(六) 呈现数据
一、标准文件描述符 linux系统会将每个对象当作文件来处理,包括输入和输出。linux用文件描述符来描述每个对象。文件描述符是一个非负整数,唯一会标识的是打开的文件。每个进程一次最多能打开9个文件描述符。处于特殊目的,bash shell保留了前…...
计算机网络:网络层 - IPv4数据报 ICMP协议
计算机网络:网络层 - IPv4数据报 & ICMP协议 IPv4数据报[版本 : 首部长度 : 区分服务 : 总长度][标识 : 标志 : 片偏移][生存时间 : 协议 : 首部检验和][可变部分 : 填充字段] ICMP协议 IPv4数据报 一个IPv4数据报,由首部和数据两部分组成ÿ…...
【需求设计】软件概要设计说明怎么写?概要设计说明书实际项目案例(63页Word直接套用)
软件概要设计说明书书写要点可以归纳为以下几个方面,以确保文档的准确性、完整性和可读性: 引言 目的:介绍编写该文档的目的、主要内容及目标读者。 背景:说明被开发软件的名称、项目提出者、开发者等背景信息。 需求概述…...
网络编程2----UDP简单客户端服务器的实现
首先我们要知道传输层提供的协议主要有两种,TCP协议和UDP协议,先来介绍一下它们的区别: 1、TCP是面向连接的,UDP是无连接的。 连接的本质是双方分别保存了对方的关键信息,而面向连接并不意味着数据一定能正常传输到对…...
服务架构的设计原则
墨菲定律与康威定律 在系统设计的时候,可以依据于墨菲定律 任何事情都没有表面上看起来那么简单所有的事情都会比你预计的时间长可能出错的事总会出错担心的某一个事情的发送,那么它就更有可能发生 在系统划分的时候,可以依据康威定律 系…...
Day 14:2938. 区分黑球和白球
Leetcode 2938. 区分黑球和白球 桌子上有 n 个球,每个球的颜色不是黑色,就是白色。 给你一个长度为 n 、下标从 0 开始的二进制字符串 s,其中 1 和 0 分别代表黑色和白色的球。 在每一步中,你可以选择两个相邻的球并交换它们。 返…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
