1. 程式人生 > >基於AT89C52和串列埠通訊助手的串列埠通訊

基於AT89C52和串列埠通訊助手的串列埠通訊

我們要實現的功能是在程式執行的時候通過微控制器的串列埠向串列埠除錯助手傳送一個字串諸如“hello world”,串列埠通訊助手接收到字串之後顯示並由使用者反饋回去一個長度為4的字串並顯示到數碼管上

來看一下效果

這裡寫圖片描述

首先是串列埠通訊電路的配置和藉助VSPD、串列埠通訊助手對相關串列埠的設定

  • 通過VSPD建立兩個可以相互通訊的虛擬串列埠,如COM1和COM2。點選新增埠按鈕後,可以看到左邊欄中的虛擬埠處看到你新建立的兩個虛擬埠。
  • 開啟串列埠除錯助手V2.2,對其進行配置,將串列埠改為COM2埠,波特率設為9600,校驗位選擇NONE,資料位為8位,停止位為1位
  • 電路圖中的配置:首先將晶振改為11.0592MHZ,再將AT89C52晶片中的晶振也改為11.0592MHZ。再配置串列埠,將物理埠設定為COM1,物理波特率設定為9600,物理資料位數設為8位,物理奇偶校驗位設定為NONE,下面的虛擬波特率、虛擬資料位數和虛擬奇偶校驗位與上面相同。
  • 接下來上電路圖

    這裡寫圖片描述

    用VSPD建立兩個虛擬埠

    這裡寫圖片描述

    可以通過裝置管理器來檢視串列埠是否建立成功

    這裡寫圖片描述

    AT89C52的相關配置

    這裡寫圖片描述

    對COMPIM的相關配置

    這裡寫圖片描述

    一些埠的設定

    這裡寫圖片描述

    硬體配置的差不多了,接下來我們看看如何在Keil裡編寫程式碼實現,這裡僅摘錄一些比較重要的程式碼片段,感興趣的可以[下載程式碼](http://download.csdn.net/detail/lrwwll/9720330)

    /*數碼管顯示函式,利用74HC595實現序列輸入並行輸出*/
    void ser_inout(uchar datas)      
    {
        uchar i;                                                //迴圈控制變數
    STCP = 0; //P2.6引腳置0 for(i = 0 ; i < 8 ; i++) //for迴圈,從高位到低位,依次傳送資料 { SHCP = 0; //P2.7引腳置0 if( (datas & 0x80) == 0) //如果最高位資料等於0 { DS
    = 0; //傳遞資料0給P2.5引腳 } else { DS = 1; //如果最高位資料不等於0,傳遞資料1給P2.5引腳 } datas <<= 1; //將傳輸的8位資料左移一位 SHCP = 1; //P2.7引腳置1,產生上升沿,將P2.5引腳上的資料傳入74HC595 } STCP = 1; //P2.6置1,產生上升沿,送八位資料 }
    /*動態顯示函式,數碼管動態顯示資料*/
    void Display()
    { 
        uint i = 0;                                            //i是迴圈控制變數 
      while( i!=900 )                                        //while迴圈,迴圈90次,讓數碼管動態顯示資料約1.5S
        {
          ser_inout(table[show[0]]);                            //將最高位資料送入數碼管
        wx0 = 0;                                              //選中第一個數碼管,低電平有效  
        delay_ms(1);                                          //延時1ms
        wx0 = 1;                                              //取消位選
    
          ser_inout(table[show[1]]);                            //將第二位資料送入數碼管  
        wx1 = 0;                                                //選中第二個數碼管,低電平有效
        delay_ms(1);                                          //延時1ms
        wx1 = 1;                                              //取消位選
    
          ser_inout(table[show[2]]);                            //將第三位資料送入數碼管
        wx2 = 0;                                                //選中第三個數碼管,低電平有效 
          delay_ms(1);                                          //延時1ms
        wx2 = 1;                                              //取消位選
    
        ser_inout(table[show[3]]);                            //將第四位資料送入數碼管
        wx3 = 0;                                                //選中第四個數碼管,低電平有效 
          delay_ms(1);                                          //延時1ms
        wx3 = 1;                                              //取消位選  
          i++;                                                  //i加1
        }       
    }
    
    /*輸出函式,通過數碼管顯示相應資料*/
    void printf(uchar dat[])                                    //dat儲存要顯示的資料
    {
        uint i = 0;                                            //迴圈控制變數
        for(i = 4;i > 0;i--)                                    //迴圈4次,將要顯示的資料儲存在show陣列中
        {
            show[4-i]=dat[4-i];
      }
        Display();                                              //呼叫動態顯示函式,讓數碼管動態顯示資料
    }
    /*串列埠通訊相關初始化*/
    void init()
    {
        TMOD=0X20;                                              //設定定時器1方式2
        TH1=0XFD;                                               //設定波特率為9600
        TL1=0XFD;                                               //同上
        SCON=0X50;                                              //將序列口控制暫存器設定為序列口工作方式1並允許中斷接收資料
        PCON&=0XEF;                                             //波特率不倍增
        TR1=1;                                                  //啟動定時器1
        IE=0X0;                                                 //禁止任何中斷
    }
    /*微控制器串列埠傳送一個字元*/
    void send(uchar txd)
    {
        SBUF=txd;
        while(!TI);
        TI=0;
    }
    
    /*微控制器串列埠傳送一個字串*/
    void send_buf(uchar dat[])
    {
        uint i=0;
        while(dat[i]!='\0')
        {
            send(dat[i]);
            i++;
        }
    }

    一些解釋

  • SCON=0x50:
    SCON是序列口控制暫存器,0x50為16進位制,轉換成二進位制是01010000,對應下附表各位,即將序列口控制暫存器設定為序列口工作方式1並允許中斷接收資料.
    附:scon暫存器結構表
    SCON SM0 SM1 SM2 REN TB8 RB8 TI RI
    位地址 9FH 9EH 8DH 9CH 9BH 9AH 99H 98H
  • TMOD=0x20: TMOD是定時/計數器方式控制暫存器,所以TMOD=0x20是將定時/計數器1設定為工作方式2.
  • TH1=0xE8,TL1=0xE8:
    給定時/計數器1裝初值,即確定定時時長,具體時間與晶振有關.
  • TI=1,TR=1:
    由上附表可得,TI和RI是SCON暫存器的最低兩位.TI:傳送中斷標誌位 ,RI:接收中斷標誌位. TI=1表示幀傳送結束,RI=1表示幀接收完成.