51单片机printf重定向

在这里插入图片描述
从keil的帮助文档里我们可以看到,printf是基于putchar实现的,所以我们只要重新实现putchar,就可以实现printf的重定向,即可以将printf用在其他串口上。

putchar的函数实现在…/C51/LIB下可以找到。

#include <reg51.h>

#define XON  0x11
#define XOFF 0x13


/*
 * putchar (full version):  expands '\n' into CR LF and handles
 *                          XON/XOFF (Ctrl+S/Ctrl+Q) protocol
 */

char putchar (char c)  {

  if (c == '\n')  {
    if (RI)  {
      if (SBUF == XOFF)  {
        do  {
          RI = 0;
          while (!RI);
        }
        while (SBUF != XON);
        RI = 0; 
      }
    }
    while (!TI);
    TI = 0;
    SBUF = 0x0d;                         /* output CR  */
  }
  if (RI)  {
    if (SBUF == XOFF)  {
      do  {
        RI = 0;
        while (!RI);
      }
      while (SBUF != XON);
      RI = 0; 
    }
  }
  while (!TI);
  TI = 0;
  return (SBUF = c);
}

我们来分析一下代码,首先我们先不管那两个if判断,putchar函数总是要执行的语句其实只有三句,首先先等待上一个数据发送完毕,将标志位置零以后,再发送下一个数据。这也解释了为什么我们在第一次调用printf函数时要先把TI置1,因为STC单片机复位以后TI的值为0,直接调用printf函数就会一直卡死在while(!TI)里面了。

while(!TI);
TI = 0;
return (SBUF = c);

if(c == '\n')部分是判断是否接收到换行符,如果接收到换行符以后,就会输出CR+LF。SBUF = 0X0d是在输出CR,推测LF是在putchar函数之外输出的。

最后if(RI)部分是软件流控制。当接收端数据缓存区满了以后,就会向发送端发送XOFF标志,发送端接收到XOFF以后停止发送数据。接收端处理完数据以后,会向发送端发送XON标志,表示可以继续发送数据。

使用流控制可以有效的防止数据传输过程中的丢失情况。

分析完官方的putchar函数以后,我们需要自己写一个putchar函数来调用串口3,这里要说明一下,如果我们的工程中包含了putchar函数,编译器会优先使用我们所定义的函数,而不会去使用…/C51/LIB下的putchar函数。

下面是我写的putchar函数,因为没有那么高的要求,所以我并没有使用流控制,其次我的代码是先发送数据,再检测标志位,我认为这样做更符合我们平时的使用习惯。

char putchar(char c)
{
    if (c == '\n')
    {
        S3BUF = 0x0d;
        while (!(S3CON & S3TI));  //等待发送成功
        S3CON &= ~S3TI;
        /* output CR  */
    }
    S3BUF = c;
    while (!(S3CON & S3TI));	//等待发送成功
    S3CON &= ~S3TI;	  //清除发送中断标志
    return c;
}

我们只需要将这个putchar函数包含在工程中,然后初始化串口3,便可以利用printf打印串口了。

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值