怎么解决STM32(MDK)中不能使用printf()函数的问题

发布者:沭阳小黄同志最新更新时间:2016-09-08 来源: eefocus关键字:STM32  MDK  printf()函数 手机看文章 扫描二维码
随时随地手机看文章
简单地说:想在mdk 中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式),
标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数.
例如:printf输出到串口,需要将fputc里面的输出指向串口(重定向),方法如下:
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
因printf()之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,以下是解决方法:
方法1.使用微库,因为使用微库的话,不会使用半主机模式.
方法2.仍然使用标准库,在主程序添加下面代码:
#pragma import(__use_no_semihosting) 
_sys_exit(int x) 

x = x; 

struct __FILE 

int handle; 
/* Whatever you require here. If the only file you are using is */ 
/* standard output using printf() for debugging, no file handling */ 
/* is required. */ 
}; 
/* FILE is typedef’ d in stdio.h. */ 
FILE __stdout;
如果使用的是MDK,请在工程属性的“Target“-》”Code Generation“中勾选”Use MicroLIB;今天参考了一下论坛,使用微库可以很好的解决这个问题。
2.另一种方法:(其实大同小异)  
需要添加以下代码 
(论坛里应该有完整介绍这个的帖子,但是我没搜到,也许是沉了。)
#pragma import(__use_no_semihosting)  
/******************************************************************************  
*标准库需要的支持函数  
******************************************************************************/  
struct __FILE  
{  
int handle;  
/* Whatever you require here. If the only file you are using is */  
/* standard output using printf() for debugging, no file handling */  
/* is required. */  
};  
/* FILE is typedef’ d in stdio.h. */  
FILE __stdout;  

///   
/// 定义_sys_exit()以避免使用半主机模式  
///
  
///   
///   
_sys_exit(int x)  
{  
x = x;  
}  



int fputc(int ch, FILE *f) 

    //USART_SendData(USART1, (u8) ch); 
    USART1->DR = (u8) ch; 
     
    /* Loop until the end of transmission */ 
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    { 
    } 

    return ch; 

semihosting的作用,介绍如下 
Semihosting is a mechanism for ARM targets to communicate input/output requests 
from application code to a host computer running a debugger. This mechanism could be 
used, for example, to allow functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system. 
This is useful because development hardware often does not have all the input and 
output facilities of the final system. Semihosting allows the host computer to provide these facilities. 
Semihosting is implemented by a set of defined software interrupt (SWI) operations. 
The application invokes the appropriate SWI and the debug agent then handles the SWI 
exception. The debug agent provides the required communication with the host. 
In many cases, the semihosting SWI will be invoked by code within library functions. The application can also invoke the semihosting SWI directly. Refer to the C library descriptions in the ADS Compilers and Libraries Guide for more information on support for semihosting in the ARM C library. 
按我的理解,这个模式是用来调试的,通过仿真器,使用主机的输入输出代替单片机自己的,也就是说即便单片机没有输出口也能printf到电脑上。反过来,由于这个模式更改了printf()等的实现方式,输入输出就不走单片机的外设了,所以只重定义fputc不起作用。 

用代码关闭此模式后,需要同时更新一下__stdout 和__stdin 的定义,所以有后面的语句。 

以上仅为个人理解,如有错误请指正。 


另外,勾选microlib之后,也许编译的时候就不把开启semihosting的文件包进去了,所以没事。

