打印
[应用相关]

STM32:UART-printf,scanf重定向

[复制链接]
1676|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);  
}

使用特权

评论回复
5
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);
}

使用特权

评论回复
6
modesty3jonah| | 2024-5-4 22:02 | 只看该作者
与fputc类似,fgetc函数负责从文件中读取一个字符。要实现scanf的重定向,你需要修改fgetc函数,使其能够从USART接收数据。这通常涉及到使用USART的接收函数,如USART_ReceiveData。

使用特权

评论回复
7
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

使用特权

评论回复
8
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);
}

使用特权

评论回复
9
louliana| | 2024-5-6 20:57 | 只看该作者
要实现printf和scanf的重定向,我们需要包含stdio.h头文件,并定义_write和_read函数。这两个函数分别用于数据的发送和接收。

使用特权

评论回复
10
juliestephen| | 2024-5-7 18:32 | 只看该作者
在STM32中,可以通过重定向标准输入输出(stdin和stdout)来实现UART的printf和scanf功能。

使用特权

评论回复
11
uytyu| | 2024-5-8 12:57 | 只看该作者
在重定向printf之前,不要调用任何依赖于这些函数的C库函数,以避免未定义的行为。

使用特权

评论回复
12
earlmax| | 2024-5-8 18:47 | 只看该作者
对于scanf,由于它是阻塞性的,并且UART接收是异步的,因此你可能需要实现一个非阻塞版本的scanf或使用其他方法(如中断)来处理UART接收。

使用特权

评论回复
13
Henryko| | 2024-5-8 21:50 | 只看该作者
这个非阻塞方式怎么实现啊

使用特权

评论回复
14
sdlls| | 2024-5-8 22:22 | 只看该作者
为了重定向printf的输出到USART,你需要修改fputc函数。这个函数负责将一个字符写入到文件指针所指向的文件。

使用特权

评论回复
15
deliahouse887| | 2024-5-10 14:56 | 只看该作者
在多任务环境中,重定向的 fputc 和 fgetc 需要考虑线程安全。

使用特权

评论回复
16
eefas| | 2024-5-10 19:04 | 只看该作者
我们调用了HAL_UART_Transmit函数来发送数据。huart1是UART接口的句柄,ptr是要发送的数据指针,len是数据的长度。

使用特权

评论回复
17
sesefadou| | 2024-5-10 22:42 | 只看该作者
要在工程选项中勾选“Use MicroLIB”。MicroLIB是一个对标准C库进行了优化的库,它可以减少代码量和资源占用。

使用特权

评论回复
18
jimmhu| | 2024-5-12 13:22 | 只看该作者
在STM32上使用printf和scanf函数,并且它们应该通过UART进行通信。

使用特权

评论回复
19
Bowclad| | 2024-5-12 20:25 | 只看该作者
用sprintf构建字符串再发送也行

使用特权

评论回复
20
mikewalpole| | 2024-5-13 20:00 | 只看该作者
可以在STM32的程序中使用printf和scanf函数来进行数据的发送和接收了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15650

帖子

12

粉丝