STM32的printf函数重定向

发布者:BeaLaity0170最新更新时间:2018-06-10 来源: eefocus关键字:STM32  printf函数  重定向 手机看文章 扫描二维码
随时随地手机看文章

在前面学习了STM32的串口编程,通过USART1向计算机的串口调试助手打印数据,或者接收计算机串口调试助手的数据,接下来我们可以实现STM32工程上的printf()函数了,方便用于程序开发中调试信息的打印。

1. 法1:使用MicroLIB库

1.1 KEIL-MDK中的Use MicroLIB选项

在MDK开发环境中, 
这里写图片描述

MicroLib是缺省c库的备选库,它可装入少量内存中,与嵌入式应用程序配合使用,且这些应用程序不在操作系统中运行。 
MicroLib进行了高度优化以使代码变得很小,功能比缺省c库少,不具备某些ISO c特性,部分库函数的运行速度也比较慢,如内存拷贝函数memcpy()。 
MicroLib与缺省c库之间的主要差异在网上有许多文章都有写到,这里摘抄记录: 
(1)MicroLib 不符合 ISO C 库标准。 不支持某些 ISO 特性,并且其他特性具有的功能也较少。 
(2)MicroLib 不符合 IEEE 754 二进制浮点算法标准。 
(3)MicroLib 进行了高度优化以使代码变得很小。 
(4)无法对区域设置进行配置。 缺省 C 区域设置是唯一可用的区域设置。 
(5)不能将 main() 声明为使用参数,并且不能返回内容。 
(6)不支持 stdio,但未缓冲的 stdin、stdout 和 stderr 除外。 
(7)MicroLib对 C99 函数提供有限的支持。 
(8)MicroLib不支持操作系统函数。 
(9)MicroLib不支持与位置无关的代码。 
(10)MicroLib不提供互斥锁来防止非线程安全的代码。 
(11)MicroLib不支持宽字符或多字节字符串。 
(12)与stdlib不同,MicroLib不支持可选择的单或双区内存模型。MicroLib只提供双区内存模型,即单独的堆栈和堆区。

MicroLib提供了一个有限的stdio子系统,它仅支持未缓冲的stdin、stdout和stderr,那么也就是说勾选了Use MicroLib选项后,在代码工程中就可以使用printf()函数咯? 
然而事实并非如此,这样直接使用printf()函数,其打印的字符串最终不知道打印到何处。我们要做的是将调试信息打印到USART1中,所以需要对printf()函数所依赖的打印输出函数fputc()重定向(MicroLib中的printf()函数打印操作依赖fputc())。

1.2 重定向fputc函数

在MicroLib的stdio.h中,fputc()函数的原型为:

int fputc(int ch, FILE* stream)


此函数原本是将字符ch打印到文件指针stream所指向的文件流去的,现在我们不需要打印到文件流,而是打印到串口1。基于前面的代码:


#include

int fputc(int ch, FILE* stream)

{

    //USART_SendData(USART1, (unsigned char) ch);

    //while (!(USART1->SR & USART_FLAG_TXE));

    USART_SendChar(USART1, (uint8_t)ch);

    return ch;

}


注意,需要包含头文件stdio.h,否则FILE类型未定义。 

勾选了Use MicroLib选项,重定向fputc()函数后,我们就可以在工程代码中使用printf()函数了:


int main(void)

{


    USART_Configuration();

    //USART_SendString(USART1, "HelloWorld\n");

    //USART_SendChar(USART1, 'h');

    printf("\r\nstm32f103rct6\r\n");

    printf("\r\nCortex-M3\r\n");

    while (1);  


    return 0;

}


printf()函数的使用方法跟之前一样,运行结果: 

这里写图片描述

2. 法2:不使用MicroLIB库

2.1 半主机模式

半主机模式是ARM的一种机制,实现将来ARM应用程序代码的输入/输出请求传送至运行着调试器的主机。例如设置使用半主机模式下的ARM应用程序,可以使用printf()和scanf()来使用主机的显示器和键盘,而不需要在ARM系统上搭配显示器和键盘。 
半主机通过一组定义好的软件指令(如SVC)来实现的,这些指令在程序控制下产生异常,ARM应用程序调用半主机对应的异常处理函数,然后调试代理处理该异常。

第二段话感觉理解起来有点模糊,但是第一段还是懂它在讲什么的。一般的ARM应用程序中并不需要半主机操作,在这里为确保ARM应用程序中没有链接MicroLib的半主机相关函数,我们要取消ARM的半主机工作模式。

