STM32
直播中

陈勇

7年用户 1245经验值
私信 关注
[问答]

如何实现使用printf()函数在STM32串口上输出数据呢

如何使用printf等标准C流函数输出数据呢?

如何实现使用printf()函数在STM32串口上输出数据呢?

回帖(1)

李梅

2021-12-2 14:49:45
STM32使用printf打印串口

摘要
  
           该方法适用于STM32,实现了使用printf等标准C流函数输出数据的办法,极大的减少了输出串口数据时所需要做的数据处理。
   
  


  • 实现原理

           在C库中,printf()等输出流函数都是通过fputc()这个函数实现的,所以我们通过重映射的方式,修改这个函数的定义使它输出在STM32的寄存器中,便可以实现使用printf()函数在STM32串口上输出数据的功能。
   
  


  • Keil环境 重映射

   在STM32的Keil开发环境中,C的库函数有两种实现方式
   



  •   


    • 使用标准的C函数库


             就是我们平常在PC Window平台上用的C库函数,此库的的优点在于实现的功能全面。但是由于这个库基本上是专为PC设计的,故而如果在嵌入式芯片中调用时将会使得工程文件变得十分庞大。
   

   将下列代码加入工程,无需使用#include调用即可生效。


/*
* libc_printf.c
*
*  Created on: Dec 26, 2015
*      Author: Yang
*
*                使用标准C库时,重映射printf等输出函数的文件
*    添加在工程内即可生效(切勿选择semihost功能)
*/

#include
//include "stm32f10x.h"  


#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
        int handle;

};
FILE __stdout;

//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}

//重映射fputc函数,此函数为多个输出函数的基础函数
int fputc(int ch, FILE *f)
{
        while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
        USART_SendData(USART1, (uint8_t) ch);
        return ch;
}




    • 使用MDK提供的 MicroLib


     
MicroLib is a highly-optimized library for ARM-based embedded applications written in C. When compared to the standard C library included with the ARM Compiler toolchain, MicroLib provides significant code size advantages required for many embedded systems.
  
                                             
  



   基本就是说:Microlib 是缺省 C 库的备选库。 它旨在与需要装入到极少量内存中的深层嵌入式应用程序配合使用。 这些应用程序不在操作系统中运行。microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,例如,memcpy()。

   

   
  同样的将下列代码加入工程,并在Keil设置中勾选Use MicroLib

/*
* microlib_printf.c
*
*  Created on: Dec 26, 2015
*      Author: Yang
*   
*    keil工程内勾选使用microlib时,重映射printf等输出函数的文件
*    添加在工程内即可生效(注意:仅在使用microlib有效)
*/
#ifdef UART_PRINT
#include
//include "stm32f10x.h"  

//重映射fputc函数,此函数为多个输出函数的基础函数
int fputc(int ch, FILE *f)
{
//        while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);    //修改此处的while循环条件
//        USART_SendData(USART1, (uint8_t) ch);                           //与寄存器,以修改输出端口
        return ch;
}
//输入函数,如上
int GetKey (void)  
{
//        while (!(USART1->SR & USART_FLAG_RXNE));                  //如上
//        return ((int)(USART1->DR & 0x1FF));
}
#endif
                  
  

  

  
  



  •   


    • GCC环境 重映射


                     在GCC开源开发环境中,则可以调用nano_printf.c 等多种方式重映流函数输出端口
举报

更多回帖

发帖
×
20
完善资料,
赚取积分