嵌入式如何使用printf打印

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

  有两种方法:ui

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

  其二,从新定义一个相似printf的函数debug

  首先,介绍把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()时,就能够经过串口把数据发出去。code

 

  接下来介绍第二种方法:blog

 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);

 

注:内存

  一、在C中,当咱们没法列出传递函数的全部实参的类型和数目时,能够用省略号指定参数表。it

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

  二、函数参数的传递原理

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

  栈是从上往下增加的,即从内存地址高的位置开始增加,往内存地址低的方向上增加。所以,咱们只要知道形参中任一变量的内存地址,就能够获得其它变量的内存地址。

  三、介绍下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);

   }