代码使用<stdio.h>库中的sprintf函数将格式字符串存储到缓存中,以及<string.h>中的strlen函数获取缓存数长度(这里注意是长度而不是大小sizeof),这里简单说明一下者的区别:
strlen:是获取数组长度,遇到‘\0’结束,获取的是长度
sizeof:计算数据类型占内存的大小
好了我们开始:
我这里使用的是串口发送dma方式,小伙伴们可以自己更改HAL_UART_Transmit_DMA改为自己的就可以了,使用这个方法可以很快理解,当然也有使用vprintf的方式,需要重定向printf,个人感觉比较麻烦,这个理解了马上就能写出来。当然不能实现scanf,但只是打印数据还是很方便的。而且代码可移植性非常强。
自定义log函数打印:
注意要定义打印缓存log_buf
#define DEBUG_LEN 100
#define LOGXHH(fmt,...) {sprintf(log_buf,fmt,##__VA_ARGS__);\
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)log_buf ,strlen(log_buf));\
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)==RESET);}
这样就实现了简单的串口打印数据的宏定义也可以算是自己写的printf
我们再加上一些条件编译:
#define DEBUG_LEN 100 //定义串口发送数据最大长度
extern char log_buf[DEBUG_LEN];//声明打印缓存变量为外部变量
#define DEBUG_OFF 0//关闭打印
#define DEBUG_ERROR 1//只打印错误
#define DEBUG_WARNING 2//打印警告和错误
#define DEBUG_INFO 3//打印所有信息
#define DEBUG DEBUG_INFO//选择打印所有信息
#define DEBUG_USART huart1//日志打印串口为串口1
#if (DEBUG==DEBUG_OFF)
#define LOGE(fmt,...) {;}
#define LOGW(fmt,...) {;}
#define LOGI(fmt,...) {;}
#else
#if(DEBUG>=DEBUG_ERROR)
#define LOGE(fmt,...) {sprintf(log_buf,fmt,##__VA_ARGS__);\
HAL_UART_Transmit_DMA(&DEBUG_USART, (uint8_t *)log_buf ,strlen(log_buf));\
while(__HAL_UART_GET_FLAG(&DEBUG_USART,UART_FLAG_TC)==RESET);}
#if(DEBUG>=DEBUG_WARNING)
#define LOGW(fmt,...) {sprintf(log_buf,fmt,##__VA_ARGS__);\
HAL_UART_Transmit_DMA(&DEBUG_USART, (uint8_t *)log_buf ,strlen(log_buf));\
while(__HAL_UART_GET_FLAG(&DEBUG_USART,UART_FLAG_TC)==RESET);}
#if(DEBUG>=DEBUG_INFO)
#define LOGI(fmt,...) {sprintf(log_buf,fmt,##__VA_ARGS__);\
HAL_UART_Transmit_DMA(&DEBUG_USART, (uint8_t *)log_buf ,strlen(log_buf));\
while(__HAL_UART_GET_FLAG(&DEBUG_USART,UART_FLAG_TC)==RESET);}
#else
#define LOGI(fmt,...) {;}
#endif
#else
#define LOGW(fmt,...) {;}
#define LOGI(fmt,...) {;}
#endif
#endif
#endif
这样就实现了日志打印!!!!!
是不是很简单!!!
下面我们来使用屏幕实现printf的类似功能:
查看屏幕显示字符串的函数
因为没有回车需要指定行数(与printf唯一的区别)
#define OLED_LEN 48
#define TXT_SIZE 16
extern char oled_buf[OLED_LEN];
#define oled_printf(line,fmt,...) {sprintf(oled_buf,fmt,##__VA_ARGS__);\
OLED_ShowString(0,line*TXT_SIZE,(uint8_t *)oled_buf,TXT_SIZE,1);\
OLED_Refresh();}
使用其函数打印效果极佳,舒服
欢迎交流