<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

          51單片機串口程序

          作者: 時間:2016-11-19 來源:網(wǎng)絡 收藏
          串口中斷服務函數(shù)集

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

          putbyte(charc)
          {uchari,j;
          ES=0;/*暫停串行中斷,以免數(shù)據(jù)比較時出錯?*/
          //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;//放字節(jié)進入緩沖區(qū)
          putlast++;//發(fā)送緩沖區(qū)指針加一
          if(putlast==outbuf+OLEN)putlast=outbuf;//指針到了頂部換到底部
          outbufsign=1;
          if(!outbufsign0){outbufsign0=1;TI=1;}//緩沖區(qū)開始為空置為有,啟動發(fā)送
          ES=1;
          }
          //
          //放一串數(shù)據(jù)到發(fā)送緩沖區(qū)
          putbytes(unsignedchar*outplace,unsignedcharj)
          {inti;
          for(i=0;i{putbyte(*outplace);
          outplace++;
          }
          }
          //
          //輸出一個無符號字符數(shù)的十進制表示,必須標示小數(shù)點的位置,自動刪除前面無用的零
          //例如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);
          }

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

          }
          }
          }
          //*
          //串口初始化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;

          }
          //*
          //測試用主函數(shù)

          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單片機串口程

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();