新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > MODBUS通訊協定及RS485介面通訊程式

        MODBUS通訊協定及RS485介面通訊程式

        作者: 時間:2016-12-16 來源:網絡 收藏
        MODBUS通訊協定RS485介面通訊程式
        一.檔案列表
        RS485.pdf電路圖
        RS485.CC的原始程式
        RS485.asm由C轉成的組合語言檔
        RS485.hex燒錄檔
        二.MODBUS介紹
        MODBUS通訊協定原本是MODICON公司為自己所生產的PLC(可程式邏輯控制器)所開發的通訊協定,後來廣泛為工業界所使用,它是一對多的方式來通訊,目前他是採開放的方式不需支付任何費用,任何人皆可開發,所以目前許多PLC、人機介面及圖控軟體都有支援。
        目前modbus通訊協定可分為ModbusASCII及ModbusRTU兩種傳送方式,ModbusASCII顧名思義就是以ASCII碼的方式來傳輸,而ModbusRTU是以Binary的方式來傳輸,二者以RTU的方式最快,所以我介紹RTU的方式,它傳送資料是從低位元開始傳送,下面的表格是Modbus通訊協定的功能表,其中384、484、584、884、M84及984為Modicon公司所生產的PLC型號。
        CodeName384484584884M84984
        01ReadCoilStatusYYYYYY
        02ReadInputStatusYYYYYY
        03ReadHoldingRegistersYYYYYY
        04ReadInputRegistersYYYYYY
        05ForceSingleCoilYYYYYY
        06PresetSingleRegisterYYYYYY
        07ReadExceptionStatusYYYYYY
        08Diagnostics(seeModiconModbusProtocolReferenceGuideChapter3)
        09Program484NYNNNN
        10Poll484NYNNNN
        11FetchComm.EventCtr.YNYNN
        12FetchComm.EventLogYNYNN
        13ProgramControllerYNYNNY
        14PollControllerYNYNNY
        15ForceMultipleCoilsYYYYYY
        16PresetMultipleRegistersYYYYYY
        17ReportSlaveIDYYYYY
        18Program884/M84NNNYYN
        19ResetComm.LinkNNNYYN
        20ReadGeneralReferenceNNYNNY
        21WriteGeneralReferenceNNYNNY
        22MaskWrite4XRegisterNNNNN(1)
        23Read/Write4XRegistersNNNNN(1)
        24ReadFIFOQueueNNNNN(1)
        Notes:
        (1)Functionissupportedin984–785only.
        此次的範例我們只用了Function3(ReadHoldingRegisters)及Function6(PresetSingleRegister)的功能,所以以下針對這兩個Function做一說明
        Function03(ReadHoldingRegisters)
        讀取SlaveHoldingRegisters的內容(二進制碼)從PLC4X的參考位置,我以範例來說明
        QUERYExample

        FieldName (Hex)
        --------------------------------
        SlaveAddress 11
        Function 03
        StartingAddressHi 00
        StartingAddressLo 6B
        No.ofPointsHi 00
        No.ofPointsLo 03
        ErrorCheck(LRCorCRC) ––

        SlaveAddress從0-7E(Hex),Functioncode為03,讀取暫存器的起始位置從40108-40110,其中108為6C,但因通訊的暫存器位置從0開始,所以108需減一,也就是6B,108-110總共三個暫存器(No.ofPoints),ErrorCheck有分LRC及CRC,LRC為ModbusASCIIMode的錯誤檢查碼,RTUMode使用的是CRC的檢查方式,CRC的檢查方式在程式說明的章節再說明。織夢內容管理系統

        RESPONSEExample

        FieldName (Hex)
        --------------------------------
        SlaveAddress 11
        Function 03
        ByteCount 06
        DataHi(Register40108) 02
        DataLo(Register40108) 2B
        DataHi(Register40109) 00
        DataLo(Register40109) 00
        DataHi(Register40110) 00
        DataLo(Register40110) 64
        ErrorCheck(LRCorCRC) ––

        此回應是從Slave傳至Master,前頭的Address及Function都與Master傳過來的一樣,ByteCount為要回傳至Master的byte數,因為Master要求讀取3個暫存器的資料,一個暫存器有兩個bytes,所以總共6個bytes,再來就是依次傳回40108-10110的內容,最後再CRC檢查碼。
        Function06(PresetSingleRegister)
        將資料寫入HoldingRegister,且一次只寫入一個暫存器
        QUERYExample

        FieldName (Hex)
        --------------------------------
        SlaveAddress 11
        Function 06
        RegisterAddressHi 00
        RegisterAddressLo 01
        PresetDataHi 00
        PresetDataLo 03
        ErrorCheck(LRCorCRC) ––

        將資料03寫入SlaveAddress11暫存器40002的位置。
        RESPONSEExample

        FieldName (Hex)
        --------------------------------
        SlaveAddress 11
        Function 06
        RegisterAddressHi 00
        RegisterAddressLo 01
        PresetDataHi 00
        PresetDataLo 03
        ErrorCheck(LRCorCRC) ––

        Slave的回應很簡單,只要從Master傳來的資料無誤,也通過CRC的檢查,將原本收到的資料傳回給Master即可。
        三.程式說明
        程式裡頭最主要的是CRCcheck,在這裡針對CRCcheck做一說明,程式裡有一個副程式uns16crc16(uns8*puchMsg,uns8crc_count),我針對其參數做一說明:
        uns16à傳回16bits的無號數資料
        uns8*puchMsgà傳入字串位址,其字串的資料型態為無號數的八位元
        uns8crc_countà無號數的八位元,其代表傳入字串的長度
        針對crc16副程式做一說明:
        先宣告三個暫存器uindex,uchCRCHi及uchCRCLo,且將ff(Hex)的值丟入uchCRCHi及uchCRCLo。
        1.檢查crc_count是否為零,若為零則到步驟5,否則繼續。
        2.將uchCRCHi與字串的第一個byte做ExclusiveOR(互斥或),將結果送到uindex暫存器,將指標移到字串的下一個字元。織夢內容管理系統
        3.使用uindex當索引去查auchCRCHi的表格相對應的值,再將它與uchCRCLo做ExclusiveOR(互斥或),將結果送入uchCRCLo中。
        4.將crc_count減一,跳至步驟一。
        5.將uchCRCHi往左移8bit再與uchCRCLo做OR,然後將此16bits的資料傳回。
        這套C語言是由BKnudsenData所開發,其網站為http://www.bknd.com/cc5x/index.shtml,相對其他公司,這套CCompiler較為便宜,所以較符合經濟效益,以下針對主程式做一說明:
        此程式是當Modbus的Slave,其位址為11(Hex),它只有設定頻率(set_hz)及設定啟動(set_run)這兩組暫存器需要設定而已,而需讀取的資料有設定頻率(40001)、設定啟動(40086)、目前運轉的頻率(40079)、目前運轉的電流(40080)、目前運轉的狀態(40085)及目前的錯誤訊息(40087)。
        從第205-266列為Slave從Master接收到資料之後所做的相關處理及回應,第207列是做從Master接收的資料再一次做CRC的檢查,看計算的CRC檢查碼與Master傳過來的檢查碼有無一樣,若一樣則傳回該回應的值。dedecms.com
        從第267-282列為將要傳送到Master的值,透過串列埠傳出去,且將LTC485的IC設為傳送模式;第283-284列為若TRMT(TransmitShiftRegisterStatusbit)為空的話,這表示所有資料已傳送完畢,則將LTC485設為接收模式。
        第112-113列為若接收資料間隔超過8ms,則需從新開始接收字串。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 车致| 平罗县| 南乐县| 建平县| 荥经县| 白银市| 手游| 特克斯县| 花垣县| 慈溪市| 桐柏县| 益阳市| 蓬莱市| 海城市| 道孚县| 万盛区| 通河县| 黎平县| 石狮市| 金川县| 徐汇区| 离岛区| 郯城县| 永昌县| 瑞安市| 万州区| 尉犁县| 大丰市| 崇阳县| 林周县| 朝阳区| 翁牛特旗| 景德镇市| 宝兴县| 垦利县| 溧水县| 图木舒克市| 平湖市| 柏乡县| 措勤县| 屯昌县|