2.2 实现代码

在工程中加上如下代码:

//取消ARM的半主机工作模式

#pragma import(__use_no_semihosting)                             

struct __FILE { 

    int handle; 

}; 


FILE __stdout;          

_sys_exit(int x) 

    x = x; 

}


int fputc(int ch, FILE *f){      

    while((USART1->SR&0X40)==0);

    USART1->DR = (u8) ch;      

    return ch;

}

上面的代码摘自正点原子的范例程序,具体每一行的意义目前也不大清楚。这样操作后,在不使用MicroLib的前提下,仍能使用printf()函数将调试信息打印到USART1上了。

关键字:STM32  printf函数  重定向 引用地址:STM32的printf函数重定向

上一篇:STM32-串口通信printf重定向
下一篇:STM32之串口重定向printf函数和scanf函数

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

STM32在程序中禁用JTAG功能后不能进行仿真的解决办法
STM32在程序中禁用JTAG功能后不能进行仿真会出现不能进行JTAG仿真的现象。 在程序中,通常禁止JTAG的函数如下所示: //改变指定管脚的映射 GPIO_Remap_SWJ_Disable SWJ 完全失能(JTAG+SW-DP) GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); //改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable JTAG-DP 失能 + SW-DP使能 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); 当设置了以上语句后,当运行了这两个语句后
[单片机]
STM32之LED按键中断
*************************************************************************************************************************************** 开发板 :奋斗STM32 CPU :STM32F103 开发环境:keil uVsion4 *****************************************************************************************************************************
[单片机]
STM32+0.91寸oled滚动显示bme680测得的数据
#include bme680.h uint8_t bme680_data ={0}; uint8_t aqi_accuracy; int16_t temperature,altitude; uint16_t humidity,aqi; uint32_t pressure,gas; void Bme680_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1Perip
[单片机]
STM32驱动W5100实现udp通信
环境: 主机:WIN7 开发环境:MDK4.72 MCU:STM32F103ZE 源代码: 驱动层代码: drv_w5100.h /********************************************************************* * w5100驱动层头文件 * (c)copyright 2013,jdh * All Right Reserved *文件名:drv_w5100.h *程序员:jdh *修改日期:2013/10/22 * 2013/10/23 * 2013/10/24 ************************
[单片机]
STM32的ADC用法你都知道吗?
AD采样在电路中是一种比较常见的功能,可以用于电池电压检测、传感器值读取、信号采集等。STM32的ADC,由于引入了DMA,以及多种触发源,功能自然强大,用法也多种多样。这里简单说下单通道情况下,AD采样的几种用法。 1、AD单次转换+软件启动 最基本的用法,通过程序启动AD,AD采集一次,我们就去读一次。这种情况,建议开启AD转换完成中断,在中断中读出AD值并做处理。 这种方式的优点是配置简单,缺点么,太T么简单~ 初始化的时候,启动一次。然后在主循环里,每隔一秒启动一次。 在中断回调函数里,进行相关处理: 电脑输出如下: 2、连续转换+软件启动 在方法1的基础上做调整,从单次转换,变成连续转换。也就是说,只需要
[单片机]
<font color='red'>STM32</font>的ADC用法你都知道吗?
stm32 SysTick定时器常见问题和实现延时
Q:什么是SYSTick定时器? SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。 Q:为什么要设置SysTick定时器? (1)产生操作系统的时钟节拍 SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 (2)便于不同处理器之间程序移植 Cortex‐M
[单片机]
stm32 keil中出现use of undeclared identifier' '的原因
出现这种情况,一般有以下几种原因: 1.变量未定义 2.未包含头文件 3.编译路径未包含该文件地址
[单片机]
<font color='red'>stm32</font> keil中出现use of undeclared identifier' '的原因
ST宣布STM32 F4系列为迄今性能最高ARM® Cortex™-M微控制器
    横跨多重电子应用领域、全球领先的半导体供应商意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)宣布,采用Green Hills软件公司最新软件工具独立进行的处理器性能评测证实,STM32 F4系列是迄今全球性能最高的ARM® Cortex™-M微控制器。    在行业基准CoreMark™评测 中,Green Hills软件公司的2012版编译器让STM32 F4系列多释放出29%的性能。CoreMark测试成绩用单一数字表示,以便设计人员比较不同品牌的处理器。这个创新高的CoreMark得分让工程师对STM32 F4系列微控制器更有信心,为他们选择业界性能最高的Cortex-M微
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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