简单地说:想在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库函数之间的一个抽象层。

printf函数指向串口的方法的更多相关文章

  1. [STM32F10x] 使用printf函数进行串口调试问题

    硬件:STM32F103C8T6 平台:Keil ARM-MDk V5.11 利用printf函数通过串口(USART)进行调试时遇到的一个问题: printf("Hello, Mini-M ...

  2. 使用printf函数实现串口信息打印——设置IAR和Keil的Options

    在Keil和IAR中都可以使用printf函数,但两者设置的方法不一样.以下分别是IAR和Keil的设置. 下面是Keil的设置. 选中Options--->Target--->Code ...

  3. STM32F051关于printf函数在串口打印中的使用

    1.需要在Options for Target -> Code Generation 中勾选Use MicroLIB: 2.需要加入下面这个函数: int fputc(int ch, FILE ...

  4. STM32 的 printf() 函数串口重定向(HAL库标准库都适用)

    1.建立工程 2.核心:添加新文件usar_fputc.c (名字随便自己命名),把文件添加到项目中去 #include "stdio.h" #include "stm3 ...

  5. 如何在单片机上使用printf函数(printf)(avr)(stm)(lpc)(单片机)(转)

    摘要:    当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上,来判断我们的程序是否按预期的运行,printf函数很好的做到了这一点,它能直接以字符的方式输出变量名和变量的值,printf ...

  6. 修改HAL标准库用printf函数发送数据直接输出

    主函数文件,请直接关注自己写上去的代码: 直接看43行代码:#include "stdio.h"//要添加这个头文件 还有97行到112行:实现用HAL库函数和printf函数发送 ...

  7. 通过串口利用printf函数输出数据

    一.printf函数格式 printf函数具有强大的输出功能 %表示格式化字符串输出 目前printf支持以下格式的输出,例如: printf("%c",a);输出单个字符. pr ...

  8. 【stm32】实现STM32的串口数据发送和printf函数重定向

    在调试电机驱动程序的时候,是不能随便利用中断来进行一些寄存器或数据的查看的,不然你在运行的时候突然来一下,如果占空比大的话那可能直接就把MOS管给烧了,所以我们很多情况下只能使用USART(串口)来进 ...

  9. STM32 printf()函数和scanf()函数重定向到串口

    STM32 printf()函数和scanf()函数重定向到串口 printf()函数和scanf()函数重定向 在学习STM32的时候,常常需要用串口来测试代码的正确与否,这时候就要要用到print ...

随机推荐

  1. HDFS源码分析DataXceiver之整体流程

    在<HDFS源码分析之DataXceiverServer>一文中,我们了解到在DataNode中,有一个后台工作的线程DataXceiverServer.它被用于接收来自客户端或其他数据节 ...

  2. JQuery的一些思想,自己的一些见解!!!!

    自己总结了一下JQuery底层的一些思想,纯属于个人见解.. 为了方便描述,现在客户假如给了我们一个需求: 页面上有两个按钮,一张图片,当我点击hidden按钮时隐藏图片,当我点击show按钮时显示图 ...

  3. ssh无密码登陆权威指南

    [0]写在前面 由于ssh 实现的是免密码登陆,大致步骤是: 0.1) client通过ssh登陆到server: 0.2) server检查家目录下的.ssh文件, 并发送公钥文件 authoriz ...

  4. android的Environment类 Android存储访问及目录

    http://www.cnblogs.com/mengdd/p/3742623.html http://blog.csdn.net/barnett_zhubo/article/details/6832 ...

  5. 解决UICollectionView的Cell复用引起的布局混乱问题

    解决UICollectionView的Cell复用引起的布局混乱问题   问题复现.gif 查了一下度娘发现没有好的解决办法,于是发动自己的聪明才智,终于找到如下解决办法(充分证明了自己动手丰衣足食啊

  6. Objective-C中NSString转NSNumber的方法

    本文转载至 http://www.linuxidc.com/Linux/2013-02/78866.htm 在Objective-C中,以数字格式组成的字符串经常需要转换为NSNumber对象后再使用 ...

  7. 应用索引技术优化SQL 语句(转)

    原文出处 一.前言 很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致 ...

  8. 移动端 (H5) 调试工具 -- vconsole

    最近在改一个移动端项目,在手机上调试贼头疼,什么日志都看不到,分析不了bug问题. 然后我同事给我介绍了一个移动端的调试神器 -- vconsole 有了这个神器,领导再也不用担心我的工作啦!!! 0 ...

  9. react-native 支持 gif 图片

    只需要在android/app/build.gradle中的dependencies字段中添加: compile 'com.facebook.fresco:animated-gif:0.13.0' 然 ...

  10. M1卡的工作原理【转】

    本文转载自:https://blog.csdn.net/zmq5411/article/details/52042457 M1卡的工作原理 本篇对M1卡的编程是利用上述第二种方法.M1卡最为重要的优点 ...