首页 > 代码库 > 嵌入式如何使用printf打印

嵌入式如何使用printf打印

  我们在程序中使用printf把需要打印的信息打印到控制台上,那么在嵌入式中如何用printf来输出打印信息呢?

  有两种方法:

  其一,把fput()函数重新定义

  其二,重新定义一个类似printf的函数

  首先,介绍把fput()重新定义的方法

 1 struct __FILE 
 2 {
 3     int handle;
 4 };
 5 FILE __stdout;
 6 FILE __stdin;
 7 
 8 int fputc(int ch, FILE * p_file)
 9 {
10     assert_param(p_file);
11     
12         HAL_UART_Transmit(&UartDebugHandle, (uint8_t *)&ch, 1, 0xFFFF);
13 
14     return ch;
15 }

  因为printf()会调用fputc()函数向控制台发数据,我们将fputc()重定义,在该函数里边用串口发数据,所以当我们调用printf()时,就可以通过串口把数据发出去。

 

  接下来介绍第二种方法:

 1 #include <stdarg.h>
 2 #include <stdio.h>
 3 
 4 #define MAX_LENGTH 200
 5 static uint8_t debug_buffer[MAX_LENGTH] = {0};
 6 
 7 void test_printf(const char *fmt, ...)
 8 {
 9     va_list vlist;
10 
11     va_start(vlist, fmt);
12     vsnprintf(debug_buffer, MAX_LENGTH, fmt, vlist);
13     HAL_UART_Transmit_IT(&UartDebugHandle, (uint8_t*)debug_buffer,strlen(debug_buffer));
14     va_end(vlist);
15 }
16 然后,就可以调用test_printf()往外发数据了。
17 eg:int num = 100;
18 test_printf(“This is test num: %d”,num);

 

注:

  1、在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表。

       eg:void test_printf(const char *fmt, ...)

  2、函数参数的传递原理

  我们知道,函数的参数再内存中是存在栈中的,形参的存入顺序是从右向左存入的,void func(int x, float y, long z),在调用函数时,形参入栈的顺序是z > y >x,即z先入栈。

  栈是从上往下增长的,即从内存地址高的位置开始增长,往内存地址低的方向上增长。因此,我们只要知道形参中任一变量的内存地址,就可以得到其它变量的内存地址。

  3、介绍下test_printf()的实现

  在<stdarg.h>中定义了如下:

  typedef char * va_list;

  void va_start ( va_list ap, prev_param );

  void va_end ( va_list ap );

 

  void test_printf(const char *fmt, ...)

  {

    //定义指针vlist

      va_list vlist;

 

    //让vlist指向形参的第一个变量

    va_start(vlist, fmt);

    //把fmt和不定长的参数(vlist指向参数列表)复制到debug_buffer中

    vsnprintf(debug_buffer, MAX_LENGTH, fmt, vlist);

    HAL_UART_Transmit_IT(&UartDebugHandle, (uint8_t*)debug_buffer, strlen(debug_buffer));

    //在使用完指针之后,需要把指针关掉,以防出现危险。

        va_end(vlist);

   }

嵌入式如何使用printf打印