打印
[方案相关]

对printf和scanf的实现

[复制链接]
183|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
deliahouse887|  楼主 | 2023-12-23 14:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.printf函数在格式化输出时,向下调用了char putchar(char c);这个函数,在“stdio.h”里可以发现有这个函数,所以我们需要自己构造一个这样的函数,即通过串口putchar(),代码如下:

char putchar(char c)  

{  

    hal_uart_putchar(c);  

    return c;  

}  

        其中hal_uart_putchar(c);函数是我们比较熟悉的了,是51单片机通过串口发送一个字节的函数,具体代码如下:

void hal_uart_putchar(char i)  

{  



}  

        有了这两个函数,在单片机启动后,首先进行串口初始化,接着就可以使用printf了……是不是很简单……

-------------------------------------------------------------------------------------------------------------------------------------

        2.下面再看scanf的具体实现方法:

        scanf函数在格式化输入时,向下调用了char getkey(void);这个函数,在“stdio.h”里可以发现有这个函数,所以我们需要自己构造一个这样的函数,即通过串口getkey(),代码如下:

char _getkey (void)   

{  

    return hal_uart_getchar();  

}  

其中hal_uart_getchar(); 稍稍复杂,但也很好理解,代码如下:

char hal_uart_getchar(void)  

{  

    uchar ch;  

    //Wait until a character is available:   

    while(uart_rx_cnt == 0);  

    ES = 0;  

    ch = uart_rx[uart_rx_rp];  

    uart_rx_rp = (uart_rx_rp + 1) % UART_BUF_SIZE;  

    uart_rx_cnt--;  

    ES = 1;  

    return ch;  

}  

这个函数是从串口接收队列中取出队尾的一个字节。uart_rx_cnt 表示现在串口队列中的已有字节数,uart_rx_rp 指向队尾。

最后要介绍的一个函数是串口接收中断函数,代码如下:

void UART1InterruptReceive(void) interrupt 4  

{  

    ES=0;//关串行口中断   

    if(RI)  

    {  

        RI=0;//接收中断信号清零,表示将继续接收   

        if(uart_rx_cnt < UART_BUF_SIZE)  

        {  

            uart_rx[uart_rx_wp] = SBUF;  

            uart_rx_wp = (uart_rx_wp + 1) % UART_BUF_SIZE;  

            uart_rx_cnt++;  

        }  

    }   

    ES=1;//开串行口中断   

}  

该函数实现了串口的中断接收,收到的新的字节存放在队首,即uart_rx_wp指向队列的首地址,每次收到一个新的字节,uart_rx_cnt增1。

至此,scanf函数也可以实现了。

使用特权

评论回复
沙发
华大MCU代理| | 2023-12-25 10:12 | 只看该作者
感谢分享

使用特权

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

本版积分规则

12

主题

1014

帖子

0

粉丝