立即注冊(cè) 登錄
返回首頁

uid:90541的個(gè)人空間

日志

51模擬串口

熱度 1已有 491 次閱讀2015-9-19 17:21 |個(gè)人分類:51

#include <reg51.h>   
       
    #define uchar unsigned char   
    #define uint    unsigned int   
       
    sbit Tx_Pin = P1^1;   
    sbit Rx_Pin = P1^2;         //定義接收、發(fā)送引腳   
       
    /*******************************************  
    I/O口模擬232通訊程序  
    使用兩種方式的C程序 占用定時(shí)器0  
      
    /******************************************/   
       
    #define MODE                                                    //定義工作模式,決定使用哪種算法   
    #define Flg F0                                              //標(biāo)志位,使用PSW的F0位   
    #define Start_Timer0 TL0=TH0;TR0=1;     //定時(shí)計(jì)數(shù)器0的啟動(dòng)處理   
    #define Close_Timer0 TR0=0;                     //定時(shí)計(jì)數(shù)器0的關(guān)閉處理   
       
    sbit ACC0 = ACC^0;   
    sbit ACC1 = ACC^1;   
    sbit ACC2 = ACC^2;   
    sbit ACC3 = ACC^3;   
    sbit ACC4 = ACC^4;   
    sbit ACC5 = ACC^5;   
    sbit ACC6 = ACC^6;   
    sbit ACC7 = ACC^7;   
       
    void Timer0() interrupt 1                           //定時(shí)計(jì)數(shù)器中斷處理   
    {   
        Flg = 1;                                                        //置位標(biāo)志位   
    }   
       
    //發(fā)送一個(gè)字符   
    void SendByte(uchar adata)   
    {   
        #ifdef MODE                                                 //算法一   
            ACC = adata;                                                //待發(fā)送數(shù)據(jù)放入ACC   
            Flg = 0;   
            Tx_Pin = 0;                                             //啟動(dòng)位   
            Start_Timer0;                                           //啟動(dòng)定時(shí)器   
            while(!Flg)   
                ;   
            Tx_Pin = ACC0;                                      //先送出低位   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC1;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC2;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC3;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC4;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC5;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC6;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC7;   
            Flg = 0;   
            while(!Flg)                                             //停止位   
                ;   
            Tx_Pin = 1;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Close_Timer0;                                           //停止定時(shí)計(jì)數(shù)器   
        #else                                                               //第二種算法   
        uchar j;   
        j = 0;                                                             
        Flg = 0;                                                        //初始化   
        Tx_Pin = 0;                                                 //起始位   
        Start_Timer0;                                               //啟動(dòng)定時(shí)計(jì)數(shù)器   
        while(!Flg)   
            ;   
        while(j<8)                                                   //如果沒有發(fā)送完一個(gè)字節(jié)   
        {   
            if(adata&1)                                             //如果待發(fā)送位是1   
            {   
                Tx_Pin = 1;   
            }   
            else                                                            //如果待發(fā)送位是0   
            {   
                Tx_Pin = 0;   
            }   
            Flg = 0;   
            while(!Flg)   
                ;   
            j++;   
            adata>>=1;                                                    //移位   
        }   
        Tx_Pin = 1;   
        Flg = 0;   
        while(!Flg)                                                 //停止發(fā)送   
            ;      
        #endif   
        Close_Timer0;                                               //停止定時(shí)計(jì)數(shù)器   
    }   
       
    //接收一個(gè)字符       
           
    uchar RecByte()   
    {   
        #ifdef MODE                                                 //算法一   
        Start_Timer0;   
        Flg = 0;   
        while(!Flg)                                                 //等待起始位   
            ;   
        ACC0 = Rx_Pin;                                          //接收一位數(shù)據(jù)   
        TL0 = TH0;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC1 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC2 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC3 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC4 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC5 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC6 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC7 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)                                                 //等待停止位   
        {   
            if(Rx_Pin)   
            {   
                break;   
            }   
        }   
        Close_Timer0;                                               //停止timer    
        return ACC;                                                 //函數(shù)返回值通過ACC寄存器傳遞   
        #else                                                               //第二種算法   
        uchar Rx_Data, j;   
        Start_Timer0;   
        Flg = 0;   
        j = 0;   
        Rx_Data = 0;                                                //等待起始位   
        while(!Flg)                                                    
            ;   
        while(j<8)   
        {   
            Rx_Data>>=1;   
            if(Rx_Pin)   
            {   
                Rx_Data |= 0x80;                                //判斷引腳電平   
            }   
            j++;   
            Flg = 0;   
            while(!Flg)   
                ;   
        }   
        Flg = 0;   
        while(!Flg)   
        {   
            if(Rx_Pin)   
            {   
                break;   
            }   
        }   
        Close_Timer0;                                               //停止定時(shí)計(jì)數(shù)器   
        return Rx_Data;   
        #endif   
    }   
           
    //檢查是不是起始位   
    bit CheckStartBit()   
    {   
        return (Rx_Pin == 0);                               //返回引腳狀態(tài)   
    }   
       
    void main()   
    {   
        uchar temp;   
        TMOD = 0x02;                                                //定時(shí)器0 模式2 8位重裝   
        PCON = 0x00;   
        TR0 = 0;                                                            //在發(fā)送或接收才開始使用   
        TH0 = (256.96);                                            
        //9600bps 就是1000000/9600=104.167us 執(zhí)行時(shí)間即是104.167*10.0592/12=96   
        TL0 = TH0;   
        ET0 = 1;   
        EA = 1;   
        SendByte(0x55);   
        SendByte(0xaa);   
        SendByte(0x00);   
        SendByte(0xff);                                         //發(fā)送數(shù)據(jù)   
        while(1)   
        {   
            if(CheckStartBit())                             //如果檢測(cè)到起始位   
            {   
                temp = RecByte();                               //接收數(shù)據(jù)   
                SendByte(temp);                                 //發(fā)送數(shù)據(jù)   
            }   
        }   
    }   


1

路過

雞蛋

鮮花

握手

雷人

剛表態(tài)過的朋友 (1 人)

評(píng)論 (0 個(gè)評(píng)論)

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

返回頂部