关于stm32中串口重定向问题详解

发布者:脑力舞者最新更新时间:2017-09-07 来源: eefocus关键字:stm32  串口  重定向 手机看文章 扫描二维码
随时随地手机看文章

usart这部分代码我也是从网上copy出来的,一下是作者的解释:
简单地说:想在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库函数之间的一个抽象层。

第二个问题,路径:D:\Keil3.80\ARM\Examples\ST\STM32F10xFWLib\Examples


关键字:stm32  串口  重定向 引用地址:关于stm32中串口重定向问题详解

上一篇:基于stm32f103zet6的串口学习
下一篇:基于stm32f103zet6点亮LED之启动文件

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

stm32程序中的assert_param()的说明
子程序都有assert_param(....),如下:这句到底有什么用呢???把它删了应该可以的吗?? void TIM1_TimeBaseInit(u16 TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, u16 TIM1_Period, u8 TIM1_RepetitionCounter) { assert_param(IS_TIM1_COUNTER_MODE_OK(TIM1_CounterMode)); ...... } 答: 这是断言,可以删掉,只在编译的时候防
[单片机]
利用ARM的串口传送实现数控系统G代码的高速处理
一、 引言 现代数控加工都是先采用 CAD/CAM 软件画出零件的加工草图,然后根据草图做适当的属性设置,生成G 代码,生成G 代码之后通过某种方式将G 代码传送给数控系统进行解释转化成实际的轴运动。但是由于实际生成的G 代码数据量相对于ARM 嵌入式数控系统存储资源而言很大,不可能将G代码全部传给ARM数控系统存储起来之后再一条一条来解释、加工,因此在数据传输的过程中应该有一个流量控制的问题。虽然PC 机G 代码到ARM 数控系统代码传送方式很多,但ARM 的串口相对而言,操作方便,因此本设计采用串口来传送数据。虽然串口方便操作,但是在数据传送过程中也存在一些问题,比如说,PC 机向ARM传送9 个数据,却只收到8 个,如果数据
[单片机]
利用ARM的<font color='red'>串口</font>传送实现数控系统G代码的高速处理
stm32 4*4矩阵键盘
stm32f030开发板。 使用HAL库。 状态机做debounce消抖。 col列,Pin配置为PP推挽输出模式; row行,Pin配置为Input模式,启用内部上拉电阻。 代码如下: .h文件 /* * * Name: keypad.h * Faq: www.mazclub.com */ #ifndef KEYPAD_H #define KEYPAD_H #include stm32f0xx_hal.h //#include pinname.h #define COLS (GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|G
[单片机]
基于FPGA和STM32的FSMC通信
1、FSMC简介:FSMC即灵活的静态存储控制器,FSMC管理1GB空间,拥有4个Bank连接外部存储器,每个Bank有独立的片选信号和独立的时序配置;支持的存储器类型有SRAM、PSRAM、NOR/ONENAND、ROM、LCD接口(支持8080和6800模式)、NANDFlash和16位的PCCard。 2、在设计中将FPGA当做SRAM来驱动,使用库函数来实现FSMC的初始化配置代码如下: //初始化外部SRAM void FSMC_SRAM_Init(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; //定义FSMC初始化的结构体变量 FS
[单片机]
STM32定时器的TRGO信号
定时器的框图中有一个TRGO信号输出,此信号可以用来触发ADC、DAC、其他定时器等。 此信号怎么产生呢? 要使用 TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); 函数来选择TRGO信号的事件源,这个函数给TIMx_CR2寄存器的位6到位4赋值,位6到位4是MMS ,描述如下: 如果MMS 值为000:当TIMx_EGR寄存器的UG位有效,就会触发TRGO输出。 如果MMS 值为010:当产生更新事件时,就会触发TRGO输出。 另外: 当配置MMS 值为010:当产生更新事件时,就会触发TRGO输出。还可以配合重复计数寄存器来使用: 即重复多少
[单片机]
<font color='red'>STM32</font>定时器的TRGO信号
STM32STM32固件库(标准外设库)
标准外设库概述 STM32标准外设库是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。 因此,使用固态函数库可以大大减少开发者开发使用片内外设的时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用的标准化的API去驱动。这里介绍的是V3.5版本的外设库,也是迄今最新的版本。 STM32F10x标准外设库文件结构 库的下载处是在ST公司的官方网站,下载链接:ST公司官方网站。
[单片机]
【<font color='red'>STM32</font>】<font color='red'>STM32</font>固件库(标准外设库)
stm32 中DMA的stream和channel关系
问:STM32(意法)DMA中的stream和channel到底什么关系和区别? 答:拿stm32的DMA1做例举。DMA1中总共有8个stream,而每个stream可以配置成不同的传输源和目的地址,这就是channel。1个不同的源和目的就叫1个channel。如下图所示: 上图中stream0可以被配置成channel 0、1、2、3、4、6。配置成channel0时用spi3_rx功能,配置channel1时是i2c1_rx功能,但是stream0只能配置其中的1个channel,因为同一个stream不可能给外设1传输数据的同时又个外设2传输数据。具体配置在DMA_SxCR寄存器的CHSEL域配置
[单片机]
<font color='red'>stm32</font> 中DMA的stream和channel关系
基于AVR单片机的卫星地面测控系统设计
引言 本文介绍了单片机Atmega128在一种卫星地面测控系统中的应用,该系统利用Atmega128完成了10路模拟信号的测量、4路脉冲信号的频率测量以及脉冲宽度的测量,由单片机上的16位定时计数器输出两路与输入信号具有相位关系的信号,并通过外扩串口与其它测试模块及工控机进行通信。由于要求系统能够连续稳定工作3年,并且数据不能丢失,因此,在设计时采用了双电源冗余热备份的方案,并且采用两个工控机同时接收数据并互为备份的设计方案。 图1 卫星地面测控系统结构图 图2 测试箱的硬件原理图 图3 电地球波相位关系 硬件设计 Atmega12
[单片机]
基于AVR单片机的卫星地面测控系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

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

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

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved