Modbus-RTU和Modbus-TCP協(xié)議模板(C語言)_第1頁
Modbus-RTU和Modbus-TCP協(xié)議模板(C語言)_第2頁
Modbus-RTU和Modbus-TCP協(xié)議模板(C語言)_第3頁
Modbus-RTU和Modbus-TCP協(xié)議模板(C語言)_第4頁
Modbus-RTU和Modbus-TCP協(xié)議模板(C語言)_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Modbus-RTU 和 Modbus-TCP 協(xié)議模板(C 語言)目錄簡介:2Modbus-RTU 簡介:2Modbus-TCP 3System, h: 4CRC_Check. h5CRC_Check. c5Modbus.RTU.h,8Modbus_RTU. c10Modbus_TCP. h.27Modbus_TCP. c27第2頁簡介:在單片機內(nèi)部實現(xiàn)modbus協(xié)議,可以簡單地將變量的值映射到modbus寄存器地址,這種方法是高效 的,但是有以下缺點:1、通常不支持一條指令操作多個變量(寄存器);2、可移植性較差。本模板使用8位數(shù)組模擬modbus寄存器。06, 10指令均對數(shù)組進行寫操

2、作,同時記錄寄存器的寫入操 作,在其他地方定時判斷“寫入標志”,將“寫入標志”置位的“模擬寄存器”的值轉(zhuǎn)移到相關(guān)變量,或 進行其他操作。03指令讀取最新數(shù)據(jù),要求定時將變量的值寫入“模擬寄存器”。本模板缺點是占用資源較多、效率較低,優(yōu)點是完整支持了 modbus的03, 06, 10指令。Modbus-RTU 簡介:1、Modbus讀寄存器指令(0x03)地址(1B) +功能碼(1B) +起始地址(2B) +寄存器數(shù)量(2B) +CRC (2B)返回:地址(1B) +功能碼(1B) +字節(jié)數(shù)(1B) +數(shù)據(jù)值(2* “寄存器數(shù)量" Bytes或者“字節(jié)數(shù)”)+CRC(2B)2、Mod

3、bus寫單個寄存器指令(0x06)地址(1B) +功能碼(1B) +寄存器地址(2B) + 數(shù)據(jù)值(2B) +CRC (2B)返回:地址(1B) +功能碼(1B) +寄存器地址(2B) +數(shù)據(jù)值(2B) +CRC (2B)(返回與發(fā)送的指令相同)3、Modbus寫多個寄存器指令(0x10)地址(IB) +功能碼(IB) +起始地址(2B)+CRC (2B)+寫寄存器數(shù)量(2B n) +字節(jié)計數(shù)數(shù)B n*2) +數(shù)據(jù)存*2 B)返回:地址(1B) +功能碼(1B) +起始地址(2B)+寫寄存器數(shù)量(2B) +CRC(2B)Modbus-TCP 簡介:在MODBUS-RTU前添加6個字節(jié),并刪除M

4、ODBUS-RTU的CRC校驗。示例指令:0051 0000 0009 01 10 0001 0001 02 00 006個字節(jié)部分稱為“MBAP報文頭”示例:0051 0000 00090051是客戶端發(fā)出的校驗信息,服務(wù)端原內(nèi)容返回即可0000 表示 modbus-tcp 協(xié)議0009表示后面還有9個字節(jié)后面部分:01 10 0001 0001 02 00 0001設(shè)備地址10表示10指令0001起始地址0001寫寄存器數(shù)量02字節(jié)計數(shù)00 00數(shù)據(jù)響應(yīng)指令:0051 0000 0006 01 10 0001 0001System, h:#ifndef SYSTEM H define SY

5、STEM Hinclude ”stm32f10x. h:=不常改動項* stm32f lOx. h 第 505、506、507 行已經(jīng)定義了 u32, ul6 和 u8 */typedef unsignedchar u8;/typedef unsignedshort int ul6;/typedef unsignedint u32;/typedef unsignedchar INT8U;/typedef unsigned short int INT16U;/typedef unsignedint INT32U;/typedef signedchar int8_t;/typedef signed

6、/typedef signedint int32_t;/typedef signedlonglong int int64_ttypedef unsignedlonglong int u64;typedef unsignedcharbool_t;#defineFALSE#defineTRUE!FALSE#defineNULL#endifCRC_Check. hitifndef _CRC_CHECK_H_#define _CRC_CHECK_H_include ,system, h”ul6 CRC16_Verify(u8 *puchMsg,ul6 usDataLen);#endifCRC Chec

