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