历史上的今天
返回首页

历史上的今天

今天是:2024年10月05日(星期六)

正在发生

2018年10月05日 | STM32关于printf重定向到串口

2018-10-05 来源:eefocus

简单地说:想在mdk 中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式), 标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数. 
例如:printf输出到串口,需要将fputc里面的输出指向串口(重定向),方法如下: 
#ifdef __GNUC__ 
 
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) 
#else 
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) 
#endif  
PUTCHAR_PROTOTYPE 

  
  
 USART_SendData(USART1, (uint8_t) ch); 
  
 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;  
 
 
 
};  
 
FILE __stdout; 
如果使用的是MDK,请在工程属性的“Target“-》”Code Generation“中勾选”Use MicroLIB;今天参考了一下论坛,使用微库可以很好的解决这个问题。 
2.另一种方法:(其实大同小异)   
需要添加以下代码  
(论坛里应该有完整介绍这个的帖子,但是我没搜到,也许是沉了。) 
#pragma import(__use_no_semihosting)   
  
struct __FILE   
{   
int handle;   
  
  
  
};   
  
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;  
      
     
    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) 
{ 
chartempch=ch; 
sendchar(&tempch); 
returnch; 
} 
这个例子简单地将输入字符重新定向到另一个函数sendchar(),sendchar()假定是个另外定义的串口输出函数。在这里,fputc()就似乎目标硬件和标准C库函数之间的一个抽象层。
 
第二个问题,路径:D:\Keil3.80\ARM\Examples\ST\STM32F10xFWLib\Examples

推荐阅读

史海拾趣

Baneasa SA公司的发展小趣事

随着产品的逐渐成熟,Baneasa SA开始积极寻求市场拓展的机会。公司通过与各大电子设备制造商建立合作伙伴关系,成功将其产品应用于手机、电脑、家电等多个领域。这些合作伙伴关系的建立不仅为Baneasa SA带来了稳定的订单量,还进一步提升了公司的品牌知名度和市场份额。

FCT Electronics公司的发展小趣事

随着电子行业的快速发展,市场竞争日益激烈。为了应对挑战,FCT Electronics不断加大研发投入,推出了一系列具有自主知识产权的新产品。同时,公司还加强了与高校、研究机构的合作,引进了一批高素质的人才,为公司的持续发展注入了新的活力。

Herth+Buss Fahrzeugteile GmbH & Co KG公司的发展小趣事
监控人员进出,确保安全。
Hi-Light Electronic Co Ltd公司的发展小趣事
安装在门窗、围墙等处,提高家庭安防水平。
Avasem公司的发展小趣事

在国内市场取得一定成功后,Avasem公司开始实施国际化战略,以进一步拓展全球市场份额。公司首先在欧洲和北美等成熟市场设立了研发中心和销售网点,以便更好地了解当地市场需求和消费者偏好。随后,Avasem公司通过与当地合作伙伴建立战略联盟,共同推广其产品和技术。这一战略不仅提升了公司在全球市场的知名度,还为其带来了可观的收益增长。

ETEQ Microsystems Inc公司的发展小趣事

在电子行业的浪潮中,ETEQ Microsystems Inc于XXXX年应运而生,创始人带着对微型电子技术的深厚理解和远见,立志打造一家具有创新精神的芯片设计企业。初创期,公司面临资金短缺、人才匮乏和市场竞争激烈的挑战。然而,通过精心研发的几款高性能低功耗芯片,ETEQ Microsystems Inc迅速在市场上打开了局面,赢得了合作伙伴的认可。

问答坊 | AI 解惑

单片机怎样处理LM331送来的信号

本帖最后由 paulhyde 于 2014-9-15 09:41 编辑 当将模拟信号转换成方波脉冲后,再将脉冲信号送入单片机,那么单片机是怎样处理这个脉冲信号的?  …

查看全部问答>

8051fxxx IDE出现下列问题

note:usb address and data registers will not valid until usb clock is running 这是什么造成的呢?…

查看全部问答>

技术在于积累!-------谈谈偶做LED驱动电源的经历

技术在于积累!        第一次刚接触LED驱动是从一块DEMO板: DC输入,输出是低电流大致200MA的; 因为客户的需求,后来公司头一次想用SMD802开发一块非隔离的7*1w 450MA驱动板;那时候没买样板,也没找专门的IC厂商,要求技 ...…

查看全部问答>

关于AT89S52单篇机,

你好,我刚买了上面那个型号,,但是,我烧写时,出现了编程器不存在,什么回事?…

查看全部问答>

用软件如何实现蓝牙接收的数据转换

最近做了一个题目,使用蓝牙接收到的数据在LED点阵上显示出来,但是前提是不知道要接收的数据的内容。该如何实现接收到的数据用编程直接转换成LED点阵上能识别的二进制数。是该做一个字库还是有其他什么别的方法。请专业人士帮忙解决一下。谢谢。…

查看全部问答>

windows ce stream driver wizard

搜遍了整个网络也没有找到windows ce stream driver wizard这个工具,哪位大哥大姐弟弟妹妹能够慷慨解囊,帮小弟一把,不胜感激。小弟的邮箱是:cougarz@somagic.com.cn…

查看全部问答>

哪位达人用过《EVC高级编程及其应用开发》这本书上基础数据库的例子?

我在wince下试了这个程序,可是不好使阿,添加不了,也删除不了,请问是还需要安装什么程序还是本身实例程序有问题啊?…

查看全部问答>

今天用Proteus仿真的ADC0809。。。但实际0809不工作啊。。。。

  单片机的对应ST脚的P口接上0809时就被拉低了。Proteus仿真什么问题都没有。0809要注意什么问题么?有两个问题:1,我希望设定的是500K,用定时器方式2也是设成255。可从P口出来的就是50K 啊。2,ST脚被拉低,但不接0809时单片机P口是正常的 ...…

查看全部问答>

【求助】JTAG下载遇到问题:-(

我在使用msp430F149的JTAG模块下载时,一开始还能下载运行,试了有两三天,突然一天不能下载了,后来就再也不能下了,软件提示不能发现目标。然后又贴了一块板子,结果这块好了半天就又出现和前面一样的现象。很是郁闷 量了下载口各个引脚的电压 ...…

查看全部问答>

I2C连续读写请教

想通过I2C连续写数据和读数据,用for循环来操作,写入的都是第一个数据,后面的就没有写入了,读也是这样。但如果不用for循环写,直接写入两个数据可以实现,但是读得时候也不能实现;在网上搜了下也是用for循环啊,但是我的怎么不能实现呢?请大家 ...…

查看全部问答>