7、ks cinclude "CRC Check, h”*高位表static const u8 auchCRCHi = 0x00, OxCl,0x81, 0x40, 0x01,OxCO,0x80,0x41, 0x01,OxCO,0x80, 0x41, 0x00,OxCl,0x81,0x40, 0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80, 0x41,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01,OxCO

8、, 0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x01,OxCO,0x80,0x41,0x00, OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40, 0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x01,OxCO,0x80, 0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x01,

9、OxCO, 0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x00, OxCl, 0x81, 0x40, 0x01, OxCO, 0x80, 0x41, 0x01, OxCO, 0x80, 0x41, 0x00, OxCl, 0x81,0x40, 0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80, 0x41,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x00,OxC

10、l,0x81,0x40,0x01,OxCO, 0x80,0x41,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00, OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40, 0x01,OxCO,0x80,0x41,0x01,OxCO,0x80,0x41,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80, 0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01

11、,OxCO,0x80,0x41,0x01,OxCO, 0x80,0x41,0x00,OxCl,0x81,0x40,0x00,OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x00, OxCl,0x81,0x40,0x01,OxCO,0x80,0x41,0x01,OxCO,0x80,0x41,0x00,OxCt0x81,0x40*低位表*/static const u8 auchCRCLo = 0x00, OxCO,OxCl,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04, OxCC,OxO

12、C,OxOD,OxCD,OxOF,OxCF,OxCE,OxOE,OxOA,OxCA,OxCB,OxOB,0xC9,0x09,0x08, 0xC8,0xD8,0x18,0x19,0xD9,OxlB,OxDB,OxDA,OxlA,OxlE,OxDE,OxDF,OxlF,OxDD,OxlD, OxlC,OxDC,0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,Oxll, OxDl,OxDO,0x10,OxFO,0x30,0x31,OxFl,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37, 0xF5

13、,0x35,0x34,0xF4,0x3C,OxFC,OxFD,0x3D,OxFF,0x3F,0x3E,OxFE,OxFA,0x3A,0x3B, OxFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,OxEB,0x2B,0x2A,OxEA,OxEE,0x2E, 0x2F,OxEF,0x2D,OxED,OxEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,OxE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,OxEl,0x2 L0x20,OxEO,OxAO,0x60,0x61,OxAl,0x63,0xA3,0xA2,0x62, 0

14、x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,0x6C,OxAC,OxAD,0x6D,OxAF,0x6F,0x6E, OxAE,OxAA,0x6A,0x6B,OxAB,0x69,0xA9,0xA8,0x68,0x78,0xB8,0xB9,0x79,OxBB,0x7B, 0x7A,OxBA, OxBE,0x7E,0x7F, OxBF,0x7D, OxBD,OxBC,0x7C, 0xB4,0x74,0x75,0xB5,0x77, 0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,OxBl,0x71,0x70,OxBO,0x50,0x90,0x91

15、,0x51, 0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C,0x5D, 0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,0x88,0x48, 0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,OxlD,0x4C,0x8C,0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0

16、x80,0x40;/* 16位CRC校驗函數(shù),查表法*/ul6 CRC16_Verify(u8 *puchMsg, ul6 usDataLen) (u8 uchCRCHi = OxFF ;u8 uchCRCLo = OxFF ;ul6 ulndex ;while (usDataLen)(ulndex = uchCRCHi 八 *puchMsg+ ;uchCRCHi = uchCRCLo 八 auchCRCHiulndex; uchCRCLo = auchCRCLo .ulndex;)/ return (ul6)(uchCRCLo) « 8) uchCRCHi);return (ul6

17、)(uchCRCHi) « 8) uchCRCLo);Modbus_RTU. h#ifndef _MODBUS_RTU_H_#defineODBUS_RTU_H_include ,system, h”*是否啟用“記錄寫入功能”* 0=不記錄寫入操作,1;記錄寫入操作。*需要將數(shù)據(jù)存儲到其他地方時,需要開啟“記錄寫入功能”。* /#define RECJ'RITE 1定義MODBUS緩存大小(8位)* 寄存器數(shù)量二MODBUS_Bl;FFER_LEN/2 * /"define MODBUS.BUFFER.LEN4000define MODBUS_IDLE_REGOxF

