色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 單片機實現(xiàn)485總線現(xiàn)場監(jiān)測系統(tǒng)

          單片機實現(xiàn)485總線現(xiàn)場監(jiān)測系統(tǒng)

          作者: 時間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
          在一些要求響應(yīng)速度快、實時性強、控制量多的應(yīng)用場合,往往理由多個單片機結(jié)合PC機組成分布系統(tǒng),在這樣的系統(tǒng)中可以使用RS-485接口連接單片機和PC機。RS-485是RS-232的改良標準,在通信速率、傳輸距離、多機連接等方面較RS-232有了很大的提高,在軟件設(shè)計上和RS-232基本一致。在結(jié)合RS-485及有關(guān)資料基礎(chǔ)上學習了用單片機實現(xiàn)485總線現(xiàn)場監(jiān)測系統(tǒng)。這個系統(tǒng)以PC機為主機,多個單片機為從機的現(xiàn)場監(jiān)測系統(tǒng),單片機組組成的各個節(jié)點負責采集終端設(shè)備的狀態(tài)信息,主機以輪詢的方式向各個節(jié)點獲取這些設(shè)備信息,并根據(jù)信息內(nèi)容進行相關(guān)的操作。

          本文引用地址:http://cafeforensic.com/article/201611/315972.htm

          主要器件:

          1、PC機端的232/485轉(zhuǎn)換接口:MC1488和MC1489實現(xiàn)TTL電平和RS-232通信電平的轉(zhuǎn)化;PC147光電隔離器件;MAX481485驅(qū)動收發(fā)芯片。

          2、單片機端:AT89C52單片機芯片,用于數(shù)據(jù)采集和與485總線接口;MAX481485驅(qū)動收發(fā)芯片;DIP-6開關(guān)用于確定本機的設(shè)備號。

          試驗流程圖:

          主機端流程:


          單片機端流程圖:


          試驗電路圖:

          主機端

          單片機端:

          試驗程序代碼:

          // 485Mon.h程序

          #ifndef_485MON_H//防止485Mon.h被重復引用

          #define_485MON_H

          #include //引用標準庫的頭文件

          #include

          #include

          #define uchar unsigned char

          #define uint unsigned int

          #define ACTIVE0x11

          #define GETDATA0x22

          #define READY0x33

          #define SENDDATA0x44

          #define RECFRMMAXLEN 16//接收幀的最大長度,超過此值認為幀超長錯誤

          #define STATUSMAXLEN 10//設(shè)備狀態(tài)信息最大長度

          uchar DevNo;//設(shè)備號

          xdata uchar StatusBuf[STATUSMAXLEN];

          //為簡化起見,假設(shè)了10位固定的采集數(shù)據(jù)

          #define DATA00x10

          #define DATA10x20

          #define DATA20x30

          #define DATA30x40

          #define DATA40x50

          #define DATA50x60

          #define DATA60x70

          #define DATA70x80

          #define DATA80x90

          #define DATA90xA0

          sbit DE = P1^6;//驅(qū)動器使能,1有效

          sbit RE = P1^7;//接收器使能,0有效

          void init();//系統(tǒng)初始化

          void Get_Stat();//簡化的數(shù)據(jù)采集函數(shù)

          bit Recv_Data(uchar *type);//接收數(shù)據(jù)幀函數(shù)

          void Send(uchar m);//發(fā)送單字節(jié)數(shù)據(jù)

          void Send_Data(uchar type,uchar len,uchar *buf);//發(fā)送數(shù)據(jù)幀函數(shù)

          void Clr_StatusBuf();//清除設(shè)備狀態(tài)信息緩沖區(qū)函數(shù)

          #endif

          // 485Mon.c程序

          #include "485Mon.h"

          void main(void)

          {

          uchar type;

          /*初始化*/

          init();

          while (1)

          {

          if (Recv_Data(&type)==0)//接收幀錯誤或者地址不符合,丟棄

          continue;

          switch (type)

          {

          case ACTIVE://主機詢問從機是否在位

          Send_Data(READY,0,StatusBuf);//發(fā)送READY指令

          break;

          case GETDATA://主機讀設(shè)備請求

          Clr_StatusBuf();

          Get_Stat();//數(shù)據(jù)采集函數(shù)

          Send_Data(SENDDATA,strlen(StatusBuf),StatusBuf);

          break;

          default:

          break;//指令類型錯誤,丟棄當前幀

          }

          }

          }

          /*初始化*/

          void init(void)

          {

          P1 = 0xff;

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

          TMOD = 0x20;

          SCON = 0x50;

          TH1 = 0xfd;

          TL1 = 0xfd;

          TR1 = 1;

          PCON = 0x00;// SMOD=0

          EA = 0;

          }

          /*接收數(shù)據(jù)幀函數(shù),實際上接收的是主機的指令*/

          bit Recv_Data(uchar *type)

          {

          uchar tmp,rCount,i;

          uchar r_buf[RECFRMMAXLEN];//保存接收到的幀

          uchar Flag_RecvOver;//一幀接收結(jié)束標志

          uchar Flag_StartRec;//一幀開始接收標志

          uchar CheckSum;//校驗和

          uchar DataLen;//數(shù)據(jù)字節(jié)長度變量

          /*禁止發(fā)送,允許接收*/

          DE = 0;

          RE = 0;

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

          rCount = 0;

          Flag_StartRec = 0;

          Flag_RecvOver = 0;

          while (!Flag_RecvOver)

          {

          RI = 0;

          while (!RI);

          tmp = SBUF;

          RI=0;

          /*判斷是否收到字符$,其數(shù)值為0x24 */

          if ((!Flag_StartRec) && (tmp == 0x24))

          {

          Flag_StartRec = 1;

          }

          if (Flag_StartRec)

          {

          r_buf[rCount] = tmp;

          rCount ++;

          /*判斷是否收到字符*,其數(shù)值為0x2A,根據(jù)接收的指令設(shè)置相應(yīng)標志位*/

          if (tmp == 0x2A)

          Flag_RecvOver = 1;

          }

          if (rCount == RECFRMMAXLEN)//幀超長錯誤,返回0

          return 0;

          }

          接上篇程序:

          /*計算校驗和字節(jié)*/

          CheckSum = 0;

          DataLen = r_buf[3];

          for (i=0;i++;i<3+DataLen)

          {

          CheckSum = CheckSum + r_buf[i+1];

          }

          /*判斷幀是否錯誤*/

          if (rCount<6)//幀過短錯誤,返回0,最短的指令幀為6個字節(jié)

          return 0;

          if (r_buf[1]!=DevNo)//地址不符合,錯誤,返回0

          return 0;

          if (r_buf[rCount-2]!=CheckSum)//校驗錯誤,返回0

          return 0;

          *type = r_buf[2];//獲取指令類型

          return 1;//成功,返回1

          }

          /*發(fā)送數(shù)據(jù)幀函數(shù)*/

          void Send_Data(uchar type,uchar len,uchar *buf)

          {

          uchar i,tmp;

          uchar CheckSum = 0;

          /*允許發(fā)送,禁止接收*/

          DE = 1;

          RE = 1;

          /*發(fā)送幀起始字節(jié)*/

          tmp = 0x24;

          Send(tmp);

          Send(DevNo);//發(fā)送地址字節(jié),也即設(shè)備號

          CheckSum = CheckSum + DevNo;

          Send(type);//發(fā)送類型字節(jié)

          CheckSum = CheckSum + type;

          Send(len);//發(fā)送數(shù)據(jù)長度字節(jié)

          CheckSum = CheckSum + len;

          /*發(fā)送數(shù)據(jù)*/

          for (i=0;i

          {

          Send(*buf);

          CheckSum = CheckSum + *buf;

          buf++;

          }

          Send(CheckSum);//發(fā)送校驗和字節(jié)

          /*發(fā)送幀結(jié)束字節(jié)*/

          tmp = 0x2A;

          Send(tmp);

          }

          /*采集數(shù)據(jù)函數(shù)經(jīng)過簡化處理,取固定的10個字節(jié)數(shù)據(jù)*/

          void Get_Stat(void)

          {

          StatusBuf[0]=DATA0;

          StatusBuf[1]=DATA1;

          StatusBuf[2]=DATA2;

          StatusBuf[3]=DATA3;

          StatusBuf[4]=DATA4;

          StatusBuf[5]=DATA5;

          StatusBuf[6]=DATA6;

          StatusBuf[7]=DATA7;

          StatusBuf[8]=DATA8;

          StatusBuf[9]=DATA9;

          }

          /*發(fā)送單字節(jié)數(shù)據(jù)*/

          void Send(uchar m)

          {

          TI = 0;

          SBUF = m;

          while(!TI);

          TI = 0;

          }

          /*清除設(shè)備狀態(tài)信息緩沖區(qū)函數(shù)*/

          void Clr_StatusBuf(void)

          {

          uchar i;

          for (i=0;i

          StatusBuf[i] = 0;

          }



          評論


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

          關(guān)閉