STM32輸出除錯資訊-printf重定向到串列埠
阿新 • • 發佈:2019-01-31
在STM32除錯過程中常常需要將除錯資訊輸出到串列埠,然後通過串列埠助手檢視輸出的除錯資訊。一般來說,串列埠輸出的是指定長度的十六進位制位元組,對於想列印的除錯資訊來
說,略顯靈活性不足。這時候如果可以將printf重定向到串列埠輸出,則能很好的解決這個問題。
關於printf重定向的方法有很多種,這裡只討論一種我認為相對簡單實用的方法。其主要方法步驟如下:
1、配置STM32的串列埠,確保STM32能輸出資料到串列埠除錯助手。
2、新增printf標頭檔案#include <stdio.h>void USART5_Init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD |RCC_APB2Periph_AFIO , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure the USART1_Rx as input floating GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //Enable rx enable, USART_ClearFlag(UART5, USART_IT_RXNE); /* Configure the USARTx */ USART_Init(UART5, &USART_InitStructure); /* Enable the USARTx */ USART_Cmd(UART5, ENABLE); }
3、點選Keil中小魔術棒Target頁勾選Use MicroLIB。
注:這個步驟必須有,否則程式碼編譯通過後,進行模擬時會卡住,進入不了Main函式。printf、malloc等標準庫函式在工程建立時,不勾選Use MicroLIB就會引起這類問題。
至此,就可以通過printf列印除錯資訊到串列埠助手了。
接下來關於輸出除錯資訊再補充兩點。
1、printf輸出指定長度的字串。
格式為printf("%.*s\n",strlen,str);
2、列印十六進位制資料。printf("指定長度字串:%.*s\n",strlen,str); //列印指令長度位元組串
當我們使用串列埠除錯助手檢視輸出資訊,如果我們檢視的資料是十六進位制型別,我們會勾選除錯助手中的Hex顯示選項。這時當資料量很大時,我們可能需要附加一些可見字元的說明,比如英文或者中文,這時在Hex顯示下,這些字元辨識度比較低,甚至是亂碼,printf輔助列印除錯資訊目的作用不大。這裡可以選擇一種方法,電腦串列埠助手不勾選Hex選項,而將要顯示的十六進位制資料轉為可見的ASCII碼格式。
如下為指定長度的十六進位制資料轉化為字串的函式:
/********************************************************** *函式功能:將十六進位制資料轉為字串格式 *參 數:In,十六進位制資料;Len十六進位制資料長度 * Out,輸出字串 *返 回 值:無 **********************************************************/ void HexToString(char *Out,char *In,char Len){ long i; char Temp; for(i=0;i<Len;i++) { Temp = In[i]>>4; if(Temp>9)Out[2*i] = Temp + 'A' - 10; else Out[2*i] = Temp + '0'; Temp = In[i] & 0x0F; if(Temp>9)Out[2*i+1] = Temp + 'A' - 10; else Out[2*i+1] = Temp + '0'; } Out[2*i] = 0; }
此時再呼叫printf即可打印出清晰的除錯資訊:
HexToString(DebugData,(char *)buffer,bufferlen);
printf("NTP傳送:\n%s\r\n",DebugData);
以上步驟根據除錯成功後的結果總結。