为什么printf函数输出到串口需要调用FPUTC函数
时间: 2023-06-20 12:06:01 浏览: 582
在嵌入式系统中,printf函数通常是通过串口输出调试信息,而printf内部是通过标准输出流来输出字符的。但是,标准输出流并不是直接输出到串口的,而是输出到一个缓冲区中,等到缓冲区满了或者调用fflush函数时才会将缓冲区中的内容输出到串口。
因此,为了将printf函数的输出直接输出到串口,需要重定向标准输出流,并实现FPUTC函数。FPUTC函数将每个字符直接输出到串口,而不是先输出到缓冲区。这样,每次调用printf函数时,输出的字符就会直接输出到串口。
相关问题
stm32printf函数的串口输出
stm32printf函数可以用来在STM32微控制器上通过串口输出数据。具体步骤如下:
1. 首先需要在代码中引入相关的库文件,如下:
#include "stdio.h"
#include "string.h"
#include "stdarg.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
2. 然后需要进行串口的初始化,如下:
void USART_Config(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_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_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
3. 接下来就可以使用stm32printf函数进行输出了,如下:
void stm32printf(const char* fmt, ...)
{
char buf[256];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
int len = strlen(buf);
for (int i = 0; i < len; i++) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, buf[i]);
}
}
4. 最后在需要输出的地方调用stm32printf函数即可,如下:
stm32printf("Hello, world!\r\n");
注意事项:
1. 如果使用printf函数进行输出,则需要在上面的代码中添加以下语句进行重定向:
int fputc(int ch, FILE* f)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, (uint8_t)ch);
return ch;
}
2. 在使用stm32printf函数进行输出时,需要注意串口的波特率和串口接口的配置要与代码中的配置相符。
kei5 printf函数
在Keil开发环境下,要使用printf函数进行输出,需要将printf函数的输出重新定向到UART上,然后使用串口调试助手接收打印信息。具体操作可以参考以下代码:
在Retartget.c文件中,需要包含stdio.h、time.h和rt_misc.h头文件,并加入以下代码:
```c
#pragma import(__use_no_semihosting_swi)
extern int sendchar(int ch); /* 在Serial.c文件中实现,用于发送字符到串口 */
extern int getkey(void); /* 在Serial.c文件中实现,用于从串口接收字符 */
extern long timeval; /* 在Time.c文件中实现 */
struct __FILE
{
int handle; /* 可根据需要在此添加其他成员 */
};
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
return (sendchar(ch));
}
int fgetc(FILE *f)
{
return (sendchar(getkey()));
}
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
sendchar(ch);
}
void _sys_exit(int return_code)
{
while (1);
}
```
同时,将串口的输出连接到这两个函数。假设使用UART0作为输出通道,可以在sendchar和getkey函数中实现与UART0的交互,发送和接收字符。
```c
int sendchar(int ch)
{
UART0_SendByte(ch); // 通过UART0发送字符
return(ch);
}
int getkey(void)
{
return (int)UART0_GetChar(); // 通过UART0接收字符
}
```
这样,就可以在Keil开发环境下使用printf函数进行输出,并通过串口线将输出连接到电脑的串口调试助手来查看打印信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *3* [Keil调用printf函数](https://blog.csdn.net/u012778549/article/details/80359081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"]
- *2* [KEIL编程中如何重定义printf()函数,以便在后来的开发中使用此函数进行串口数据输出](https://blog.csdn.net/weixin_41020947/article/details/86611548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"]
[ .reference_list ]
阅读全文