【摘要】 平時開發C語言程序時,經常需要調試代碼,C語言有一些宏,可以打印出當前的行號、文件名稱、日期、時間,對程序的調試起到很大的幫助,可以快速定位問題。特別是開發單片機程序時,使用這些宏打印這些信息或者在LCD上顯示程序的編譯日期、時間,可以知道這個單片機上的固件是什么時候編譯。幫助判斷版本。
一、前言
平時開發C語言程序時,經常需要調試代碼,C語言有一些宏,可以打印出當前的行號、文件名稱、日期、時間,對程序的調試起到很大的幫助,可以快速定位問題。特別是開發單片機程序時,使用這些宏打印這些信息或者在LCD上顯示程序的編譯日期、時間,可以知道這個單片機上的固件是什么時候編譯。幫助判斷版本。
ANSIC標準定義了可供C語言使用的預定義宏:
__LINE__ : 在源代碼中插入當前源代碼行號
__FILE__ : 在源代碼中插入當前源代碼文件名
__DATE__ : 在源代碼中插入當前編譯日期
__TIME__ : 在源代碼中插入當前編譯時間
其中標識符__LINE__和__FILE__一般用來調試程序,打印信息,方便定位錯誤。
標識符__DATE__和__TIME__一般可以用來表示固件的版本,方便了解運行的程序是什么時候的版本。
標識符__LINE__是一個整數,其他的文件名稱、日期、時間都是字符串。
二、打印示例
printf("編譯日期與時間: %s,%s\n", __DATE__,__TIME__);
printf("當前所在行號:%d\r\n", __LINE__);
printf("當前源文件名稱:%s\r\n", __FILE__);
printf("當前固件編譯日期:%s\r\n", __DATE__);
printf("當前固件編譯時間:%s\r\n", __TIME__);
三、C語言封裝快捷Debug
#define DEBUG
#ifdef DEBUG
static int DebugPrintf(const char *format, ...)
{
va_list arg_data;
int count;
va_start(arg_data, format); /* 獲取可變參數列表 */
fflush(stdout); /* 強制刷新輸出緩沖區 */
count = vfprintf(stderr, format, arg_data); /* 將信息輸出到標準出錯流設備 */
va_end(arg_data); /* 可變參數列表結束 */
return count;
}
#else
static inline int DebugPrintf(const char *format, ...)
{
}
#endif
通過DEBUG這個宏來開啟是否開啟調試信息打印功能,如果程序穩定后,不需要打印調試信息,就可以將DEBUG的定義取消掉即可。
完整代碼:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//#define DEBUG
#ifdef DEBUG
static int DebugPrintf(const char *format, ...)
{
va_list arg_data;
int count;
va_start(arg_data, format); /* 獲取可變參數列表 */
fflush(stdout); /* 強制刷新輸出緩沖區 */
count = vfprintf(stderr, format, arg_data); /* 將信息輸出到標準出錯流設備 */
va_end(arg_data); /* 可變參數列表結束 */
return count;
}
#else
static inline int DebugPrintf(const char *format, ...)
{
return 0;
}
#endif
int main()
{
DebugPrintf("編譯日期與時間: %s,%s\n", __DATE__,__TIME__);
DebugPrintf("當前所在行號:%d\r\n", __LINE__);
DebugPrintf("當前源文件名稱:%s\r\n", __FILE__);
DebugPrintf("當前固件編譯日期:%s\r\n", __DATE__);
DebugPrintf("當前固件編譯時間:%s\r\n", __TIME__);
return 0;
}
四、STM32單片機上封裝printf函數
/*
函數功能: 字符串發送
*/
void USARTx_StringSend(USART_TypeDef *USARTx,u8 *str)
{
while(*str!='\0')
{
USARTx->DR=*str++;
while(!(USARTx->SR&1<<7)){}
}
}
//printf函數底層函數接口
int fputc(int c, FILE* stream)
{
USART1->DR=c;
while(!(USART1->SR&1<<7)){}
return c;
}
/*
函數功能: 格式化打印函數
*/
char USART1_PRINTF_BUFF[1024];
void USART1_Printf(char *fmt,...)
{
va_list ap;
/*1. 初始化形參列表*/
va_start(ap,fmt);
/*2. 提取可變形參數據*/
vsprintf(USART1_PRINTF_BUFF,fmt,ap);
/*3. 結束,釋放空間*/
va_end(ap);
/*4. 輸出數據到串口1*/
USARTx_StringSend(USART1,(u8*)USART1_PRINTF_BUFF);
//USART1_Printf("%d%s",123,454656);
//int data=va_arg(ap,int);
}
USART1_Printf的用法與printf是一樣的,通過這個函數就可以實現數據打印到任意地方,包括改成存儲到SD卡上。
-
單片機
+關注
關注
6035文章
44553瀏覽量
634765 -
C語言
+關注
關注
180文章
7604瀏覽量
136713 -
程序
+關注
關注
117文章
3785瀏覽量
81009
發布評論請先 登錄
相關推薦
評論