返回列表 发新帖我要提问本帖赏金: 100.00元(功能说明)

[STM32H5] STM32H5开发之printf的应用与固件编译时间的输出

[复制链接]
 楼主| yangjiaxu 发表于 2023-7-30 21:31 | 显示全部楼层 |阅读模式
<
本帖最后由 yangjiaxu 于 2023-7-30 21:32 编辑
#申请原创#@21小跑堂
上一篇帖子讲了搭建STM32H503RBT6-Nucleo的开发环境,感觉STM32H503RBT6-Nucleo的上手速度真的是泰裤辣,今天呢,趁热打铁,继续对STM32H503RBT6-Nucleo进行深一步的研究,本次将实现使用串口与printf函数,同时利用printf输出编译的时间与日期等等。
printf 是 C 语言中用于输出格式化输出的函数,它是标准输入/输出库 (stdio.h) 的一部分。
printf 的语法如下:
  1. int printf(const char *format, ...);
这里,format 是一个字符串,用于指定输出的格式,可选的省略号 (...) 表示可以有额外的参数与格式字符串中的格式说明符相对应。
使用printf函数可以很容易的将想要利用串口输出的数据打印出来,使用printf也可以做log输出,非常省事儿。使用printf有个前提,就是要将串口初始化,同时需要打开keil的Usemicrolib,之后在重定义串口。这样才能正常的使用printf函数。
本次利用STM32H503RBT6-Nucleo来实现以上描述的功能。首先由于板载带有STLINKV3,这个STlinkV3比较好在有个虚拟串口功能,这里虚拟串口以默认连接STM32H503RBT6芯片的串口3。
cf0463709a7c02ddfe36e6c02ec2b347
图1 开发板串口硬件连接说明
既然知道串口的连接,就可以利用cubemx实现对串口3的初始化了。打开cubemx,找到串口3的位置,然后选中,接下来就可以对其设置了,由于cubemx给了个基础配置,就是使用波特率115200,同时8位字节长度,一个停止位,无校验位,这样就可以了。
4e7f2e1ce78a64ed596ee7f756a3e756
图2 使用cubemx对串口3配置
当配置完成之后,就可以使用cubemx进行工程生成了,这里最基本的底层配置就算是完成了。接下来就是对串口重定义了,这里由于用到的是串口3,因此代码如下:
  1. int fputc(intch, FILE *f)
  2. {
  3.     HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 2);//huart根据你的配置修改
  4. return ch;
  5. }

当重定义之后就可以使用printf了,但是这时候写printf虽然不报错,编译也能通过,但是将程序烧录到芯片之中后,芯片是不能正确运行的,因为没有勾选UseMicroLIB,因此需要在keil上勾选一下,至此,就可以玩好的玩耍printf了。
e5cb84f111411c6e641b4d93d869a6bf
图3 keil的配置
这么玩耍printf好像也没啥意思,我们可以提升一点有意义的事情,比如通过printf输出代码编译出来的时间,日期和版本号。这里的时间日期都是代码编译出来的时候,keil获取的本地电脑时间,其实这个信息是非常有意义的,因为在做程序版本管理的时候,这信息可以代表程序是否是最新一次编译的。同时再配合自定义的程序版本号,就可以清晰明了的知道这个程序是否是最新的了。防止固件更新错误,导致误工误事。好,那我们说干就干,那么怎么利用keil获取本地时间呢?
这里keil其实已经帮我们做好了。就是    __DATE__,和 __TIME__,前者是日期,后者是时间。通过调用这两个预定义宏,就可以获取当前的时间和日期。接下来我们写点代码,就可以实现该功能。
写两个结构体:
  1. typedefstruct

  2. {

  3. char CodeVersion[32]; // 软件自定义版本

  4. char CodeBuildDate[32]; // 程序编译日期

  5. char CodeBuildTime[32]; // 程序编译时间

  6. } AppInfo_t;

  7. constAppInfo_tsg_tAppInfo =

  8. {

  9. "STM32_V0.1.0",

  10. __DATE__,

  11. __TIME__,

  12. };

