新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機串口程序

        51單片機串口程序

        作者: 時間:2016-11-19 來源:網絡 收藏
        串口中斷服務函數集

        //本函數集來自“51單片機世界”,作者斑竹丁?。櫺∶停?。
        //主頁地址http://www.mcu51.com
        //串口中斷服務程序,僅需做簡單調用即可完成串口輸入輸出的處理
        //出入均設有緩沖區,大小可任意設置。
        //可供使用的函數名:
        //chargetbyte(void);從接收緩沖區取一個byte,如不想等待則在調用前檢測inbufsign是否為1。
        //getline(charidata*line,unsignedcharn);獲取一行數據回車結束,必須定義最大輸入字符數
        //putbyte(charc);放入一個字節到發送緩沖區
        //putbytes(unsignedchar*outplace,j);放一串數據到發送緩沖區,自定義長度
        //putstring(unsignedcharcode*puts);發送一個定義在程序存儲區的字符串到串口
        //puthex(unsignedcharc);發送一個字節的hex碼,分成兩個字節發。
        //putchar(ucharc,ucharj);輸出一個無符號字符數的十進制表示,必須標示小數點的位置,自動刪除前面無用的零
        //putint(uintui,ucharj);輸出一個無符號整型數的十進制表示,必須標示小數點的位置,自動刪除前面無用的零
        //delay(unsignedchard);延時nx100ns
        //putinbuf(ucharc);人工輸入一個字符到輸入緩沖區
        //CR;發送一個回車換行
        //*
        #include
        #defineucharunsignedchar
        #defineuintunsignedint
        #defineOLEN32/*sizeofserialtransmissionbuffer*/
        idataunsignedcharoutbuf[OLEN];/*storagefortransmissionbuffer*/
        unsignedcharidata*outlast=outbuf;//最后由中斷傳輸出去的字節位置
        unsignedcharidata*putlast=outbuf;//最后放入發送緩沖區的字節位置
        #defineILEN12/*sizeofserialreceivingbuffer*/
        idataunsignedcharinbuf[ILEN];
        unsignedcharidata*inlast=inbuf;//最后由中斷進入接收緩沖區的字節位置
        unsignedcharidata*getlast=inbuf;//最后取走的字節位置
        bitoutbufsign0;//最后一個數據覵BUF發完標志發完=0
        bitoutbufsign;//輸出緩沖區非空標志有=1
        bitinbufsign;//接收緩沖區非空標志有=1
        bitinbufful;//輸入緩沖區滿標志滿=1
        #defineCRputstring("/r/n")//CR=回車換行

        //*
        //延時nx100ns
        voiddelay(unsignedchard)//在源程序開頭定義是否用w77e58或22。1184M晶振
        {unsignedcharj;
        do{d--;

        //110592&89c52
        #ifndefcpuw77e58
        #ifndefxtal221184
        j=21;//k=38cpu80320100usk=21cpu8052
        #else
        j=42;
        #endif
        #else
        #ifndefxtal221184
        j=38;
        #else
        j=76;
        #endif
        #endif

        do{j--;}while(j!=0);
        }while(d!=0);
        }
        //*
        //放入一個字節到發送緩沖區

        putbyte(charc)
        {uchari,j;
        ES=0;/*暫停串行中斷,以免數據比較時出錯?*/
        //if(outlast=putlast)
        while((((outlast-putlast)==2)&&(outlast>putlast))||((outlast{ES=1;c++;c--;ES=0;
        //i=(0-TH1);
        //do{i--;j=39;do{j--;}while(j!=0);}while(i!=0);//i=39
        }
        *putlast=c;//放字節進入緩沖區
        putlast++;//發送緩沖區指針加一
        if(putlast==outbuf+OLEN)putlast=outbuf;//指針到了頂部換到底部
        outbufsign=1;
        if(!outbufsign0){outbufsign0=1;TI=1;}//緩沖區開始為空置為有,啟動發送
        ES=1;
        }
        //
        //放一串數據到發送緩沖區
        putbytes(unsignedchar*outplace,unsignedcharj)
        {inti;
        for(i=0;i{putbyte(*outplace);
        outplace++;
        }
        }
        //
        //輸出一個無符號字符數的十進制表示,必須標示小數點的位置,自動刪除前面無用的零
        //例如putchar(0x32,2),輸出"4.8".
        //putchar(0x32,3),輸出"0.48".
        //putchar(0x32,1),輸出"48".
        putchar(ucharc,ucharj)
        {ucharidatafree[4];uchardatai;
        i=0;
        free[i++]=(c/100+0x30);
        if(j==3)free[i++]=.;
        free[i++]=(c%100)/10+0x30;
        if(j==2)free[i++]=.;
        if(j==2&&free[i-3]==0x30)free[i-3]=0x20;
        free[i++]=(c%10)+0x30;
        if(j==1&&free[i-3]==0x30)free[i-3]=0x20;
        if(j==1&&free[i-3]==0x20&&free[i-2]==0x30)free[i-2]=0x20;
        putbytes(free,i);
        }

        //
        //輸出一個無符號整型數的十進制表示,必須標示小數點的位置,自動刪除前面無用的零
        putint(uintui,ucharj)
        {ucharidatafree[6];
        uchardatai;
        i=0;
        free[i++]=(ui/10000+0x30);
        if(j==5)free[i++]=.;
        free[i++]=((ui%10000)/1000+0x30);
        if(j==4)free[i++]=.;
        if(j==4&&free[i-3]==0x30)free[i-3]=0x20;
        free[i++]=((ui%1000)/100+0x30);
        if(j==3)free[i++]=.;
        if(j==3&&free[i-4]==0x30)free[i-4]=0x20;
        if(j==3&&free[i-4]==0x20&&free[i-3]==0x30)free[i-3]=0x20;
        free[i++]=((ui%100)/10+0x30);
        if(j==2)free[i++]=.;
        if(j==2&&free[i-5]==0x30)free[i-5]=0x20;
        if(j==2&&free[i-5]==0x20&&free[i-4]==0x30)free[i-4]=0x20;
        if(j==2&&free[i-5]==0x20&&free[i-4]==0x20&&free[i-3]==0x30)free[i-3]=0x20;
        free[i++]=(ui%10+0x30);
        if(j==1&&free[i-5]==0x30)free[i-5]=0x20;
        if(j==1&&free[i-5]==0x20&&free[i-4]==0x30)free[i-4]=0x20;
        if(j==1&&free[i-5]==0x20&&free[i-4]==0x20&&free[i-3]==0x30)free[i-3]=0x20;
        if(j==1&&free[i-5]==0x20&&free[i-4]==0x20&&free[i-3]==0x20&&free[i-2]==0x30)free[i-2]=0x20;
        putbytes(free,i);
        }
        //*
        //發送一個定義在程序存儲區的字符串到串口
        putstring(unsignedchar*puts)
        {for(;*puts!=0;puts++)//遇到停止符0結束
        putbyte(*puts);
        }
        //*
        //發送一個字節的hex碼,分成兩個字節發。
        unsignedcharcodehex_[]={"0123456789ABCDEF"};
        puthex(unsignedcharc)
        {intch;
        ch=(c>>4)&0x0f;
        putbyte(hex_[ch]);
        ch=c&0x0f;
        putbyte(hex_[ch]);
        }
        //*
        //從接收緩沖區取一個byte,如不想等待則在調用前檢測inbufsign是否為1。
        uchargetbyte(void)
        {charidatac;
        while(!inbufsign);//緩沖區空等待
        ES=0;
        c=*getlast;//取數據
        getlast++;//最后取走的數據位置加一
        inbufful=0;//輸入緩沖區的滿標志清零
        if(getlast==inbuf+ILEN)getlast=inbuf;//地址到頂部回到底部
        if(getlast==inlast)inbufsign=0;//地址相等置接收緩沖區空空標志,再取數前要檢該標志
        ES=1;
        return(c);//取回數據
        }
        //*
        //接收一行數據,必須定義放數據串的指針位置和大小del=0x7f,backspace=0x08,cr=0x0d,lf=0x0a
        voidgetline(ucharidata*line,unsignedcharn)
        {unsignedcharcnt=0;//定義已接收的長度
        charc;
        do{
        if((c=getbyte())==0x0d)c=0x00;//讀一個字節,如果是回車換成結束符
        if(c==0x08||c==0x7f)//BACKSPACE和DEL的處理
        {if(cnt!=0)//已經輸入退掉一個字符
        {cnt--;//總數目減一
        line--;//指針減一
        putbyte(0x08);//屏幕回顯的處理
        putbyte();
        putbyte(0x08);
        }
        }
        else
        {putbyte(*line=c);//其他字符取入,回顯
        line++;//指針加一
        cnt++;//總數目加一
        }
        }while(cnt*line=0;//再加上停止符0
        }
        //
        //人工輸入一個字符到輸入緩沖區
        putinbuf(ucharc)
        {ES=0;if(!inbufful)
        {*inlast=c;//放入數據
        inlast++;//最后放入的位置加一
        if(inlast==inbuf+ILEN)inlast=inbuf;//地址到頂部回到底部
        if(inlast==getlast)inbufful=1;//接收緩沖區滿置滿標志
        inbufsign=1;
        }
        ES=1;
        }
        //*
        //串口中斷處理
        serial()interrupt4
        {if(TI)
        {TI=0;
        if(outbufsign)
        //if(putlast==outlast)outbufsign=0;
        //else
        {SBUF=*outlast;//未發送完繼續發送
        outlast++;//最后傳出去的字節位置加一
        if(outlast==outbuf+OLEN)outlast=outbuf;//地址到頂部回到底部
        if(putlast==outlast)outbufsign=0;//數據發送完置發送緩沖區空標志
        }
        elseoutbufsign0=0;
        }
        if(RI)
        {RI=0;
        if(!inbufful)
        {
        *inlast=SBUF;//放入數據
        inlast++;//最后放入的位置加一
        inbufsign=1;
        if(inlast==inbuf+ILEN)inlast=inbuf;//地址到頂部回到底部
        if(inlast==getlast)inbufful=1;//接收緩沖區滿置滿標志

        }
        }
        }
        //*
        //串口初始化0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200
        serial_init(){
        SCON=0x50;/*mode1:8-bitUART,enablereceiver*/
        TMOD|=0x20;/*timer1mode2:8-Bitreload*/
        PCON|=0x80;TH1=0xfA;//fa,//baud*2/*reloadvalue19200baud*/
        TR1=1;/*timer1run*/
        ES=1;REN=1;EA=1;SM2=1;//SM2=1時收到的第9位為1才置位RI標志
        TMOD|=0x01;//th1autoload2X8,th01X16
        TH0=31;TL0=0;//X32=1S
        TR0=1;//ET0=1;

        }
        //*
        //測試用主函數

        voidmain(void)
        {charc;
        idataunsignedcharfree[16];
        unsignedcharidata*freep=free;
        serial_init();


        putstring("jdioptuejls;j;klj");
        delay(10);

        while(1)
        {putstring("comisready!");}
        c=getbyte();
        putbyte(0x20);
        puthex(c);
        switch(c)
        {caser:
        putbytes(inbuf,ILEN);
        break;
        caseg:
        getline(freep,10);
        putbyte(0x20);
        putstring(freep);
        break;
        default:
        putbyte(c);
        //}
        }
        }



        關鍵詞: 51單片機串口程

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 衡山县| 宁陵县| 麻城市| 高青县| 浙江省| 精河县| 营山县| 颍上县| 芜湖市| 正安县| 儋州市| 深州市| 板桥市| 疏勒县| 沾益县| 房产| 屯留县| 阿拉善盟| 汶川县| 崇阳县| 太仆寺旗| 建德市| 永宁县| 资兴市| 绥化市| 察隅县| 扶余县| 自贡市| 高密市| 凤庆县| 新宁县| 中超| 惠安县| 错那县| 翁牛特旗| 山东省| 贡嘎县| 格尔木市| 二手房| 新营市| 乌审旗|