C库函数重定向:
用户能定义自己的C语言库函数,连接器在连接时自动使用这些新的功能函数。这个过程叫做重定向C语言库函数,如下图所示。
举例来说,用户有一个I/O设备(如UART)。本来库函数fputc()是把字符输出到调试器控制窗口中去的,但用户把输出设备改成了UART端口,这样一来,所有基于fputc()函数的printf()系列函数输出都被重定向到UART端口上去了。
下面是实现fputc()重定向的一个例子:
externvoidsendchar(char*ch);
intfputc(intch,FILE*f)
{/*e.g.writeacharactertoanUART*/
chartempch=ch;
sendchar(&tempch);
returnch;

这个例子简单地将输入字符重新定向到另一个函数sendchar(),sendchar()假定是个另外定义的串口输出函数。在这里,fputc()就似乎目标硬件和标准C库函数之间的一个抽象层。
关键字:STM32  MDK  printf()函数 引用地址:怎么解决STM32(MDK)中不能使用printf()函数的问题

上一篇:stm32 启动顺序以及系统时钟设置
下一篇:学习STM32之SD卡总结

推荐阅读最新更新时间:2024-03-16 15:09

STM32-通用定时器基本定时功能
1. STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。 定时器 计数器分辨率 计数器类型 预分频系数 产生DMA请求 捕获/比较通道 互补输出 TIM1 TIM8 16位 向上,向下,向上/向下 1-65536之间的任意数 可以 4 有 TIM2 TIM3 TIM4 TIM5 16位 向上,向下,向上/向下 1-65536之间的任意数 可以 4 没有 TIM6
[单片机]
STM32 USB 之从0开始移植笔记
-----------------------------------动机----------------------------------- 写在前面的话:最近逛淘宝无意间发现RC522居然只要10元左右就可以包邮买到,真是太便宜了,就忍不住买了个回来玩玩。到货移植到我的板子上OK 后突然发现我的USB口紧张了,一个用来给板子供电一个插jlink 一个插入usb转串口给RC522下命令。就想着将板子供电和RC522传输用一个USB接口来实现。这就是这次折腾USB的来由~-~ ----------------------------------开始折腾USB----------------------------- 首
[单片机]
<font color='red'>STM32</font> USB 之从0开始移植笔记
STM32一个定时器同时捕获4路PWM波
问题的提出: 最近需要用航模遥控器控制遥控车,32单片机做主控,需要用到4个通道即需要捕获4路PWM波。如果用四个定时器来捕获四路PWM波,就太浪费资源了。由于STM32单片机的定时器资源有限,故设想用一个定时器的4个通道同时捕获四路PWM波。 设计思路: 由于接收机输出的PWM波高电平最多就2ms,故可以让4个通道轮流使用定时器捕获PWM波 程序如下: include PWMin.h void TIM2_2PWMin_Init(u16 arr,u16 psc) { RCC- APB1ENR|=1 0; RCC- APB2ENR|=1 2; GPIOA- CRL&=0XFFFF0000; GPIOA- CRL|=0X0000
[单片机]
STM32学习之uCGUI移植详解
以下内容大多是网上资源,我只做一些修改和结合,为的是能够方便更多的和我一样的菜鸟们搞懂GUI的移植。 第一部分:在UCGUI移植之前 在移植之前,首先要了解在网上下的UCGUI 3.98源码的文件结构是。 UCGUI 3.98源码中有三个文件夹: 1)“tool文件夹”是用来使用一些uCgui的上位机程序,基本都是字体和模板查看之类的. 2)“sample文件夹”下面是已经别人帮你写好了很多有用的东西,像跟操作系统有关的GUI_X或者一些模板(后面我们会用到的自己定义的Demo),或者是gui配置.后面再一一详细叙说这个文件夹的功能. 3)“Start文件夹”里面,这是我们最主要的文件夹.里面就包含了uCG
[单片机]
DMA传输实验
DMA简介 DMA(Direct Memory Access)一种直接存储器存取,单片机的一个外设,它的主要功能就是用传输数据的,好处就是传输数据的时候不占用CPU。数据传输的方向有 外设到存储器,存储器到存储器,外设到外设这里的存储器包括SRAM和FLASH。 DMA 的要素 1.DMA请求如果外设想要通过DMA传输数据,必须先给DMA控制器发送DMA请求。DMA收到信号后控制器会给外设发送一个应答信号,当外设收到应答信号且DMA控制器收到应答信号之后,就会启动DMA传输,直到传输完毕 2通道。DMA具有12个独立的可编程通道,每个通道对应不同的外设的DMA请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一
[单片机]
STM32高级开发——使用VS Code搭建STM32开发环境
以前在伴随着开发平台的转换中,我尝试过各种各样的开发环境,而在最近一段时间的开发中我使用了Visual Studio Code来作为代码编辑器,其优异的工程管理,超快的启动速度,各种各样功能强大的插件,使我立刻爱上了这个文本编辑器。 但是在开发中来来回回在编辑器和Keil等IDE之间来回切换对我造成了不少不方便,另外由于希望能够在windows下使用gcc工具链开发,所以我尝试使用插件来完整的在vscode上搭建了一个开发环境。可以说这是我在windows平台下尝试过的最好用的一种搭配,下面我就来详细讲述一下这个环境的搭建和基本使用方式。 ps:启动真心快,在win下优化程度堪比记事本. 1 安装软件 下载安装 Visual
[单片机]
STM32 F103USB官方例程枚举知识
下面是USB枚举方面用到的一些函数以及他们之间的调用关系,由于本人刚刚接触STM32,可能会有一些错误,还望指正
[单片机]
<font color='red'>STM32</font> F103USB官方例程枚举知识
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved