版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Modbus-RTU 和 Modbus-TCP 协议模板(C 语言)目录简介:2Modbus-RTU 简介:2Modbus-TCP 3System, h: 4CRC_Check. h5CRC_Check. c5Modbus.RTU.h,8Modbus_RTU. c10Modbus_TCP. h.27Modbus_TCP. c27第2页简介:在单片机内部实现modbus协议,可以简单地将变量的值映射到modbus寄存器地址,这种方法是高效 的,但是有以下缺点:1、通常不支持一条指令操作多个变量(寄存器);2、可移植性较差。本模板使用8位数组模拟modbus寄存器。06, 10指令均对数组进行写操
2、作,同时记录寄存器的写入操 作,在其他地方定时判断“写入标志”,将“写入标志”置位的“模拟寄存器”的值转移到相关变量,或 进行其他操作。03指令读取最新数据,要求定时将变量的值写入“模拟寄存器”。本模板缺点是占用资源较多、效率较低,优点是完整支持了 modbus的03, 06, 10指令。Modbus-RTU 简介:1、Modbus读寄存器指令(0x03)地址(1B) +功能码(1B) +起始地址(2B) +寄存器数量(2B) +CRC (2B)返回:地址(1B) +功能码(1B) +字节数(1B) +数据值(2* “寄存器数量" Bytes或者“字节数”)+CRC(2B)2、Mod
3、bus写单个寄存器指令(0x06)地址(1B) +功能码(1B) +寄存器地址(2B) + 数据值(2B) +CRC (2B)返回:地址(1B) +功能码(1B) +寄存器地址(2B) +数据值(2B) +CRC (2B)(返回与发送的指令相同)3、Modbus写多个寄存器指令(0x10)地址(IB) +功能码(IB) +起始地址(2B)+CRC (2B)+写寄存器数量(2B n) +字节计数数B n*2) +数据存*2 B)返回:地址(1B) +功能码(1B) +起始地址(2B)+写寄存器数量(2B) +CRC(2B)Modbus-TCP 简介:在MODBUS-RTU前添加6个字节,并删除M
4、ODBUS-RTU的CRC校验。示例指令:0051 0000 0009 01 10 0001 0001 02 00 006个字节部分称为“MBAP报文头”示例:0051 0000 00090051是客户端发出的校验信息,服务端原内容返回即可0000 表示 modbus-tcp 协议0009表示后面还有9个字节后面部分:01 10 0001 0001 02 00 0001设备地址10表示10指令0001起始地址0001写寄存器数量02字节计数00 00数据响应指令:0051 0000 0006 01 10 0001 0001System, h:#ifndef SYSTEM H define SY
5、STEM Hinclude ”stm32f10x. h:=不常改动项* stm32f lOx. h 第 505、506、507 行已经定义了 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校验函数,查表法*/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;记录写入操作。*需要将数据存储到其他地方时,需要开启“记录写入功能”。* /#define RECJ'RITE 1定义MODBUS缓存大小(8位)* 寄存器数量二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;设为0, STM32设为1)发送缓存由外部定义时,使用上面的定义方法。/modbus缓存(定义为8位方便传输)/modbus起始地址/0二不转换字节顺序,1二允许转换字节顺序(51单片机#if REC.WRITEu8 ModbusjmecordM0DBUS_BUFFER_LEN/16 +1; 记录modbus寄存器的写入操作。需要将数据存储到 其他地方时,需要开启“写入记录功能”。#endif*读modbus寄存器(16位)写入状态 start:起始地址* length:寄存器个数* 返回: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位)写入状态* start: 起始地址* length:寄存器
23、个数* sta:写入状态,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位变量存储顺序转换 ul6 Modbus_16BitsSwapEndian(u
26、l6 num) (if(Mo dbu s_Swap_End i an)(return num«8 num»8;else return num;* 32位变量存储顺序转换 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位变量存储顺序转换 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数据帧* 返回0:不通过* 返回L发往本机的数据* 返回2:广播数据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;待操作寄存器的数量ul6 bytes;字节数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指令的数据位从3开始if(Modbus_Read_Buffer(Modbus_sBuf+3, (index-Modbus_Start_Addr)*2, cmd_num*2)if (rBuf 0 != 0) 本语句存在时,不响应广播帧(地址0);屏蔽后,响应广播帧。/=返回指令bytes = cmd-num 解析06H指令,写单个寄存器voi
32、d Modbus_RTU_06H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x)ul6 index;寄存器索引ul6 cmd_num;待操作寄存器的数量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;将数据写入modbus缓存。注:RTU/6指令数据位从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)本语句存在时,不响应广播帧(地址0);屏蔽后,响应广播帧°/=返回指令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;待操作寄存器的数量ul6 crc;crc 校验index = rBuf 2«8rBuf 3;if (index < Modbus_Start_Addr) return; 地址过小cmd_num = rBuf 4 «8 rBuf 5;将数据写入mod
36、bus缓存。注:RTUO指令数据位从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)本语句存在时,不响应广播帧(地址0);屏蔽后,响应广播帧。二= 返回指令 =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协议处理程序 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),需转换变量存储顺序。可重定义寄存器的变量u8 *numAlH = (u8 *) (ul6 *)Modbus_Buffer+0);u8 *numAlL = (u8 *) (ul6 *)Modbus.BufferO)+1; 此处的 0二寄存器序号(16 位),此处的 1 表示 转换成(u8 *)数组后,往后偏移一个序号。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)固定寄存器的数组(注意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* /)*示例函数:判断modbus写入操作。*/#if REC.WRITEvoid Mo
44、dbus_WRecod_Example(void)(if (Modbus_Read_Oecord(4,1)(清除写入状态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数据帧*返回0:不通过*返回1:发往本机的数据*返回2:广播数据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地址。可以定义为在其他地方定义的地址,例如 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协议。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;待操作寄存器的数量ul6 bytes;字节数index = rBuf 8«8rBuf 9;if (index < Modbus_Start_Addr) return; 地址过小 cmd_num = rBuf 10«8 rBuf Ell
48、;读取modbus缓存。注:TCP_03指令的数据位从9开始if(Modbus_Read_Buffer(Modbus_sBuf+9, (index-Modbus_Start_Addr)*2,cmd_num*2)if(rBuf6 != 0)本语句存在时,不响应广播帧(地址0):屏蔽后,响应广播帧,/=返回指令 bytes = 3 + cmd_num » «»» 解析06H指令,写单个寄存器void Modbus_TCP_06H(u8 *rBuf, void(*Send_Function)(u8 *string,ul6 x) (ul6 index;寄存器索引
49、ul6 cmd_num;待操作寄存器的数量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);)将数据写入modbus缓存,注:TCP_06指令数据位从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)本语句存在时,不响应广播帧(地址0);屏蔽后,响应广播帧。/=返回指令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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年高职第一学年(园林工程技术)园林工程测量试题及答案
- 2025年中职生物制药技术(生物制药)技能测试题
- 2025年高职建筑经济管理(建筑经济管理应用)试题及答案
- 2025年大学第三学年(新闻学)媒介经营管理基础试题及答案
- 2025年大学教育原理(教学设计)试题及答案
- 2025年大学文学(文学理论)试题及答案
- 深度解析(2026)《GBT 18114.6-2010稀土精矿化学分析方法 第6部分:二氧化硅量的测定》
- 深度解析(2026)《GBT 17980.99-2004农药 田间药效试验准则(二) 第99部分杀菌剂防治杧果贮藏期炭疽病》
- 深度解析(2026)《GBT 17958-2000手持式机械作业防振要求》
- 高精度有限元网格划分准则探讨
- 2025-2030中国氯碱行业市场发展分析及发展趋势预测研究报告
- 香港合作合同范本格式
- 2025年苏锡常镇高三语文一模作文素材积累及范文:我会洗碗
- 造血干细胞移植治疗儿童再生障碍性贫血的疗效分析
- 饮食遗传与生活方式研究-深度研究
- 《血管活性药物静脉输注护理》团体标准解读课件
- 高考语文复习:文言文特殊句式 课件
- 手扶拖拉机保养手册
- 安全生产专题工作会议
- 零星工程维修合同模板
- 2023年全国人大机关直属事业单位招聘考试真题
评论
0/150
提交评论