嵌入式
返回首页

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

2015-05-05 来源:elecfans

MODBUS通訊協定及RS485介面通訊程式
一. 檔案列表
RS485.pdf 電路圖
RS485.C C的原始程式
RS485.asm 由C轉成的組合語言檔
RS485.hex 燒錄檔
二. MODBUS介紹
MODBUS通訊協定原本是MODICON公司為自己所生產的PLC(可程式邏輯控制器)所開發的通訊協定,後來廣泛為工業界所使用,它是一對多的方式來通訊,目前他是採開放的方式不需支付任何費用,任何人皆可開發,所以目前許多PLC、人機介面及圖控軟體都有支援。
目前modbus通訊協定可分為Modbus ASCII及Modbus RTU兩種傳送方式,Modbus ASCII顧名思義就是以ASCII碼的方式來傳輸,而Modbus RTU是以Binary的方式來傳輸,二者以RTU的方式最快,所以我介紹RTU的方式,它傳送資料是從低位元開始傳送,下面的表格是Modbus通訊協定的功能表,其中384、484、584、884、M84及984為Modicon公司所生產的PLC型號。 
Code Name 384 484 584 884 M84 984
01 Read Coil Status Y Y Y Y Y Y
02 Read Input Status Y Y Y Y Y Y
03 Read Holding Registers Y Y Y Y Y Y
04 Read Input Registers Y Y Y Y Y Y
05 Force Single Coil Y Y Y Y Y Y
06 Preset Single Register Y Y Y Y Y Y
07 Read Exception Status Y Y Y Y Y Y
08 Diagnostics (see Modicon Modbus Protocol Reference Guide Chapter 3)
09 Program 484 N Y N N N N
10 Poll 484 N Y N N N N
11 Fetch Comm. Event Ctr. Y N Y N N
12 FetchComm. Event Log Y N Y N N
13 Program Controller Y N Y N N Y
14 Poll Controller Y N Y N N Y
15 Force Multiple Coils Y Y Y Y Y Y
16 Preset Multiple Registers Y Y Y Y Y Y
17 Report Slave ID Y Y Y Y Y
18 Program 884/M84 N N N Y Y N
19 Reset Comm. Link N N N Y Y N
20 Read General Reference N N Y N N Y
21 Write General Reference N N Y N N Y
22 Mask Write 4X Register N N N N N (1)
23 Read/Write 4X Registers N N N N N (1)
24 Read FIFO Queue N N N N N (1)
Notes: 
( 1 ) Function is supported in 984–785 only.
此次的範例我們只用了Function 3(Read Holding Registers)及Function 6(Preset Single Register)的功能,所以以下針對這兩個Function做一說明
Function 03(Read Holding Registers)
讀取Slave Holding Registers的內容(二進制碼)從PLC 4X的參考位置,我以範例來說明
QUERY Example

Field Name  (Hex)
--------------------------------
Slave Address   11
Function   03
Starting Address Hi   00
Starting Address Lo   6B
No. of Points Hi   00
No. of Points Lo   03
Error Check (LRC or CRC)   ––

Slave Address從0-7E(Hex),Function code為03,讀取暫存器的起始位置從40108-40110,其中108為6C,但因通訊的暫存器位置從0開始,所以108需減一,也就是6B,108-110總共三個暫存器(No. of Points),Error Check有分LRC及CRC,LRC為Modbus ASCII Mode的錯誤檢查碼,RTU Mode使用的是CRC的檢查方式,CRC的檢查方式在程式說明的章節再說明。 织梦内容管理系统 

RESPONSE Example

Field Name  (Hex)
--------------------------------
Slave Address   11
Function   03
Byte Count   06
Data Hi (Register 40108)   02
Data Lo (Register 40108)   2B
Data Hi (Register 40109)   00
Data Lo (Register 40109)   00
Data Hi (Register 40110)   00
Data Lo (Register 40110)   64
Error Check (LRC or CRC)   ––

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

Field Name  (Hex)
--------------------------------
Slave Address   11
Function   06
Register Address Hi   00
Register Address Lo   01
Preset Data Hi   00
Preset Data Lo   03
Error Check (LRC or CRC)   ––

將資料03寫入Slave Address 11暫存器40002的位置。
RESPONSE Example

Field Name  (Hex)
--------------------------------
Slave Address   11
Function   06
Register Address Hi   00
Register Address Lo   01
Preset Data Hi   00 
Preset Data Lo   03
Error Check (LRC or CRC)   ––

Slave的回應很簡單,只要從Master傳來的資料無誤,也通過CRC的檢查,將原本收到的資料傳回給Master即可。
三. 程式說明
程式裡頭最主要的是CRC check,在這裡針對CRC check做一說明,程式裡有一個副程式uns16 crc16(uns8 *puchMsg,uns8 crc_count),我針對其參數做一說明:
uns16à傳回16bits的無號數資料
uns8 *puchMsgà傳入字串位址,其字串的資料型態為無號數的八位元
uns8 crc_countà無號數的八位元,其代表傳入字串的長度
針對crc16副程式做一說明:
先宣告三個暫存器uindex,uchCRCHi及uchCRCLo,且將ff(Hex)的值丟入uchCRCHi及uchCRCLo。
1. 檢查crc_count是否為零,若為零則到步驟5,否則繼續。
2. 將uchCRCHi與字串的第一個byte做Exclusive OR(互斥或),將結果送到uindex暫存器,將指標移到字串的下一個字元。 织梦内容管理系统 
3. 使用uindex當索引去查auchCRCHi的表格相對應的值,再將它與uchCRCLo做Exclusive OR(互斥或),將結果送入uchCRCLo中。
4. 將crc_count減一,跳至步驟一。
5. 將uchCRCHi往左移8bit再與uchCRCLo做OR,然後將此16bits的資料傳回。
這套C語言是由B Knudsen Data所開發,其網站為http://www.bknd.com/cc5x/index.shtml,相對其他公司,這套C Compiler較為便宜,所以較符合經濟效益,以下針對主程式做一說明:
此程式是當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(Transmit Shift Register Status bit)為空的話,這表示所有資料已傳送完畢,則將LTC485設為接收模式。
第112-113列為若接收資料間隔超過8ms,則需從新開始接收字串。
进入嵌入式查看更多内容>>
相关视频
  • PX4固件二次开发课程

  • RISC-V嵌入式系统开发

  • NuttX Workshop 2024

  • 自己动手写操作系统

  • SOC系统级芯片设计实验

  • 自己动手做一台计算机

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章