stm32新增串列埠除錯
阿新 • • 發佈:2018-12-14
MCU為stm32F103,選擇usart3作為輸出除錯口。
有三種實現方法:
//////////////////////////////////////////
方法一:
1、usart3.c
#if 1 #pragma import(__use_no_semihosting) //標準庫需要的支援函式 struct __FILE { int handle; }; typedef struct __FILE FILE; FILE __stdout; //定義_sys_exit()以避免使用半主機模式 void _sys_exit(int x) { x = x; } //重定義fputc函式 int fputc(int ch, FILE *f) { while ((USART3->SR & USART_FLAG_TC) == 0); //迴圈傳送,直到傳送完畢: USART_FLAG_TC=0x40 USART3->DR = (u8) ch; return ch; } #endif
void Init_USART3(void) { u32 baud = USART_BAUDRATE; USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1ENR_USART3EN | RCC_APB1Periph_USART3, ENABLE); GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //輸入腳 GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; 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_Init(USART3, &USART_InitStructure); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_Cmd(USART3, ENABLE); }
2、define.h 裡面進行巨集定義:
#define DEBUG_OUT //開啟串列埠除錯
#ifdef DEBUG_OUT
#define _MSG_DBG(...) printf(__VA_ARGS__)
#else
#define _MSG_DBG(...)
#endif
3、main裡面進行串列埠初始化和呼叫:
int main(void)
{
Init_USART3();
_MSG_DBG("init ok \r\n");
while(1) {}
}
//////////////////////////////////////////
方法二:
和方法1 一樣,同樣呼叫void Init_USART3(void)和在define.h 裡面進行巨集定義,
不同在於要配置:“魔術棒”=》“Target”=>"MicroLib"。
///重定向c庫函式printf到串列埠,重定向後可使用printf函式
int fputc(int ch, FILE *f)
{
/* 傳送一個位元組資料到串列埠 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);
/* 等待發送完畢 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
///重定向c庫函式scanf到串列埠,重寫向後可使用scanf、getchar等函式
int fgetc(FILE *f)
{
/* 等待串列埠輸入資料 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}
//////////////////////////////////////////
方法三:
1、usart3.c
只需要上面的 void Init_USART3(void)部分的程式碼,再加上:
void USART3_PutChar(char ch)
{
while ((USART3->SR & USART_FLAG_TC) == 0); //迴圈傳送,直到傳送完畢
USART3->DR = (u8) ch;
}
2、Retarget.c
#if defined(DEBUG_ENABLE)
#if DEBUG_OUTPUT==DEBUG_UART1
void USART1_PutChar(char ch);
#define PUT_CHART(c) USART1_PutChar(c)
#elif DEBUG_OUTPUT==DEBUG_UART2
void USART2_PutChar(char ch);
#define PUT_CHART(c) USART2_PutChar(c)
#elif DEBUG_OUTPUT==DEBUG_UART3
void USART3_PutChar(char ch);
#define PUT_CHART(c) USART3_PutChar(c)
#endif
static inline void BoardOutChar(char ch)
{
PUT_CHART(ch);
}
int fputc(int c, FILE *f)
{
#if defined(DEBUG_ENABLE)
BoardOutChar((char) c);
#endif
return 0;
}
3、define.h 裡面進行巨集定義:
#define NO_DEBUG 0
#define DEBUG_UART1 1
#define DEBUG_UART2 2
#define DEBUG_UART3 3
#define DEBUG_ENABLE
#define DEBUG_OUTPUT DEBUG_UART3
#if DEBUG_OUTPUT!=NO_DEBUG && DEBUG_ENABLE
#define _MSG_DBG(...) printf(__VA_ARGS__)
#else
#define _MSG_DBG(...)
#endif