STM32H7系列其二

尘归尘、土归土,老夫有酒二两五

  • printf重定向介绍
  • STM32中printf重定向

printf重定向介绍

在学C语言的时候,会经常用标准库中printf(), scanf()这两个函数, 来实现数据的输入与输出. 格式化输入输出的功能还是挺强大的, 那已经有了现成的轮子, 就要寻思一下如何进一步在单片机上使用它.
下面是ARM Compiler6文档中对printf的介绍:

The printf family consists of _printf(), printf(), _fprintf(), fprintf(), vprintf(), and vfprintf().
All these functions use __FILE opaquely and depend only on the functions fputc() and ferror(). The functions _printf() and _fprintf() are identical to printf() and fprintf() except that they cannot format floating-point values.
The standard output functions of the form _printf(…) are equivalent to:
fprintf(& __stdout, …)where __stdout has type __FILE.

大致是说printf家族有这么些函数<_printf(), printf(), _fprintf(), fprintf(), vprintf(), and vfprintf()>, 这些函数都隐式的使用__FILE<文件流>, 并且只依靠fputc(), ferror()这两个函数.

If you define your own version of __FILE, your own fputc() and ferror() functions, and the __stdout object, you can use all of the printf() family, fwrite(), fputs(), puts() and the C++ object std::cout unchanged from the library.

重新定义__FILE, fputc(), ferror(), __stdout, 就可以使用printf()家族的各种函数了.

STM32中printf重定向

下面是官方给出的重映射模板:
<遇到不会的先看看文档往往能得到最直接的答案>

#include <stdio.h>
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;
int fputc(int ch, FILE *f) 
{
  /* Your implementation of fputc(). */
  return ch;
}
int ferror(FILE *f)
{
  /* Your implementation of ferror(). */
  return 0;
}

要将printf()重定向到STM32中的串口, 只需要重新实现 fputc() 函数即可, 在fputc()中通过串口发送一个char. 在上一次的工程上进行修改, 将printf()重定向到串口3.

#include <stdio.h>
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;
int fputc(int ch, FILE *f) 
{
  /* Your implementation of fputc(). */
  HAL_UART_Transmit( &huart3, ( uint8_t* )&ch, 1, 0xFFFF );
  return ch;
}
int ferror(FILE *f)
{
  /* Your implementation of ferror(). */
  HAL_UART_Transmit( &huart3, ( uint8_t* )"Printf Error\n", 13, 0xFFFF );// 可选
  return 0;
}

写个简单的程序试一试:

int main(void)
{
    MPU_Config();
    SCB_EnableICache();
    SCB_EnableDCache();
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ETH_Init();
    MX_USART3_UART_Init();
    /* USER CODE BEGIN 2 */
	double d = 1.234;
	int i = 60;
	char str[] = "Do not be lazy.\n";
	printf("Hello World\n");
	printf("d = %lf\ni = %d\n", d, i);
	printf("this is a string : %s", str);

    while (1){}
}

输出结果:
STM32H7系列其二_第1张图片
可以开始愉快的使用printf()了.

你可能感兴趣的:(STM32H7)