咱們在程序中使用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);
}