嵌入式 printf的实现
在嵌入式中,经常需要用到printf来调试程序
标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数.
printf输出到串口,需要将fputc里面的输出指向串口(重定向)
因此,实现printf就需要重定向相关的函数。有的时候,我们想自己实现printf的功能,不妨自己写一个
#include <stdarg.h> #include <stdio.h> //#include <unistd.h> #define BUFSIZE 1024 char myprintf_buf[BUFSIZE]; void Debug_printf(const char* fmt, ...) { // if(osOK == osMutexWait(uartMutexHandle, osWaitForever)) //根据需要,最好上个锁 { va_list args; int n; va_start(args, fmt); n = vsnprintf(myprintf_buf, BUFSIZE, fmt, args); va_end(args); int i = 0; for(i = 0; i < n; i++) { HAL_UART_Transmit(&huart2, (uint8_t *)&myprintf_buf[i], 1, 0xFFFF); //根据不同的平台,修改串口输出的函数 } //或者 HAL_UART_Transmit(&huart2, (uint8_t *)myprintf_buf, n, 0xFFFF); //根据不同的平台,修改串口输出的函数 } // osMutexRelease(uartMutexHandle); } int main(void) { Debug_printf("test %d\r\n", 100); return 0; }
方法二:
#include <stdarg.h> #include <stdio.h> #include <string.h> static unsigned long m_pow(int x,int y) { unsigned long sum = 1; while(y--) { sum *= x; } return sum; } //打印字符 void m_putchar(const char ch) { HAL_UART_Transmit(&huart2, (uint8_t *)ch, 1, 0xFFFF); } //打印字符串 void m_putstr(const char *str) { while(*str) { m_putchar(*str++); } } int printint(const int dec) { int count = 0, ret = 0; int r_val = dec; char ch; while(r_val) { count++; r_val /= 10; } ret = count; r_val = dec; while(count) { ch = r_val / m_pow(10, count - 1); r_val %= m_pow(10, count - 1); m_putchar(ch + '0'); count--; } return ret; } int printfloat(const float flt) { int countint = 0,countflt = 0; int count = 0, r_val = 0; int tmpint = (int)flt; int tmpflt = (long int)(10000000 * (flt - tmpint)); if(tmpflt % 10 >= 5) { tmpflt = tmpflt / 10 + 1; } else { tmpflt = tmpflt / 10; } r_val = tmpflt; count = 0; while(r_val) { count++; r_val /= 10; } countint = printint(tmpint); m_putchar('.'); int i = 0; for(i = 0; i < 6 - count; i++) { m_putchar('0'); } countflt = printint(tmpflt); return countint + 1 + count + countflt; } int m_printf(const char *str,...) { va_list ap; int val,r_val; float val_float; char count,ch; char *s = NULL; int res = 0; va_start(ap, str); while('\0' != *str) { switch(*str) { case '%': str++; switch(*str) { case 'd': val = va_arg(ap, int); count = printint(val); res += count; break; case 'x': val = va_arg(ap, int); r_val = val; count = 0; while(r_val) { count++; r_val /= 16; } res += count; r_val = val; while(count) { ch = r_val / m_pow(16, count - 1); r_val %= m_pow(16, count - 1); if(ch <= 9) m_putchar(ch + '0'); else m_putchar(ch - 10 + 'a'); count--; } break; case 'f': val_float = va_arg(ap, double); count = printfloat(val_float); res += count; break; case 's': s = va_arg(ap, char*); m_putstr(s); res += strlen(s); break; case 'c': m_putchar((char)va_arg(ap, int)); res += 1; break; default: ; } case '\n': m_putchar('\n'); res += 1; break; case '\r': m_putchar(*str); res += 1; break; default: m_putchar(*str); res += 1; } str++; } va_end(ap); return res; } int main(void) { char buf[64]; m_printf("======== begin test =========\n"); snprintf(buf, sizeof(buf), "%s %f", "hello world", 20.043); m_printf("%s\n", buf); return 0; }
Talk is cheap, show me the code