stm32的printf使用

这篇具有很好参考价值的文章主要介绍了stm32的printf使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 参考代码:Embedded/stm32/STM32_printf · guorong/study - 码云 - 开源中国 (gitee.com)

        在刚开始学习C语言的时候,都使用过printf函数,支持的格式比较齐全,相打印什么样的信息都比较好实现。在使用STM32的过程中,也可以使用printf函数,printf函数是C语言stdio的库里定义好的函数,或者在stm32中,推荐勾选use microlib库,printf函数调用了fputc函数,这个函数也在库里被“弱定义”了,弱定义指的是如果有在其他地方重新定义,则使用重新定义的函数,若没有找到,则使用之前“弱定义”好的函数。在startup.s文件中,就弱定义了很多函数,都可以重新被定义,如下

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

fputc函数被定义指向了标准输出设备,而stm32中没有该设备,所以需要做一下重映射,即将fputc重新定义一次,以方便printf打印的时候,打印到我们想让其打印去的地方

有以下两种方式

  • 串口重映射

这种方式比较常见,直接初始化一个串口外设,然后将fputc函数定义为串口输出,如下

#include "usart.h"
int main(void)
{
    uart_init(115200);	 //串口初始化为115200
    while(1)
    {
        printf("hello world!\r\n");
    }    
 }
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);
    USART1->DR = (u8) ch;      
	return ch;
}

在正确初始化串口代码之后,可以在对应的串口1接入串口调试助手,即可看到串口打印出来的字符串stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

  • ITM重映射

上一种方法会占用一个串口,并且速度可能不是很快,还有一种STM32自带的调试工具ITM中也可以打印,速度快,并且不占用单片机的外设资源,配置方式如下。注意clock要配置对

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

然后在代码中加入如下片段

#include<stdio.h>

#define ITM_PORT8(n)         (*(volatile unsigned char *)(0xe0000000 + 4*(n)))
#define ITM_PORT16(n)        (*(volatile unsigned short *)(0xe0000000 + 4*(n)))
#define ITM_PORT32(n)        (*(volatile unsigned long *)(0xe0000000 + 4*(n)))
#define DEMCR                (*(volatile unsigned long *)(0xE000EDFC))
#define TRCENA               0X01000000
 
int fputc(int ch, FILE *f)
{
    if(DEMCR & TRCENA)
    {
        while(ITM_PORT32(0) == 0);                                                                                                                                                                                                                                                                                      
        ITM_PORT8(0) = ch;
    }
    return ch;
}
int main()
{
    while(1)
    {
        printf("hello world\r\n");
    }
}

运行在线调试,打开Debug(printf)Viewer

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

点击开始运行,即可看到打印出来的字符串

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

可以用作调试

附:关于使用标准库的时候的问题

在 STM32 或其他 ARM Cortex-M 微控制器中使用标准 C 库时,库中的一些函数默认是依赖于一个宿主系统的,这称为半主机(semihosting)操作。半主机操作使得嵌入式系统可以通过调试接口使用宿主机的I/O功能。例如,printf函数默认情况下是将字符输出到宿主机的终端上。

当你使用标准库(如printf)进行输出时,库函数实际上是调用_write函数来实现输出的。在ARM的标准库实现中,如果开启了半主机,_write函数会使用半主机操作将数据输出到宿主机。如果你的嵌入式系统中没有使用调试器或不支持半主机操作,那么这种输出就无法成功。

为了在没有半主机支持的环境里使用printf,你需要关闭半主机特性,并提供必要的重定向输出机制,让printf可以在微控制器中使用。_sys_exit是半主机标准库中调用结束程序的函数,而__FILE结构体和__stdout是用于文件操作的结构和对象。这些结构和函数在半主机环境中用于与宿主系统进行交互。

如果你不声明#pragma import(__use_no_semihosting)struct __FILE以及重写相关函数(比如_sys_exit),在不使用半主机时,使用这些半主机特定函数会导致链接错误或运行时错误,因为它们试图调用不存在的宿主机功能。

因此,为了重映射printffputc,确保能够通过串口直接打印,你需要:

  1. 使用一个编译器指定语句来告诉编译器你的程序不会使用半主机特性:#pragma import(__use_no_semihosting)

  2. 提供一个struct __FILE的定义,并且定义__stdout变量,因为标准的I/O函数如fputc通常会用到这些。

  3. 提供一个_sys_exit的定义,这样程序在无法找到半主机的退出函数时不会出错。

  4. 重写fputc函数以将数据输出到你的串口(或其他所需接口),而不是试图输出到宿主机系统。

若不执行这些步骤,编译器将会试图链接到原本为半主机设计的库函数版本,而这在没有宿主机支持的情况下导致代码无法运行或失败。而microlib本身就是为了嵌入式设备写好的,处理好了这些细节。

综上,在使用标准库的时候,加入以下代码,也可以正常使用

#include "usart.h"
int main(void)
{
    uart_init(115200);	 //串口初始化为115200
    while(1)
    {
        printf("hello world!\r\n");
    }    
 }
#pragma import(__use_no_semihosting)             
struct __FILE 
{ 
    int handle; 
}; 
FILE __stdout;       
void _sys_exit(int x) 
{ 
	x = x; 
} 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);
    USART1->DR = (u8) ch;      
	return ch;
}

还有一个有趣的现象,在编译的时候,如果勾选了使用microlib,如果你没有使用malloc函数,会把堆区的内存省掉,而在使用标准库的时候,则不论是否使用了malloc函数(未使用malloc函数的话,堆内存确实是没有用处的)都会保留堆内存,空间,如下两张图,分别为勾选和未勾选use microlib的内存分配情况,所以建议在开发嵌入式代码的时候,还是勾选上use microlib

勾选use microlib内存分配情况

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机

未勾选use microlib内存分配情况

stm32的printf使用,stm32,stm32,嵌入式硬件,单片机文章来源地址https://www.toymoban.com/news/detail-832476.html

到了这里,关于stm32的printf使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式毕设分享 基于单片机的风速测量系统 - 物联网 嵌入式 stm32 arduino

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(55)
  • stm32毕设分享 stm32实现车牌识别系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(52)
  • stm32毕设分享 Stm32酒驾检查系统 - 单片机 嵌入式 物联网

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月23日
    浏览(59)
  • 嵌入式STM32 单片机 GPIO 的工作原理详解

    STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称,是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子,该芯片共有 144 脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为

    2024年02月20日
    浏览(45)
  • 嵌入式项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月22日
    浏览(43)
  • 嵌入式硬件——stm32F103C8T6

    如下图:    处理器核心:STM32F103C8T6内置了ARM Cortex-M3处理器,这是一种高性能、低功耗的32位RISC处理器,适用于嵌入式系统。 时钟速度:它可以工作在不同的时钟速度,最高主频可达72 MHz。 存储器:包括64KB的Flash程序存储器用于存储程序代码,以及20KB的SRAM用于存储数据和

    2024年02月05日
    浏览(46)
  • stm32毕设分享 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(59)
  • 嵌入式项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月16日
    浏览(51)
  • 嵌入式毕设分享 stm32人脸识别快递柜系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年04月10日
    浏览(53)
  • 【项目设计】基于STM32人脸识别系统 - 单片机 物联网 嵌入式

    项目设计主要是对于所学知识的整体回顾,需要结合各个学科,才能做出达到符合标准的设计。 文章的目的在分享优质的项目以及项目经验,提供设计思路,欢迎交流与指正不足之处。 由于人脸识别技术具有无需接触、安全性高、可靠性高等优点,在身份认证领域具有广阔

    2024年01月21日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包