关于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;

/// 《summary》

/// 定义_sys_exit()以避免使用半主机模式

/// 《/summary》

/// 《param name=“x”》《/param》

/// 《returns》《/returns》

_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中关于串口通信的printf函数重定向问题

在STM32串口通信程序中使用printf()函数发送数据非常方便,但是需要先进行简单的配置,下面介绍两种配置方法。

方法一、对工程属性进行配置

第1步:在main.c中包含“stdio.h” (标准输入输出头文件);

第2步:在main.c文件中重定义fput()这个C标准库函数(因为printf()在C标准库函数中实质上是一个宏,要调用到fputc()这个函数);

第3步:在工程属性的”Target“ -》 ”Code Generation“ 选项中勾选”Use MicroLIB“;

方法二:在工程中添加“regtarge.c”文件

第1步:在main.c文件中包含”stdio.h”文件;

第2步:在工程中创建一个文件保存为“regtarge.c”,然后将其添加到工程中;

第3步:在main文件中添加定义以下两个函数

至此完成配置,可以在main.c文件中随意调用printf() 。

c语言输入输出重定向到串口,关于printf重定向到串口的问题分析 - 全文相关推荐

  1. STC15单片机-串口打印printf重定向

    printf函数重定向为往串口打印信息 在UART.h.UART1.h和UART.c文件的内容编写好后,在main函数中实现通过串口发送一串字符串和一个不断加1的变量 方法一: 使用sprintf函数 ...

  2. STM32使用printf重定向到USART(串口)并打印数据到串口助手

    STM32使用sprintf打印数据到串口助手 一.背景知识 二. 重定向printf到USART1 三.使用printf打印hello,world到串口助手 3.1 usart.c 3.2 usar ...

  3. stm32中如何进行printf重定向用于串口调试输出

    1 在main中包含stdio.h 文件 2 Target选项框里选Use MicroLib 选项 3 在main中添加UART1_Configuration()初始化的代码 Uart1初始化, vo ...

  4. keil5 stm32f03c8t6 printf重定向到串口和TFT 1.44 LCD屏

    效果 keil5工程设置,这一步很重要: 在任意的源文件里重写int fputc(int ch, FILE* f)函数 代码: print.h #ifndef __PRINT_H__ #define ...

  5. STM32中printf重定向到串口

    学习STM32过程中,经常打交道的莫过于串口,你可以将任何信息,当然重要的是调试信息打印到串口中输出,总是用一个字节发送函数或者字符串发送函数 总是有些不放便,之前编程中熟悉的莫过于printf了,下 ...

  6. STM32 KEIL 串口打印printf使用详解

    常规打印方法 在STM32的应用中,我们常常对printf进行重定向的方式来把打印信息printf到我们的串口助手. 在MDK环境中,我们常常使用MicroLIB+fputc的方式实现串口打印功能,即 ...

  7. c语言i o编程,C 语言输入输出 (I/O)

    C 语言输入输出 (I/O) 在本教程中,您将学习如何使用scanf()函数从用户处获取输入,并使用printf()函数向用户显示输出. C 语言输出 在C语言编程中,printf()是主要的输出函数 ...

  8. c语言标准输入输出ppt,c语言输入输出语句PPT

    <c语言输入输出语句PPT>由会员分享,可在线阅读,更多相关<c语言输入输出语句PPT(29页珍藏版)>请在人人文库网上搜索. 1.输入输出语句通常需要在程序运行过程中输入数据 ...

  9. c语言课题设计字符串处理函数报告,C语言输入输出库函数设计实验报告.doc

    C语言输入输出库函数设计实验报告 第 PAGE \* MERGEFORMAT I页 共 SECTIONPAGES \* MERGEFORMAT 1页 华中科技大学计算机科学与技术学院 C语言课程设计报 ...

最新文章

  1. c语言中输入10,10 is greater than 0,2013练习题__Student
  2. JAVA面试题总汇(含答案)
  3. python list遍历定位元素_python for循环,第二遍定位不到元素?
  4. 异常来自 hresult:0x800a03ec_肺癌早期不是悄无声息,一旦出现这3个“异常”,十有八九是肺癌...
  5. python缩进问题idle_Python IDLE中的缩进问题
  6. # 20155224 第十一周 课堂练习《计算后缀表达式的值》
  7. C++ const型成员函数与 non-const型成员函数
  8. Pytorch 学习笔记:
  9. Sql根据不同条件统计总数
  10. Python3利用BeautifulSoup4抓取站点小说全文的代码
  11. android plot,androidplot行不显示
  12. IntelliJ-IDEA-Debug技巧
  13. 8乘8led点阵显示数字_光立方8乘8乘8立体点阵
  14. c语言char sex是什么意思,2012年计算机二级C语言入门教程:结构体
  15. 针对ewebeditor编辑器漏洞一次实战经验
  16. 20-Netty TCP 粘包和拆包及解决方案
  17. 怎么将Excel多个工作表拆分成多个单独的Excel
  18. excel设置行高和列宽
  19. 工作中常见的开会问题
  20. OSPF与BGP联动

热门文章

  1. VUe3 @cli(axios)跨域访问
  2. mybatis------通过mapper接口加载映射文件(六)
  3. frame越过另一个frame_一个价值2万美元的Facebook DOM XSS漏洞
  4. 计算机主机拆解,计算机硬件系统及主机拆解..ppt
  5. 单片机与普通微型计算机不同在于,单片机与普通计算机的不同之处在于什么,单片机与普通微型计算机的不同...
  6. Timeline的Clip编辑模式总结
  7. double float区别 java,float和double有什么区别?
  8. OpenShift4 - 使用 Service CA 证书增加内部通讯安全
  9. 在Blazor中构建数据库应用程序——第5部分——查看组件——UI中的CRUD列表操作
  10. 谷歌搜索将于 2019 年年底停止索引任何 Flash 内容