[应用相关] STM32:UART-printf,scanf重定向

[复制链接]
2987|25
 楼主| tpgf 发表于 2024-4-30 17:30 | 显示全部楼层 |阅读模式

在C 语言标准库中,fputc 函数是printf 函数内部的一个函数,功能是将字符ch 写入到文件指针file所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART 函数重新修改fputc 函数内容,达到类似“写入”的功能。fgetc 函数与fputc 函数非常相似,实现字符读取功能。在使用scanf 函数时需要注意字符输入格式。还有一点需要注意的,使用fput 和fgetc 函数达到重定向C 语言标准库输入输出函数必须在MDK的工程选项把“Use MicroLIB”勾选上,MicoroLIB 是缺省C 库的备选库,它对标准C 库进行了高度优化使代码更少,占用更少资源。

//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t) ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    return (ch);
}
//重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    return (int)USART_ReceiveData(USART1);
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/ZipingPan/article/details/137313753

xixi2017 发表于 2024-4-30 21:11 | 显示全部楼层
是不是用I2C也可以使用这个接口?
olivem55arlowe 发表于 2024-5-1 22:09 | 显示全部楼层
要重定向 printf 到串口,你需要自定义 fputc 函数。fputc 是 C 标准库中用来输出单个字符的函数,而 printf 最终会调用 fputc 来输出每一个字符。
adolphcocker 发表于 2024-5-2 14:39 | 显示全部楼层
int fputc(int ch, FILE *f) {  
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); // 假设你使用的是huart1  
    return (ch);  
}
mattlincoln 发表于 2024-5-3 12:58 | 显示全部楼层
#include<stdio.h>

int fputc(int ch, FILE *f) {
    USART_SendData(USART1, (uint8_t) ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    return ch;
}

int fgetc(FILE *f) {
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    return (int) USART_ReceiveData(USART1);
}
modesty3jonah 发表于 2024-5-4 22:02 | 显示全部楼层
与fputc类似,fgetc函数负责从文件中读取一个字符。要实现scanf的重定向,你需要修改fgetc函数,使其能够从USART接收数据。这通常涉及到使用USART的接收函数,如USART_ReceiveData。
earlmax 发表于 2024-5-6 09:05 | 显示全部楼层
#ifdef __GNUC__  
    // 使用GNU编译器时,将fputc重定向到UART  
    #define fputc my_fputc  
    int my_fputc(int ch, FILE *f) {  
        // ... 同上面的fputc实现 ...  
    }  
#else  
    // 对于其他编译器,可能需要不同的方法  
#endif
macpherson 发表于 2024-5-6 15:51 | 显示全部楼层
/ 重定向函数
int fputc(int ch, FILE *stream)
{
    if (ch == '\n')
    {
        HAL_UART_Transmit(UART_HANDLE, (uint8_t *)" ", 1, HAL_MAX_DELAY);
    }
    return HAL_UART_Transmit(UART_HANDLE, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
}
louliana 发表于 2024-5-6 20:57 | 显示全部楼层
要实现printf和scanf的重定向,我们需要包含stdio.h头文件,并定义_write和_read函数。这两个函数分别用于数据的发送和接收。
juliestephen 发表于 2024-5-7 18:32 | 显示全部楼层
在STM32中,可以通过重定向标准输入输出(stdin和stdout)来实现UART的printf和scanf功能。
uytyu 发表于 2024-5-8 12:57 | 显示全部楼层
在重定向printf之前,不要调用任何依赖于这些函数的C库函数,以避免未定义的行为。
earlmax 发表于 2024-5-8 18:47 | 显示全部楼层
对于scanf,由于它是阻塞性的,并且UART接收是异步的,因此你可能需要实现一个非阻塞版本的scanf或使用其他方法(如中断)来处理UART接收。
Henryko 发表于 2024-5-8 21:50 | 显示全部楼层
这个非阻塞方式怎么实现啊
sdlls 发表于 2024-5-8 22:22 | 显示全部楼层
为了重定向printf的输出到USART,你需要修改fputc函数。这个函数负责将一个字符写入到文件指针所指向的文件。
deliahouse887 发表于 2024-5-10 14:56 | 显示全部楼层
在多任务环境中,重定向的 fputc 和 fgetc 需要考虑线程安全。
eefas 发表于 2024-5-10 19:04 | 显示全部楼层
我们调用了HAL_UART_Transmit函数来发送数据。huart1是UART接口的句柄,ptr是要发送的数据指针,len是数据的长度。
sesefadou 发表于 2024-5-10 22:42 | 显示全部楼层
要在工程选项中勾选“Use MicroLIB”。MicroLIB是一个对标准C库进行了优化的库,它可以减少代码量和资源占用。
jimmhu 发表于 2024-5-12 13:22 | 显示全部楼层
在STM32上使用printf和scanf函数,并且它们应该通过UART进行通信。
Bowclad 发表于 2024-5-12 20:25 | 显示全部楼层
用sprintf构建字符串再发送也行
mikewalpole 发表于 2024-5-13 20:00 | 显示全部楼层
可以在STM32的程序中使用printf和scanf函数来进行数据的发送和接收了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2384

主题

17635

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部