新聞中心

        EEPW首頁 > 手機與無線通信 > 設計應用 > 點對多點多任務無線通信

        點對多點多任務無線通信

        ——
        作者:聶光義 時間:2005-10-19 來源: 收藏


          現代世界是一個高速自動化的世界,各種各樣的設備除了可以與計算機聯機外,還可以互相聯機,而最簡單的自動化聯機方式就是使用串行通訊。隨著時代的進步,它并沒有被取代,反倒是逐漸被廣泛應用。如今,在許多的場合有線連接的方式已經不能滿足科技的高速發展。技術正以一種快速的速度進入許多產品,它與有線相比主要有成本低,攜帶方便,省去有線布線的煩惱。特別適用于手持設備的、電池供電設備、遙控、遙測、小型網絡、抄表、門禁系統、小區傳呼、工業數據采集系統、無線標簽身份識別、非接觸RF 智能卡、小型無線數據終端、安全防火系統、無線遙控系統、生物信號采集、水文氣象監控、機器人控制、無線232 數據、無線485/422 數據、無線數字語音、數字圖像傳輸、智能小區不停車收費、銀行智能回單系統等。在如此多的無線系統應用中,無線通信的協議自然顯得特別重要,無線通信協議的好壞直接關系到系統的安全性、誤碼率、以及系統運行的速度。本文以上海桑博科技有限公司的STR-2無線收發模塊為例,詳細介紹無線收發模塊與各種單片機的硬件接口設計,無線通信協議的數據打包格式、解包程序以及相關軟件設計。

        系統概述

        一.連狀系統

          如圖1系統由一臺中央監控設備CMS (Central Monitoring System)和多臺遠程終端設備MRTU(Multiple Remote Termial Unit)構成多任務無線通信系統。在中央監控設備CMS 與 遠程終端RTU(Remote Termial Unit)之間用多臺中轉設備Tran作為中轉站,以便起到暫存數據和延伸距離的作用。中轉站之間,以單向通信方式進行傳遞數據。

        1.適用范圍

        a.適用于傳輸距離遠的多點多任務數據采集

        b.適用于條件惡劣干擾大多點多任務數據采集

        c.適用于對時間要求不高的各種復雜無線數傳

        d.適用于智能小區水、電、煤、暖氣集中抄表系統,各種遠程集中安防報警系統等。

        2.協議數據包格式

          協議的笫一件事就是能夠識別噪聲和有效數椐,噪聲是以隨機字節出現的,沒有明顯的結合方式,噪聲源可能產生任意字節的組合,在無線通信的過程中最好能通過一種協議能有效的抑制噪聲的產生

          通過測試和試驗,發現0xFF 后跟0XAA,0x55 在噪聲中不容易發生,傳輸協議應該在數據包前加開始字節0xFF 后跟0xAA,0x55發送協議的開始應該以一個任意內容的字節(這是因為第一個字節的數椐在發送時容易丟失),然后是0xFF 后跟一個0xAA,0x55;接收協議規定只接收以0xFF 后跟0xAA,0x55 開始的包.于是就可以很方便的把以上系統的數據包格式定為:

        Lead1

        Lead2

        Lead2

        Header

        Length

        HostID

        Local

        Destination

        unit

        Data1

        Data2

        ●●●

        Datan

        Checksum

         

         

         

        Lead 為引導字節

        Leader1=0xFF;

        Leader2=0xAA;

        Leader2=0x55;

        Header 為數據包的命令字節,由此確定數據包的類型

        Length 為數據包包含的Length字節之后的所有字節的長度

        HostID 為主機地址

        Local  為本地機地址

        Destination 目標地址

        Unit   為RTU地址字節

        Data   位數據包字節

        Checksum 校驗字節

        二.    星狀點對多點通信


          如圖 2系統由一臺中央監控設備CMS和多臺遠程終端設備MRTU構成點對多點多任務無線通信系統。在中央監控設備CMS 與 每一臺遠程終端RTU(Remote Termial Unit)都以雙向通信方式進行傳遞數據。特別適用于數據量大,對時間要求較高的場合。

        1. 適用范圍

        a. 適用于傳輸距離較近的地方

        a.適用于條件惡劣干擾大的地方

        b.適用于對時間要求高、數據量大的場合

        c.適用于智能小區水、電、煤、暖氣集中抄表系統,各種遠程集中安防報警系統等

        d.適用于智能家用集中控制系統

        e.工業測控、工業數據采集

        f. 醫療器械、健身器材

        g.數據倉庫、智能商場超市導購

        h.餐飲無線點菜系統

        i.PDA無線數傳

        j.水紋氣象監控

        k.生物信號采集

        l.油田環境監控

        m.銀行智能回單系統等

        2.協議數據包格式

        根據圖 2可以把系統的數據包格式定為:

         

        Lead1

        Lead2

        Lead2

        Header

        Length

        Unit

        Data1

        Data2

        ●●●

        Datan

        Checksum

         


         

        Lead 為引導字節

        Leader1=0xFF;

        Leader2=0xAA;

        Leader2=0x55;

        Header 為數據包的命令字節,由此確定數據包的類型

        Length 為數據包包含的Length字節之后的所有字節的長度

        Unit   為RTU地址字節

        Data   位數據包字節

        Checksum 校驗字節

        硬件設計

         
          上海桑博電子科技有限公司STR-2 RF Module 的核心部分為nRF401,外加精心設計的內置天線,體積為37mm x 47mm,具有體積小,功耗低的特點,傳輸距離為200米,傳輸最大速率為20kbit/s,外圍接口電路簡單,可直接與單片機的通用串行總線(UART)口連接。如圖3所示STR-2 RF Module 引腳功如下:

        VCC:正電源,接2.7~5.25V

        CS:  頻道選擇,CS=0選擇工作頻道1即433.92MHZ,CS=1選擇工作頻道2即433.33MHZ

        DOUT:    數據輸出,連接MCU串口RXD

        DIN:數據輸入,連接MCU串口TXD

        GND:      電源地

        PWR:      節能控制,PWR=1正常工作狀態,PWR=0低功耗狀態

        TXN:發射接收控制,TXN=1時模塊為發射狀態,TXN=0時模塊為接收狀態

        STR-2 RF Module 接口簡單,本文將不作詳細的敘述,如果想要詳細的了解STR-2 RF Module, 請參照參考文獻 1。

        {{分頁}}

        軟件設計

          在系統中所有STR-2 RF Module 均采用433.92MHZ作為系統工作頻率。下面以星狀點對多點通信系統為例,詳細介紹系統的軟件設計。

        1.主程序設計

          為了避免同頻干擾的問題,系統采用分時TDMA(Time Division Multiple Access)技術,把系統CMS與任意一臺RTU之間的通信采用時分的方式分開,CMS通過掃描的方式與各臺RTU設備進行單臺通信,這樣系統中的CMS與RTU的通信方式就成為點對點的通信方式。整個點對多點系統的通信就成為若干個點對點通信的組合。程序采用C51單片機語言編寫,其主控程序流程圖如圖4、圖5所示。

         

        2.打包與解包

          協議將主要數據分割成一定格式的數據,并增加一些額外的信息(用于糾錯),這個過程叫打包,在接收端協議去掉這些額外信息,只留下初始信息,這個過程叫解包.

        下面是一段打包程序:

        #define MRTUC _DATAPOLL0xE1 //定義包類型為數據包

        #define MRTUC _DATAPOLLRESPONSE    0xE2//定義包類型為應答數據包

        #define MRTUC _ACTIVATE 0xF1//定義包類型為請求握手包

        #define MRTUC _ACTIVATEREQUEST      0xF2//定義包類型為應答握手包

        #define E$HostID  0x11  //定義目標主機地址

        void SCI_Putc( unsigned char data ); //通過SCI輸出數據函數

        void SCI_Puts(unsigned char *str,unsigned char length) //輸出多數據函數

        {

           while ( length!=0 ){

              SCI_Putc( *str++ );                        //通過SCI發送數據

                             Length--;

        }

        }

        void CheckActiveFunc(unsigned char unit)  //請求握手函數

        {

           unsigned char buff[8];

          

           buff[0]=0xFF;                     //引導字節

           buff[1]=0xAA;                    //引導字節

           buff[2]=0x55;                     //引導字節

           buff[3] = MRTUC _ACTIVATE;      //數據包頭字節

           buff[4] = 0x03;                    //數據包長度

           buff[5] = E$HostID;                //主機地址

           buff[6] = unit;                     //從機地址

           buff[7] = 1 + ~(MRTUC _ACTIVATE + 0x03 + E$HostID + unit); //校驗字節

           SCI_Puts(buff,8);                  //發送數據包

        }

         

        void ResponseActiveRequestFunc(void)

        {

           unsigned char buff[8];

           buff[0]=0xFF;

           buff[1]=0xAA;

           buff[2]=0x55;

           buff[3] = MRTUC _ACTIVATEREQUEST;

           buff[4] = 0x03;

           buff[5] = E$HostID;

           buff[6] = unit;

           buff[7] = 1 + ~(MRTUC _ACTIVATEREQUEST + 0x03 + E$HostID + unit);

           SCI_Puts(buff,8);

        }

         

        void DataPollFunc(unsigned char unit)

        {

           unsigned char buff[8];

           buff[0]=0xFF;

           buff[1]=0xAA;

           buff[2]=0x55;

           buff[3] = MRTUC _DATAPOLL;

           buff[4] = 0x03;

           buff[5] = E$HostID;

           buff[6] = unit;

           buff[7] = 1 + ~(MRTUC _DATAPOLL + 0x03 + E$HostID + unit);

           SCI_Puts(buff,8);

        }

         

        void ResponseDataPollFunc(unsigned char unit)

        {

           unsigned char buff[8];

           buff[0]=0xFF;

           buff[1]=0xAA;

           buff[2]=0x55;

           buff[3] = MRTUC _DATAPOLLRESPONSE;

           buff[4] = 0x3;

           buff[5] = E$HostID;

           buff[6] = unit;

           buff[7] = 1 + ~(MRTUC _DATAPOLLRESPONSE + 0x3 + E$HostID + unit);

           SCI_Puts(buff,8);

        }

        {{分頁}}

        程序解包流程圖:

            解包子程序流程圖如圖6所示。

        解包程序:

        #define TOTAL_RESPONSE    5 //定義數據包的總數

        void SCI_Getc(void);                  //從SCI buffer取數據函數

        struct ResponseCodeStruct {      //定義數據包結構體

           unsigned char Code;              // 數據包的類型

           unsigned char Length;            // 數據包的長度

        };

        const ResponseCodeStruct ResponseCodeTable[TOTAL_RESPONSE]={

           { 0, 0 },

           {MRTUC _DATAPOLL,          3},

           {MRTUC _DATAPOLLRESPONSE,   3},

           {MRTUC _ACTIVATE,           3},

           {MRTUC _ACTIVATEREQUEST,    3},

        };

        unsigned char CheckResponseCode( unsigned char code )//檢查數據包類型函數

        {

          unsigned char i;

          

          for ( i=1; i<TOTAL_RESPONSE; i++ ) {

             if ( ResponseCodeTable[i].Code == code )

                return i;

          }

          return 0;

        }

        void ResetReceivingStatus( void )           //復位接收狀態

        {

           PacketStatus &= ~PC_START;          //數據包為開始狀態

           BufferIndex = 0;                      //復位接收頭字節標志

        }

        void SerialHandler( void )             //數據解包子程序

        {

           unsigned char char,i,j;

           unsigned char *buff;

           if ((PacketStatus & PC_READY)==0 ) { //檢查數據包狀態

              if ( SCI_Flags & SCI_IQDIRTY ) {  //檢查SCI狀態

                 char = SCI_Getc();            //從buffer取一字節數據

                 if ( BufferIndex==0) {         // 檢查是否為頭字節

                    if ( (CodeIndex=CheckResponseCode( char ))==0   ) {

                      CodeIndex=0;      

                      ResetReceivingStatus();   //復位接收狀態

                      }

                      return;               //如果不正確返回取下一字節

                    }

                    CheckSum = 0;

                    PacketStatus |= PC_START; //定義開始接收數據

                 }

                 else if ( BufferIndex==1 ) {          

                 if(char<3|| har>(SCI_IQMASK-1)|| (ResponseCodeTable[CodeIndex]. Length && ResponseCodeTable[CodeIndex].Length!=char) ) { //檢查長度

                       CodeIndex=0;

                       ResetReceivingStatus();

                       }

                       return;

                    }

                    PacketLength = char + 2;

                 }

                 else if ( BufferIndex==2 ) {           // 檢查主機地址

                    if ( char!=E$HostID ) {

                       CodeIndex=0;

                       ResetReceivingStatus();

                        }

                        return;

                    }

                 }

                 else if ( BufferIndex==3 ) {           // 檢查從機地址

                    if ( char>MAX_UNIT || char==0 ) {

                       return;

                    }

                    else {

                      if(E$UNIT!=char){

                        CodeIndex=0;

                        ResetReceivingStatus();

                        return;

                      }

                    }

                 }

                 PacketBuffer[BufferIndex++] = char;

                 if ( BufferIndex>=2 ) {

                    if ( BufferIndex==PacketLength ) {

                       CheckSum = 1 + ~CheckSum;

                       if ( char==CheckSum ) {              //校驗

                          PacketStatus |= PC_READY;

                       }

                       ResetReceivingStatus();

                    }

                 }

                 CheckSum += char;

              }

              else {

                 if ( (PacketStatus & PC_START) && TimeOut==0 ) {

                    CodeIndex=0;

                    ResetReceivingStatus();

                 }

              }

           } }

        結束語
         
          本文中的無線硬件設計、軟件設計解決方案已被多次運用于多種產品、多種系統。目前各種產品、系統運行穩定,無線通信誤碼率低、可靠性高、安全性好。文中的軟硬件設計方案,可適用于各種單片機,對于無線通信技術在我國推廣和廣泛的運用有著重要的參考價值。

        參考文獻

        1.上海桑博  STR-2無線數據收發模塊使用手冊    上海桑博電子科技有限公司   2002

        2.Nordic     nRF401 Product Specification          Nordic corporation           2000

        3. 譚浩強     C程序設計                        清華大學出版社            1999



        關鍵詞: 點對多點 無線 通信

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 和顺县| 炉霍县| 永济市| 台前县| 邵武市| 和政县| 苏尼特左旗| 东丽区| 邵阳市| 文山县| 绥阳县| 隆德县| 陵川县| 探索| 新昌县| 双城市| 响水县| 肃宁县| 闵行区| 温宿县| 宁明县| 岳西县| 伊春市| 镇巴县| 罗田县| 法库县| 宜川县| 宜昌市| 温泉县| 武汉市| 山丹县| 五原县| 泰安市| 双柏县| 塘沽区| 保定市| 太谷县| 辽中县| 通化县| 满城县| 海原县|