<i id="2ino5"><pre id="2ino5"><delect id="2ino5"></delect></pre></i>
    <track id="2ino5"><ins id="2ino5"><option id="2ino5"></option></ins></track>
    <acronym id="2ino5"></acronym><mark id="2ino5"><table id="2ino5"></table></mark>
    <video id="2ino5"><ins id="2ino5"><p id="2ino5"></p></ins></video>
  • <video id="2ino5"></video>
  • <i id="2ino5"></i> <wbr id="2ino5"><table id="2ino5"><button id="2ino5"></button></table></wbr>

    <object id="2ino5"><table id="2ino5"></table></object>

    RS485網絡的整幀數據收發

     2020-7-28     作者:黃志超    

      背景:RS485是最常用的工業現場通訊手段,它的傳輸字節采用了異步串口UART的規范。在通常的工控應用中,需要傳輸由多個字節組成的數據幀,而RS485并沒有對數據幀有任何規范,需要應用程序自己做數據幀的鑒別。


      本文介紹在ESM6800、ESM7000和ESM8000主板上,利用iMX6/7/8串口的9bit RS485模式,實現RS485通訊網絡的整幀數據收發的功能。該功能可大大簡化應用程序接收線程的復雜性,提高RS485通訊的效率。


      整幀數據擁有固定的數據長度,由地址和數據構成,地址為一個字節,其余都為數據字節,如下圖:


    RS485網絡的整幀數據收發.png


      9bit RS485模式使用了串口固定校驗位的功能,定義了地址字節和數據字節,地址字節是指固定校驗位始終為1的字節。而數據字節則是指固定校驗位始終為0的字節。同時9bit RS485模式實現了一些硬件過濾的功能,在接收的時候,必須要先接收到地址字節才會開始接收數據字節,否則硬件會將收到的數據字節全部過濾掉,通過這種方式降低了設備的負載。所以9bit RS485模式顧名思義,通常使用在RS485模式上面,因為RS485可以作為總線掛接多個設備,在多路設備通訊的情況下通過這種校驗方式可以有效的降低設備負載和軟件的復雜程度。


      英創工控主板中,能夠支持9bit RS485模式的主板和串口如下表,其中ES6801/ES6801L和ESM6800L這三款核心板能夠滿足低成本的需求,可以考慮作為RS485網絡中的Slave端:


    主板型號支持9bit RS485模式的串口備注
    ES6801(L)ttyS1—ttyS6適合作為Slave
    ESM6800(H)ttyS1—ttyS5適合作為Master
    ESM6800EttyS1—ttyS6適合作為Master
    ESM6800LttyS1—ttyS6適合作為Slave
    ESM6802ttyS1—ttyS4適合作為Master
    ESM7000ttyS1—ttyS6適合作為Master


      如果要使用9bit RS485模式,需要在程序中進行使能,使能后串口就會進入到該模式中,在發送數據的時候,可以支持兩種方式,一種是發送地址字節,另一種是發送數據字節。在接收數據字節的時候,分為master和slave兩種模式,這兩種模式都需要先接收地址字節,才能夠接收數據字節,如果沒有接收到地址字節,會自動將數據字節自動全部濾掉。他們的區別在于master模式下,只要接收到地址字節,就會將這之后的數據字節全部接收,并交給應用程序處理。而在slave模式下,需要先設置設備地址,只有接收到的地址字節和設備地址相同時,才會開始接收數據字節。


      master模式下,接收數據示意圖:


    RS485網絡的整幀數據收發-2.png


      Slave模式下,接收數據示意圖:


    RS485網絡的整幀數據收發-3.png


      采用9bit RS485模式,有兩個優點,第一點是不需要判斷是否接收到地址字節,因為串口要在接收到地址字節(校驗位為1)后,才會接收數據字節,特別是在slave模式下,只有當地址字節和設置的設備地址相等時,才會接收數據。第二點是不需要切換校驗方式,當串口啟用了9bit RS485模式,就可以正常接收所有地址字節和數據字節了,只有在發送地址字節和數據字節的時候需要切換不同的設置,可以減少軟件上的操作。


      英創公司在提供的例程Step2_serialtest中封裝的串口類CSerial的基礎上派生出一個專用于9bit RS485的類CRS485,在這個類中我們增加使能9bit RS485模式的函數,讓客戶可以直接調用來實現相關功能。


    /**
     *    派生用于9bit RS485的類
     *
    **/
    class CRS485 : public CSerial
    {
    private:
           //串口模式、設備地址和接收超時時間
           int serial_mode;
           int serial_addr;
     
    public:
           //接收數據緩存和長度
           char frame[100];
           int  frame_len;
     
           /**
            *    派生類的構造函數
            *
            *    在構造函數中初始化變量,以及設置9-bit RS485模式下的串口是處于master還是slave模式
            *
            *    參數說明:
            *    mode:值為0對應master模式,值為1對應slave模式
            *    addr:設備地址,大小為8bit,當且僅當mode為1是有效。
            *
           **/
           CRS485(int mode, int addr);
     
           /**
            *    發送9bit RS485整包數據
            *
            *    函數會將地址字節和數據字節填寫,并設置為相應的模式一并發送
            *
            *    參數說明:
            *    addr:設備地址,大小為8bit,填入發送數據的地址字節中
            *    Buf:發送的數據字節
            *    len:發送數據字節的長度
            *
            *    返回值說明:
            *    len:成功
            *    -1:失敗
            *
           **/
           int send_rs485_frame(char addr, char *Buf, int len);
     
           /**
            *    接收9bit RS485整包數據
            *
            *    函數會阻塞接收指定長度的數據,可以設置超時時間,如果超過超時時間沒有接收到指定長度的數據,則返回-1
            *
            *    參數說明:
            *    Buf:接收的數據字節
            *    len:發送數據字節的長度
            *    timeout:超時時間,單位毫秒。如果在超時時間內沒有收到指定長度的數據,則返回-1。值為0則不阻塞,讀取不到數據立即返回。值為-1則沒有超時時間,如果接受不到指定長度數據會一直等待
            *
            *    返回值說明:
            *    成功則返回接收到的數據長度
            *    -1:超時
            *
           **/
           int recv_rs485_frame(char *Buf, int len, int timeout);
     
           /**
            *    繼承自CSerial類的接收處理函數
            *
            *    在CSerial類的接收線程中會調用這個函數,可以在函數中調用recv_rs485_frame()函數,并處理接收到的數據字節
            *     
            *
           **/
           int PackagePro();
    };


      在類實例化的時候,代入參數就可以決定串口是處于master模式還是slave模式,如果是出于slave模式可以一起代入需要設定的設備地址:


    //master模式
    class CRS485  m_Serial(0, 0);
     
    //slave模式,設備地址為0x55
    class CRS485  m_Serial(1, 0x55);


      接收處理的時候,數據的長度通過宏DATA_LEN定義,客戶可以在PackagePro()函數中可以定義超時時間,然后調用recv_rs485_frame()函數來接收整包數據,recv_rs485_frame()函數會阻塞,直至收到指定長度的數據,或者到達超時時間才會返回。接收到整包數據后,就可以開始進行數據的處理,在接收線程調中循環調用PackagePro函數:


    #define DATA_LEN 10                    // 數據長度
     
    // 接收串口數據處理函數
    int CRS485::PackagePro()
    {
           int i1, timeout;
     
           //設置超時時間,單位毫秒
           timeout = 500;
     
           //調用接收函數來獲取指定長度的整包數據
           i1 = recv_rs485_frame(DatBuf, m_DatLen, timeout);
     
           //接收到整包數據,調用處理程序,這里只是簡單的打印
           if(i1 != -1)
           {
                  printf("frame addr = 0x%x\n", frame[0]);
                  printf("frame data = ");
                  for(i1=1; i1<DATA_LEN; i1++) {
                         printf("0x%x ", frame[i1]);
                  }
                  printf("\n");
     
                  //處理完數據,清除各個變量,重新設置串口以等待下一包數據
                  memset(frame, 0, 100);
                  frame_len = 0;
           }
           else
                  printf("time out!\n");
     
           return i1;
    }


      在線程中的處理,循環調用接收處理函數即可,因為recv_rs485_frame()函數會阻塞,直至收到指定長度的數據,或者到達超時時間才會返回:


    int CSerial::ReceiveThreadFunc(void* lparam)
    {
           CSerial *pSer = (CSerial*)lparam;
     
           //定義讀事件集合
           fd_set fdRead;
           int ret;
           struct timeval     aTime;
     
           while( 1 )
           {
                  //接收處理函數
                  pSer->PackagePro( pSer->DatBuf, pSer->m_DatLen);
     
           }
     
           printf( "ReceiveThreadFunc finished\n");
           pthread_exit( NULL );
           return 0;
    }


      串口在發送的時候,比較簡單,直接調用send_rs485_frame()函數,填入需要發送的地址和數據即可,使用下面的代碼來測試:


    char        addr = 0x55;
    char    Buf[2];
     
    Buf[0] = 0x55;
    Buf[1] = 0xaa;
     
    //發送地址字節和數據字節
    m_Serial.send_rs485_frame(addr, Buf, sizeof(Buf));


      主板實際輸出的波形如下:


    RS485網絡的整幀數據收發.png


      感興趣的客戶可以和英創的工程師聯系,索取完整的測試工程。

    色综合久久无码中文字幕,久久亚洲精品无码爱剪辑,亚洲国产天堂久久综合,2020久久天天躁狠狠躁夜夜,年龄最小的无码AV在线观看 亚洲国产在线精品国自产拍影院,免费网站看v片在线无遮挡,免费观看四虎精品国产,自拍偷区亚洲综合美利坚,无码毛片视频一区二区本码 国产日韩久久久久精品影院,国内精品久久久久久影院,亚洲国产日韩欧美高清片,久久亚洲国产精品影院,中文字幕四虎第一页 亚洲国产在线精品国自产拍影院,免费网站看v片在线无遮挡,免费观看四虎精品国产,自拍偷区亚洲综合美利坚,无码毛片视频一区二区本码 天堂v无码亚洲_高无码,一本大道香蕉中文在线视频,亚洲中文无码亚洲人成视不卡,亚洲精品无码不卡在线观看,亚洲综合区图片小说区 免费高清v片在线观看,免费网站看完整v片在线,日本高清视频在线网站,2019中文字幕视频,2019中文字幕视频在线 老司机在线视频体验区,亚洲国产中文字幕新在线,国产亚洲精品在线视频,国产精品高清视频免费,新国产在热线精品视频99
    天堂v无码亚洲_高无码,一本大道香蕉中文在线视频,亚洲中文无码亚洲人成视不卡,亚洲精品无码不卡在线观看,亚洲综合区图片小说区 国产女人久久香蕉精品视,男人靠女人的免费视频,久无码久无码av无码,免费的av网站手机版,亚洲国产欧美国产综合一区 亚洲乱码中文字幕综合,欧美成人无码A片视频,丝袜AV人妻系列制服丝袜,成人 H小视频在线播放,JAPANESE无码中文字幕 日本Av天堂无码一区二区免费,久久精品这里热有精品,亚洲成a人片在线观看无码,亚洲精品无码一区二区三区,国产精品亚洲日韩Av在线 香港经典a毛片免费观看,亚洲日本欧美日韩高观看免费,一级A一片在线播放,免费欧洲毛片a级视频,无码专区视频中文字幕,91精品欧美综合在线 大杳焦伊人在钱,伊人9在线观看免费观看,伊人无码高清,狠狠狠的在啪线香蕉,日本视频高清免费观看,色情亚洲21p 暖暖直播视频在线观看,亚洲国产欧美在线人成,欧美日韩AV中文日本AV三区,国产在热线精品视频99,伊人久久大香线蕉av,久久人与动人物a 欧洲自拍拍偷无码#精品在线视频,亚洲欧洲自拍拍偷无码,亚洲高清国产拍精品,亚洲愉拍自拍另类图片高清无码种子,精品视频在线观看 欧美日本一道本dⅴd在线播放,人体性爱亚洲AV,新超碰www男人的天堂,色偷偷新超碰男人的天堂,在线看片韩国免费人成视频 2020无码最新国产在线观看,亚洲2020天天堂在线观看,精品国产品国语在线不卡,无码精品国产DVD在线观看,亚洲精品国产第一区第二区