新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機軟件用定時器模擬串口程序

        51單片機軟件用定時器模擬串口程序

        作者: 時間:2016-11-30 來源:網絡 收藏
        模擬串口定時器完成,每一個串口要占用一個定時器,發送很好辦,每次定時器中斷(1BIT的時間)傳送一個Bit,接收就要你好好處理了,這個我模擬的一個串口,用的W77E58,實際工作時只用到了半雙工。


        //使用硬件:定時器0,定時器0中斷,定時器1中斷,外中斷5
        //波特率 9600 4800 2400 1200 600 300
        //每BIT周期數9696*2 96*4 96*8 96*16 96*32
        //以96為單位不同的波特率選用不同的倍率
        //如果對方在每位的1/2處采樣,則發送中斷的響應時間最多是48個時鐘周期
        //也許可以置發送中斷以較高的優先級來解決,實驗表明發送可以工作于9600
        //但若有其它中斷,并且串口工作于全雙工,則晶體頻率最好是22.1184以上
        //!!實測表明當用11.0592時鐘,標準51,收發同時,最高只能到2400波特。
        //但單發可以工作于9600
        #define BAUD_RATE 300
        //#define BAUD_RATE 600
        //#define BAUD_RATE 1200
        //#define BAUD_RATE 2400
        //#define BAUD_RATE 4800
        //#define BAUD_RATE 9600

        #define clock 110592
        //#define clock 221184


        #define RELOAD(TIMER,SVALUE) TIMER+=SVALUE+1

        bit tTI;
        bit rRI;

        unsigned char rSBUF;
        unsigned char tSBUF;

        unsigned char rSBUF0;
        unsigned char RxdCnt;
        unsigned char rSmpCnt;

        unsigned char TxdCnt;
        unsigned char tSmpCnt;
        unsigned char multiple;
        //-----------------------------------------------------------

        void SimuUARTinit(void)
        {
        #if BAUD_RATE==300
        if(clock==110592)
        multiple=32;
        else if(clock==221184)
        multiple=64;
        #endif
        #if BAUD_RATE==600
        if(clock==110592)
        multiple=16;
        else if(clock==221184)
        multiple=32;
        #endif
        #if BAUD_RATE==1200
        if(clock==110592)
        multiple=8;
        else if(clock==221184)
        multiple=16;
        #endif
        #if BAUD_RATE==2400
        if(clock==110592)
        multiple=4;
        else if(clock==221184)
        multiple=8;
        #endif
        #if BAUD_RATE==4800
        if(clock==110592)
        multiple=2;
        else if(clock==221184)
        multiple=4;
        #endif
        #if BAUD_RATE==9600
        if(clock==110592)
        multiple=1;
        else if(clock==221184)
        multiple=2;
        #endif
        tTI=1;
        tTXD=1;
        rRXD=1;

        TMOD&=0xf0;
        TMOD|=0x03;
        ET0=1;
        ET1=1;
        TR0=1;
        IT0=1;
        EX0=1;
        TR1=1;
        PT1=1; //置串口發送為高優先級
        EA=1;
        }
        //-----------------------------------------------------------
        //模擬串口發送中斷,原定時器1中斷
        void IntTH0(void) interrupt 3
        {
        RELOAD(TH0,-96);
        if(--tSmpCnt == 0)
        {
        tSmpCnt=multiple;
        if(tTI) return;
        switch(TxdCnt++)
        {
        case 0:
        tTXD=0;
        break;
        case 9:
        tTXD=1;
        tTI=1;
        TxdCnt=0;
        break;
        default:
        tTXD=tSBUF&0x01;
        tSBUF>>=1;
        break;
        }
        }
        }
        //-----------------------------------------------------------
        void RxdInt0(void) interrupt 0
        {
        TL0=-96+4; //The time of inter interrup
        ET0=1;
        TF0=0;
        rSmpCnt=multiple/2;
        }
        //----------------------------------------------------------
        //模擬串口接收中斷,原定時器0中斷
        void IntTL0(void) interrupt 1
        {
        RELOAD(TL0,-96);

        if(--rSmpCnt == 0)
        {
        rSmpCnt=multiple;
        switch(RxdCnt++)
        {
        case 0:
        if(rRXD==1){RxdCnt=0;}//ET0=0 added,no startbitfound then stop interrup
        break;
        case 9:
        RxdCnt=0;
        if(rRXD==0) return;
        rSBUF=rSBUF0;
        rRI=1;
        break;
        default:
        if(RxdCnt>9){ RxdCnt=0;return;}
        rSBUF0>>=1;
        rSBUF0|=rRXD?0x80:0;
        break;
        }
        }
        }
        //-----------------------------------------------------------


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 房产| 张家界市| 河源市| 长白| 二手房| 旬邑县| 湖南省| 太保市| 徐州市| 崇仁县| 铜梁县| 嘉鱼县| 剑河县| 广灵县| 张家港市| 辰溪县| 乐平市| 海林市| 建德市| 岢岚县| 城固县| 叙永县| 永城市| 穆棱市| 雅安市| 长丰县| 革吉县| 安达市| 当雄县| 盱眙县| 错那县| 望江县| 吉隆县| 汽车| 汝州市| 怀集县| 广安市| 德格县| 理塘县| 万山特区| 宣威市|