接下来利用printf来打印结构体,就可以了。
  1. printf("This is a serial demo\r\n");

  2. printf("Version : %s\r\n", sg_tAppInfo.CodeVersion);

  3. printf("buildTime: %s\r\n", sg_tAppInfo.CodeBuildDate);

  4. printf("buildTime: %s\r\n", sg_tAppInfo.CodeBuildTime);

e807d7434bf4b1bfc498b96250eef2c0
图4 串口输出信息
至此,STM32H503RBT6-Nucleo的printf已经讲完了,其实printf还可以做很多事情,log输出,简单的字符串输出都可以用它,非常简单方便。

打赏榜单

21小跑堂 打赏了 100.00 元 2023-08-09
理由:恭喜通过原创审核!期待您更多的原创作品~

dspmana 发表于 2023-8-7 07:26 | 显示全部楼层
如何写出多串口共用printf函数语句
 楼主| yangjiaxu 发表于 2023-8-7 09:10 | 显示全部楼层
dspmana 发表于 2023-8-7 07:26
如何写出多串口共用printf函数语句

多串口公用一个printf?咋可能嘛。再说了,printf一般作用就是log输出,所以一般固定一个串口就可以的
guijial511 发表于 2023-8-7 09:15 来自手机 | 显示全部楼层
就是获取的系统当前时间

评论

是编译的时间  发表于 2023-8-7 11:26
qiufengsd 发表于 2023-8-7 17:03 | 显示全部楼层
stm32怎么用printf打印usart串口数据
robertesth 发表于 2023-8-7 20:58 | 显示全部楼层
STM32与C51的PRINTF 有什么不一样  
sdlls 发表于 2023-8-8 22:48 | 显示全部楼层
printf函数的参数需要按照输出的格式进行编写,同时也需要注意输出的位置和格式。
lzbf 发表于 2023-8-9 20:43 | 显示全部楼层
为什么用printf重定向到串口第一个字符打印不出
xiaoyh520 发表于 2023-8-12 14:29 | 显示全部楼层
这个也能收100?
MessageRing 发表于 2023-8-12 23:36 | 显示全部楼层
这个背景是怎么设置的,好高级啊
 楼主| yangjiaxu 发表于 2023-8-13 00:47 | 显示全部楼层
MessageRing 发表于 2023-8-12 23:36
这个背景是怎么设置的,好高级啊

通过发帖时,工具栏之中有BG的背景插件,可以选择自己喜欢的背景
alvpeg 发表于 2023-8-14 16:21 | 显示全部楼层
为了让printf函数将输出发送到所选的串口, 需要重定向标准输出流。这可以通过在代码中重写标准库函数来实现。
cemaj 发表于 2023-8-14 17:50 | 显示全部楼层
stm32中printf第一次打印字符丢失
huangchui 发表于 2023-8-14 20:46 | 显示全部楼层
MessageRing 发表于 2023-8-12 23:36
这个背景是怎么设置的,好高级啊

说明楼主用心了,一看你就没用过心
linfelix 发表于 2023-8-14 22:23 | 显示全部楼层
stm32编程怎么使用printf函数
Undshing 发表于 2023-8-14 22:49 | 显示全部楼层
编译时间是如何获取的啊?
 楼主| yangjiaxu 发表于 2023-8-14 23:25 | 显示全部楼层
Undshing 发表于 2023-8-14 22:49
编译时间是如何获取的啊?

电脑的本地时间啊,这是keil自带的功能
modesty3jonah 发表于 2023-8-15 13:08 | 显示全部楼层
STM32如何实现 printf输出中文
bartonalfred 发表于 2023-8-15 14:35 | 显示全部楼层
通过printf函数打印的数据怎么查看?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:擅长电路设计、物联网产品开发、射频产品开发,喜欢打篮球,技术交流,欢迎各位来聊~

783

主题

3316

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部