前記
gcc編譯使用的printf打印函數需要的底層函數是和其他編譯器不同的,以前的是無法使用的,這里有兩種方法,一種是使用gcc庫里面的printf函數,自己實現底層IO函數_write。另外一種方法是自己定義 printf函數,這里給出兩者實現方法及測試結果。
方法一
假如要使用gcc庫里面的printf函數,這里使用底層編譯函數是_read()和_write(). 這里的read和write函數需要在system.c自己實現的,具體的實現方法如下所示:
#include <errno.h> #include <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO int _write(int file, char *data, int len) { if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) { errno = EBADF; return -1; } // arbitrary timeout 1000 HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 1000); // return # of bytes written - as best we can tell return (status == HAL_OK ? len : 0); }
方法二
其實,說白了只要找到串口寫函數,還有另外一種巧妙的方法,就是自制printf函數,不使用庫里面的,代碼如下所示:
#include <stdio.h> #include <stdarg.h> #include <string.h> void vprint(const char *fmt, va_list argp) { char string[200]; if(0 < vsprintf(string,fmt,argp)) // build string { HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 0xffffff); // send message via UART } } void my_printf(const char *fmt, ...) // custom printf() function { va_list argp; va_start(argp, fmt); vprint(fmt, argp); va_end(argp); }
代碼及運行結果
在代碼中,這里分別給出兩種方法的運行結果,如下所示:
// uart init MX_DEBUG_USART_Init(); /* 錕斤拷錕接幫拷錕斤拷錕斤拷始錕斤拷 */ KEY_GPIO_Init(); printf("test is init !\n\r"); my_printf("test pressed my printf \n\r"); /* 錕斤拷錕斤拷循錕斤拷 */ while (1) { if(KEY1_StateRead()==KEY_DOWN) { LED1_ON; printf("key1 pressed!\n\r"); //my_printf("key1 pressed my printf \n\r"); } if(KEY2_StateRead()==KEY_DOWN) { LED2_ON; printf("key2 pressed!\n\r"); //my_printf("key2 pressed my printf \n\r"); } if(KEY3_StateRead()==KEY_DOWN) { LED1_OFF; LED2_OFF; printf("key3 pressed!\n\r"); //my_printf("key3 pressed my printf \n\r"); } }
運行結果:
參考目錄
1 https://electronics.stackexchange.com/questions/206113/how-do-i-use-the-printf-function-on-stm32
2 https://www.openstm32.org/forumthread1055