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打印串口了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章