18、FFF /MODBUS空閑寄存器地址。表示未配置,不允許操作。extern u8 *Modbus_sBuf;extern u8 Modbus-BufferMODBUS_BUFFER_LEN;extern ul6 Modbus Start Addr;extern u8 Modbus_Swap_Endian;ul6 Modbus_16BitsSwapEndian(ul6 num);u32 Modbus_32BitsSwapEndian(u32 num);u64 Modbus_64BitsSwapEndian(u64 num);u8 Modbus_Read_WRecord(ul6 start,ul6

19、 length);void Modbus_Write_Oecord(ul6 start, ul6 length, u8 sta);u8 Modbus_Read_Buffer(u8 *buffer, ul6 addr, ul6 length);u8 Modbus_Write_Buffer(u8 *buffer, ul6 addr, ul6 length);void Modbus_Example(void);void Modbus_WRecod_Example(void);void Modbus_Init(void);u8 Modbus_RTU_Handler(u8 *rBuf, void(*Se

20、nd_Function)(u8 *string, ul6 x);#endifModbus_RTU. c#include "Modbus_RTU h”include "CRC_Check.h”define Modbus_Addr 1 modbus地址。可以定義為在其他地方定義的地址,例如save. localAddr。/u8 *Modbus_sBuf = Usart_sBuf;u8 Modbus_sBufE128;u8 Modbus.BufferMODBUSBUFFER_LEN;ul6 Modbus Start Addr = 0;u8 Modbus_Swap_Endian =

21、 1;設(shè)為0, STM32設(shè)為1)發(fā)送緩存由外部定義時,使用上面的定義方法。/modbus緩存(定義為8位方便傳輸)/modbus起始地址/0二不轉(zhuǎn)換字節(jié)順序,1二允許轉(zhuǎn)換字節(jié)順序(51單片機#if REC.WRITEu8 ModbusjmecordM0DBUS_BUFFER_LEN/16 +1; 記錄modbus寄存器的寫入操作。需要將數(shù)據(jù)存儲到 其他地方時,需要開啟“寫入記錄功能”。#endif*讀modbus寄存器(16位)寫入狀態(tài) start:起始地址* length:寄存器個數(shù)* 返回:0個寄存器有寫入操作,返回0* 至少有1個寄存器有寫入操作,返回1* if REC_WRITEu8

22、 Modbus_Read_WRecord(ul6 start,ul6 length)ul6 i;ul6 end;if(length = 0) return 0;end = start + length -1;if(end >= X0DBUS_BUFFER_LEN/2) return 0;for(i=start; i<=end; i+)(if (Modbus_Oecordi/8 & (u8) 1« (i%8) return 1;)return 0;)ttendif«* 寫modbus寄存器(16位)寫入狀態(tài)* start: 起始地址* length:寄存器

23、個數(shù)* sta:寫入狀態(tài),0二無寫入操作,1二有寫入操作。«! / »MM «»«» W «»«» » »#if REC_WRITEvoid Modbus_Write_Oecord(u 16 start, ul6 length, u8 sta)ul6 i;ul6 end;if(length = 0) return;end = start + length T;if(end >= MODBUS_BUFFER_LEN/2) return;if (sta) for (i=st

24、art; i<=end; i+)Modbusjmecordi/8 = (u8) l«(i%8);elsefor (i=start; i<=end; i+)Modbus_WRecordi/8 &= "(u8)l«(i%8);)ttendifu8 返回:0二寫入失敗,1二寫入成功。u8 Modbus_Write_Buffer(u8 *buffer,ul6 addr,ul6 length) (ul6 i;u8 *p_save;if(length = 0) return 0;if(addr+length > MODBUS.BUFFER.LEN)

