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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 485通信程序(51單片機)

          485通信程序(51單片機)

          作者: 時間:2016-11-11 來源:網(wǎng)絡(luò) 收藏
          #include

          #include

          本文引用地址:http://www.ex-cimer.com/article/201611/317037.htm

          #defineucharunsignedchar

          #defineuintunsignedint

          /*通信命令*/

          #define_ACTIVE_0x01//主機詢問從機是否存在

          #define_GETDATA_0x02//主機發(fā)送讀設(shè)備請求

          #define_OK_0x03//從機應(yīng)答

          #define_STATUS_0x04//從機發(fā)送設(shè)備狀態(tài)信息

          #define_MAXSIZE0x08//緩沖區(qū)長度

          #define_ERRLEN12//任何通信幀長度超過12則表示出錯

          uchardbuf[MAXSIZE]; //該緩沖區(qū)用于保存設(shè)備狀態(tài)信息

          uchardev;//該字節(jié)用于保存本機設(shè)備號

          sbitM_DE=P1^0;//驅(qū)動器使能,1有效

          sbitM_RE=P1^1;//接收器使能,0有效

          voidget_status();//調(diào)用該函數(shù)獲得設(shè)備狀態(tài)信息,函數(shù)全碼未給出

          voidsend_data(uchartype,ucharlen,uchar*buf);//發(fā)送數(shù)據(jù)幀

          bitrecv_cmd(uchar*type);//接收主機命令,主機請求包含命令信息。

          voidsend_byte(ucharda);//該函數(shù)發(fā)送一幀數(shù)據(jù)中的一個字節(jié),由send_data()函數(shù)調(diào)用

          voidmain()

          {

          uchartype;

          ucharlen;

          /*系統(tǒng)初始化*/

          P1=0xff;//讀取本機設(shè)備號

          dev=(P1>>2);

          TMOD=0x20;//定時器T1使用方式2

          TH1=250;

          TL1=250;

          TR1=1;//開始計時

          PCON=0x80;//SMOD=1;

          SCON=0x50;//工作方式1,波特優(yōu)選法9600bps,允許接收

          ES=0; //關(guān)閉串品中斷

          IT0=0;//外部中斷0使有電平觸發(fā)模式

          EX0=1;//開啟外部中斷0

          EA=0;//開啟總中斷

          /*主程序流程*/

          while(1)

          {

          if(recv_cmd(&type)==0)//發(fā)送幀錯誤或幀地址與本機地址不符,丟棄當前幀后返回

          continue;

          switch(type)

          {

          case_ACTIVE_://主機詢問從機是否存在

          send_data(_OK_,0,dbuf);//發(fā)送應(yīng)答信息,這里的buf的內(nèi)容并未用到

          break;

          case_GETDATA_://主機發(fā)送讀設(shè)備請求

          len=strlen(dbuf);

          snd_data(_STATUS_,len,dbuf);//發(fā)送設(shè)備信息

          break;

          default:

          break;//命令類型錯誤,丟棄當前幀返回

          }

          }

          }

          voidREADSTATUS()interrput0using1//產(chǎn)生外部中斷0時表示設(shè)備狀態(tài)發(fā)生改變,該函數(shù)使用寄存器組1

          {

          get_status();//獲得設(shè)備狀態(tài)信息,并將其存入dbuf指向的存儲區(qū),數(shù)據(jù)最后一個字節(jié)置0表示數(shù)據(jù)結(jié)束

          }

          /*該函數(shù)接收一幀數(shù)據(jù)度進行檢測,無論該幀是否錯誤,函數(shù)均會返回。

          *函數(shù)參數(shù)type保存接收到的命令字

          *當接收的數(shù)扭幀錯誤或其地址位不為0時(非主機發(fā)送幀),快活數(shù)返回0,反之返回1

          */

          bitrecv_cmd(uchar*type)

          {

          bitdb=0;//當接收到的上一個字節(jié)為0xdb時,該位置位

          bitc0=0;//當接慢到的上一個字節(jié)為0xc0時,該位置位

          uchardata_buf[_ERRLEN];//保存接收到的幀

          uchartmp;

          ucharecc=0;

          uchari;

          M_DE=0;//置發(fā)送禁止,接收允許

          M_RE=0;

          /*接收一幀數(shù)據(jù)*/

          i=0;

          while(!c0)//循環(huán)直至幀接收完畢

          RI=0;

          while(RI);

          tmp=SBUF;

          RI=0;

          if(db==1)//接收到的上一個字節(jié)為0xdb

          {

          swithc(tmp)

          case0xdd:

          data_buf[i]=0xdb;//0xdbdd表示0xdb

          ecc=ecc^0xdb;

          db=0;

          break;

          case0xdc:

          data_buf[i]=0xc0;//0xdbdc表示0xc0

          ecc=0;

          db=0;

          break;

          default:

          return0;//幀錯誤,返回

          i++;

          }

          switch(tmp)//正常情況下

          {

          case0xc0://幀結(jié)束

          c0=1;

          break;

          case0xdb: //檢測到轉(zhuǎn)義字符

          db=1;

          break;

          default://普通數(shù)據(jù)

          data_buf[i]=tmp;//保存數(shù)據(jù)

          ecc=ecc^tmp;//計算校驗字節(jié)

          i++;

          }

          if(i==_ERRLEN)//幀超長,錯誤,返回

          return0;

          /*判斷幀是否錯誤*/

          if(i<4)//幀過短,錯誤,返回

          return0;

          if(ecc!=0)//校驗錯誤,返回

          return0;

          if(data_buf[i!=dev) //非訪問本機命令,錯誤,返回

          return0;

          *type=data_buf[1];//獲得命令字

          return1;//函數(shù)成功返回

          }

          /*該函數(shù)發(fā)送一數(shù)據(jù)幀,參數(shù)type為命令字,len為數(shù)據(jù)長度,buf為要發(fā)送的數(shù)據(jù)內(nèi)容*/

          voidsend_data(uchartype,ucharlen,uchar*buf)

          {

          uchari;

          ucharecc=0;

          M_DE=1;//置發(fā)送允許,接收禁止

          M_RE=1;

          send_byte(dev);//發(fā)送本機地址

          ecc=dev;

          send_byte(type);//發(fā)送命令字

          ecc=ecc^type;

          send_byte(len);//發(fā)送長度

          ecc=ecc^len;

          for(i=0;i

          {

          send_byte(*buf);

          ecc=ecc^(*buf);

          buff++;

          }

          send_byte(ecc);//發(fā)送校驗字節(jié)

          TI=0;//發(fā)送幀結(jié)束標志

          SBUF=0xc0;

          while(!TI);

          TI=0;

          }

          /*該函數(shù)發(fā)送一個數(shù)據(jù)字節(jié),若該字節(jié)為0xdb,則發(fā)送0xdbdd,若該字節(jié)為0xc0,則發(fā)送0xdbdc*/

          voidsend_byte(ucharda)

          {

          switch(da)

          {

          case0xdb://字節(jié)為0xdb,發(fā)送0xdbdd

          TI=0;

          SBUF=0xdb;

          while(!TI);

          TI=0;

          SBUF=0xdd;

          while(!TI);

          TI=0;

          break;

          case0xc0://字節(jié)為0xc0,則發(fā)送0xdbdc

          TI=0;

          SBUF=0xdb;

          while(!TI);

          TI=0;

          SBUF=0xdc;

          while(!TI);

          TI=0;

          break;

          default://普通數(shù)據(jù)剛直接發(fā)送

          TI=0;

          SBUF=da;

          while(!TI);

          TI=0;

          }

          }



          關(guān)鍵詞: 485通信程序51單片

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁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); })();