25、return 0;p_save = Modbus_Buffer + addr;for(i=0; i<length; i+)p_data;if(length = 0) return 0;if(addr+length > MODBUS.BUFFER.LEN) return 0;p_data = Modbus_Buffer + addr;for(i=0; i<length; i+) bufferti = p_datai; return 1;)p_savei = buffer i;return 1;* 16位變量存儲順序轉(zhuǎn)換 ul6 Modbus_16BitsSwapEndian(u

26、l6 num) (if(Mo dbu s_Swap_End i an)(return num«8 num»8;else return num;* 32位變量存儲順序轉(zhuǎn)換 typedef unionchar arr4;int32_t int32;float f;MODBUS_UNION32;u32 Modbus_32BitsSwapEndian(u32 num)u8 temp;M0DBUS.UNI0N32 res;if(Mo dbu s_Swap_End i an)(32 = num;temp = res. arr0;res. arr 0 = res. arr

27、3;res.arr3 = temp;temp = res. arrl;res. arr 1 = res. arr 2;res.arr2 = temp;return res. int32;else return num;)« W»* 64位變量存儲順序轉(zhuǎn)換 typedef unionchar arrl8;int64_t int64;double df;M0DBUS_UNI0N64;u64 Modbus_64BitsSwapEndian(u64 num) (u8 temp;M0DBUS.UNI0N64 res;if(Mo dbu s_Swap_End i an)(res. in

28、t64 = num;temp = res. arr0;res. arr 0 = res. arr 7;res.arr7 = temp;temp = res. arrl;res. arr 1 = res. arr .6;res.arr6 = temp;temp = res. arr 2;res. arr 2 = res. arr 5;res.arr5 = temp;temp = res. arr3;res. arr 3 = res. arr4;res.arr4 = temp;return res. int64;else return num;)2 MBV """aw

29、 w* 檢查Xodbus_RTU數(shù)據(jù)幀* 返回0:不通過* 返回L發(fā)往本機的數(shù)據(jù)* 返回2:廣播數(shù)據(jù)u8 Modbus_RTU_Check_Frame(u8 *string)(u8 res = 0;if(string_0=Modbus_Addr stringE0=0x00); else return 0;if(stringLl=0x03 stringl=0x06) if(CRC16_Verify(string, 8) != 0) return 0;else if(stringtl = 0x10)(if(string4 != 0)return 0;if(string5*2 != string6)

30、return 0;if(CRC16_Verify(string, stringZ6+9) != 0) return 0;if(stringlO = OxOO) res = 2;elseres = 1;return res;)* 解析03H指令,讀寄存器«*«W« MM «»«MV4MVvoid Modbus_RTU_03H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x) (ul6 index;寄存器索引ul6 cmd_num;待操作寄存器的數(shù)量ul6 bytes;字節(jié)數(shù)ul6 crc;

31、crc 校驗index = rBuf 2«8rBuf 3;if (index < Modbus_Start_Addr) return;地址過小cmd_num = rBuf 4«8 rBuf 5;讀取modbus緩存。注:RTl,03指令的數(shù)據(jù)位從3開始if(Modbus_Read_Buffer(Modbus_sBuf+3, (index-Modbus_Start_Addr)*2, cmd_num*2)if (rBuf 0 != 0) 本語句存在時,不響應(yīng)廣播幀(地址0);屏蔽后,響應(yīng)廣播幀。/=返回指令bytes = cmd-num 解析06H指令,寫單個寄存器voi

32、d Modbus_RTU_06H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x)ul6 index;寄存器索引ul6 cmd_num;待操作寄存器的數(shù)量2;Modbus_sBuf0 = Modbus_Addr;Modbus_sBuf1 = rBuf1;Modbus_sBuf2 = bytes;crc = CRC16_Verify (Modbus_sBuf, 3+bjrtes);Modbus_sBuf 3+bytes = crc»8;Modbus_sBuf4+bytes = crc;ul6 crc;crc校驗Send_Function(

33、Modbus_sBuf, 5+bytes);index = rBuf 2«8 rBuf 3;if (index < Modbus_Start_Addr) return;地址過小cmd_num = 1;將數(shù)據(jù)寫入modbus緩存。注:RTU/6指令數(shù)據(jù)位從4開始if(Modbus_Write_Buffer(rBuf+4, (index-Modbus_Start_Addr)*2, cmd_num*2) (#if REC.WRITE/= 記錄寫入操作 =Modbus_Wr i t e_TOecord (index-Modbus_St art_Addr, cmd_num, 1);Sen

34、difif(rBuf0 != 0)本語句存在時,不響應(yīng)廣播幀(地址0);屏蔽后,響應(yīng)廣播幀°/=返回指令Modbus_sBuf0Modbus_sBuf1Modbus_sBuf2Modbus_sBuf3Modbus_sBuf4Modbus_sBuf5=Modbus_Addr=rBufl;=rBuf2;=rBuf3;=rBuf4;=rBuf5;crc = CRC16_Verify(Modbus_sBuf, 6);Modbus_sBuf 6 = crc»8;Modbus_sBuf7 = crc;Send_Function(Modbus_sBuf, 8);*解析10H指令,寫多個寄

35、存器 mhm ohmimmmm«» «»mmv aw «»<hwvoid Modbus_RTU_10H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x) ( ul6 index;寄存器索引ul6 cmd_num;待操作寄存器的數(shù)量ul6 crc;crc 校驗index = rBuf 2«8rBuf 3;if (index < Modbus_Start_Addr) return; 地址過小cmd_num = rBuf 4 «8 rBuf 5;將數(shù)據(jù)寫入mod

36、bus緩存。注:RTUO指令數(shù)據(jù)位從7開始if(Modbus_Write_Buffer(rBuf+7, (index-Modbus_Start_Addr)*2, cmd_num*2) (#if REC.WRITE/=記錄寫入操作=Modbus_Write_WRecord(index-Modbus_Start_Addr, cmd_numt 1);Sendifif (rBuf 0 != 0)本語句存在時,不響應(yīng)廣播幀(地址0);屏蔽后,響應(yīng)廣播幀。二= 返回指令 =Modbus_sBuf0 = Modbus_Addr;Modbus_sBuf1 = rBuf1;Modbus.sBuf2=rBuf2;

37、Modbus_sBuf3=rBuf3;Modbus_sBuf4=rBuf4;Modbus_sBuf5=rBuf5;crc = CRC16_Verify(Modbus_sBuf, 6);Modbus.sBuf 6 = crc»8;Modbus_sBuf7 = crc;Send_Function(Modbus_sBuf, 8);* MODBUS-RTU協(xié)議處理程序 u8 Modbus_RTU_Handler(u8 *rBuf, void(*Send_Function)(u8 *string, ul6 x)u8 res = 0;if(Modbus_RTU_Check_Frame(rBuf)

38、 != 0)。=不通過,1 二本機幀,2二廣播幀res = 1;switch(rBuf 11)break;break;case 0x03: Modbus_RTU_03H(rBuf, Send_Function);case 0x06: Modbus_RTU_06H(rBuf, Send_Function);break;break;case 0x10: Modbus_RTU_10H(rBuf, Send_Function);default: res = 0;return res;* modbus初始化 void Modbus_Init(void)ul6 i;for(i=0; iXODBUS_BUF

39、FER_LEN; i+)Modbus_Buf f er.i = 0;for(i=0; i<M0DBUS_BUFFER_LEN/16 +1; i+)Modbus_WRecord Ei = 0;*使用示例*大端模式(51單片機),可直接賦值:*小端模式(STM32),需轉(zhuǎn)換變量存儲順序??芍囟x寄存器的變量u8 *numAlH = (u8 *) (ul6 *)Modbus_Buffer+0);u8 *numAlL = (u8 *) (ul6 *)Modbus.BufferO)+1; 此處的 0二寄存器序號(16 位),此處的 1 表示 轉(zhuǎn)換成(u8 *)數(shù)組后,往后偏移一個序號。ul6 *n

40、umA2 = (ul6 *) (ul6 *)Modbus_Buffer+l);u32 *numA3 = (u32 *) (ul6 *)Modbus_Buffer+2);固定寄存器的變量define numBlH *(u8 *)(ul6 *)Modbus_Buffer+4)define numBIL * (u8 *)(ul6 *)Modbus_Buffer+4)+1)define numB2*(ul6 *)(ul6 *)Modbus_Buffer+5) define numB3 *(u32 *)(ul6 *)Modbus_Buffer+6)固定寄存器的數(shù)組(注意x的范圍,避免越界)define

41、numCl (x) *(u8 *) (ul6 *)Modbus_Buffer+x/2+8)+x%2)Sdefine numC2(x) *(ul6 *) (ul6 *)Modbus.Buffer+x+9) define numC3(x) * (u32 *) (ul6 *)Modbus_Buffer+x*2+l1)void Modbus_Example(void)(*numAlH = 0x01;*numAlL = 0x02;*numA2 = Modbus_16BitsSwapEndian(0x0304);*numA3 = Modbus_32BitsSwapEndian(0x05060708);nu

42、mBlH = 0x11;numBIL = 0x12;numB2 = Modbus_16BitsSwapEndian(0x1314);numB3 = Modbus_32B i t sSwapEnd ian(Ox15161718);numCl(0) = 0x21;numCl(1) = 0x22;numC2(0) = Modbus_16BitsSwapEndian(0x2324);numC2(l) = Modbus_16BitsSwapEndian(0x2526);numC3(0) = Modbus_32BitsSwapEndian(0x2728292A);numC3(l) = Modbus_32B

43、itsSwapEndian(0x2B2C2D2E);numC3(2) = Modbus_32BitsSwapEndian(0x2F303132);/* 讀取測試,51 單片機時SWAP_ENDIAN_EN=O,STM32 時"SWAP_ENDIAN_EX二1”。* 01030000001185C6* 010322010203040506 07 08 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 29 2A2B 2C2D2E2F3031326D3B* /)*示例函數(shù):判斷modbus寫入操作。*/#if REC.WRITEvoid Mo

44、dbus_WRecod_Example(void)(if (Modbus_Read_Oecord(4,1)(清除寫入狀態(tài)Modbus_Write_WRecord(4, 1, 0);)#endifModbus_TCP. hSifndef _MODBUS_TCP_H_define _MODBUS_TCP_H_include "system, h”u8 Modbus_TCP_Handler(u8 檢查Modbus_TCP數(shù)據(jù)幀*返回0:不通過*返回1:發(fā)往本機的數(shù)據(jù)*返回2:廣播數(shù)據(jù)rBuf, void(*Send_Function)(u8 *string, ul6 x);#endifMo

45、dbus_TCP. cinclude "Modbus_TCP. h”include "Modbus_RTU. h /* 需要和 Modbus_RTU 配合使用 */define Modbus.TCP.Addr 1 modbus地址??梢远x為在其他地方定義的地址,例如 save. localAddrou8 Modbus_TCP_Check_Frame(u8 *string)u8 res = 0;ul6 bytes;else return 0; 檢查是否為 modbus-else return 0; 檢查地址if(string2=0x00 && string3

46、=0x00);tcp協(xié)議。if(string.6=Modbus_TCP_Addrstring6. =0x00);bytes = string 4 «8 string5;if(string7 = 0x03) if (bytes != 6)return 0;else if (string7J=0x06)if (bytes != 6)return 0;else if(string7J=0x10) if(bytes-7 != (string10«8 stringEll)*2)return 0;if (string11*2 != string12)return 0;else retu

47、rn 0;if(string6 = 0x00) res = 2;elseres = 1;return res;*解析03H指令,讀寄存器-*/void Modbus_TCP_03H(u8 *rBuf, void(*Send_Function) (u8 *string, ul6 x) (ul6 index;寄存器索引ul6 cmd_num;待操作寄存器的數(shù)量ul6 bytes;字節(jié)數(shù)index = rBuf 8«8rBuf 9;if (index < Modbus_Start_Addr) return; 地址過小 cmd_num = rBuf 10«8 rBuf Ell

48、;讀取modbus緩存。注:TCP_03指令的數(shù)據(jù)位從9開始if(Modbus_Read_Buffer(Modbus_sBuf+9, (index-Modbus_Start_Addr)*2,cmd_num*2)if(rBuf6 != 0)本語句存在時,不響應(yīng)廣播幀(地址0):屏蔽后,響應(yīng)廣播幀,/=返回指令 bytes = 3 + cmd_num » «»» 解析06H指令,寫單個寄存器void Modbus_TCP_06H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x) (ul6 index;寄存器索引

49、ul6 cmd_num;待操作寄存器的數(shù)量index = rBuf 8«8 rBuf 9;if (index < Modbus_Start_Addr) return;地址過小cmd_num = 1;2;Modbus_sBuf0=rBuf0;Modbus_sBuf1=rBuftl;Modbus_sBuf2=rBuf2;Modbus_sBuf3=rBuf3;Modbus_sBuf 4 = bytes»8;Modbus_sBuf5 = bytes;bytes = cmd_num *2;Modbus_sBuf6 = Modbus_TCP_Addr;Modbus.sBuf7 =

50、 rBuf7;Modbus_sBuf8 = bytes;Send_Function(Modbus_sBuf, 9+bytes);)將數(shù)據(jù)寫入modbus緩存,注:TCP_06指令數(shù)據(jù)位從10開始if(Modbus_Write_Buffer(rBuf+10, (index-Modbus_Start_Addr)*2, cmd_num*2) (#if REC.WRITE/=記錄寫入操作=Modbus_Wr i t e_WRecord(index-Modbus_St art_Addr, cmd_num, 1);#endifif(rBuf6 != 0)本語句存在時,不響應(yīng)廣播幀(地址0);屏蔽后,響應(yīng)廣播幀。/=返回指令Modbus_sBuf0=rBuf0;Modbus_sBuf1Modbus_sBuf2=rBuf2;Modbus.sBuf3=rBuf3;Modbus.sBuf4 = 0;Modbus_sBuf5 = 6;Modbus_sBuf

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論