- 1. 1.1、编写原因
- 2. 1.2、版权说明
- 3. 1.3、更新记录
- 4. 4.1.1、function code枚举
- 5. 4.1.2、Modbus状态枚举
- 6. 4.1.3、站信息结构
- 7. 4.1.4、生成访问从站PDU单元函数
- 8. 4.1.5、Parse读取的返回data函数
- 9. 4.1.6、从站生成读data命令的Responsemessage函数
- 10. 4.1.7、function code检验函数
- 11. 4.1.8、生成TCP客户端命令函数
- 12. 4.1.9、生成TCP服务器Response函数
- 13. 4.1.10、CRC check检查
- 14. 4.1.11、生成读写RTU从站的主站命令函数
- 15. 4.1.12、生成从站应答信息message函数
- 16. 4.1.13、LRC verification检查函数
- 17. 4.1.14、将ASCII消息转换为hexadecimal
- 18. 4.1.15、生成读写ASCII从站的命令函数
- 19. 4.1.16、生成ASCII从站应答主站命令的函数
- 20. 4.2.1、RTU主站对象与从站对象
- 21. 4.2.2、RTU主站对象初始化函数
- 22. 4.2.3、生成RTU主站访问从站命令函数
- 23. 4.2.4、RTU主站Parse从站的Response函数
- 24. 4.2.5、RTU主站Parse从站返回消息命令匹配函数
- 25. 4.2.6、RTU从站Parse主站访问命令函数
- 26. 4.2.7、TCP客户端对象与TCP服务器对象
- 27. 4.2.8、TCP客户端对象初始化函数
- 28. 4.2.9、生成TCP客户端访问服务器命令函数
- 29. 4.2.10、TCP客户端Parse服务器返回信息函数
- 30. 4.2.11、TCP服务器Parse客户端命令函数
- 31. 4.2.12、ASCII主站对象与从站对象
- 32. 4.2.13、ASCII主站对象初始化函数
- 33. 4.2.14、生成访问ASCII从站的命令
- 34. 4.2.15、ASCII主站Parse从站的Response函数
- 35. 4.2.16、ASCII主站Parse从站返回消息命令匹配函数
- 36. 4.2.17、ASCII从站Parse主站访问命令函数
- 37. 4.3.1、获取线圈量值的函数
- 38. 4.3.2、获取input state值的函数
- 39. 4.3.3、获取保持register value的函数
- 40. 4.3.4、获取输入register value的函数
- 41. 4.3.5、设置单个线圈的值函数
- 42. 4.3.6、设置单个register value的函数
- 43. 4.3.7、设置Multiple coil values的函数
- 44. 4.3.8、设置Multiple register values的函数
- 45. 4.3.9、从站更新obtained的线圈量值的函数
- 46. 4.3.10、从站更新obtained的input state值的函数
- 47. 4.3.11、从站更新保持register value的函数
- 48. 4.3.12、从站更新输入register value得函数
第1章 前言
Modbus是全球第一个真正用于工业现场的总线协议。Modbus通讯在工业网络通讯中应用十分广泛,而且方便,受到大家的欢迎。
1.1、编写原因
一直以来,在我们自己的产品和项目中都多次使用Modbus通讯协议。每次都是使用者自行开发或者网上Search符合要求的源码。但每次的应用都有不同,每次都需要很多的重复劳动。而且协议站如应用软件的紧密结合也使得代码有些混乱。所以一直以来都想要开发一个比较通用的协议栈能在后续的项目中复用,而不必每次都写一遍。现在利用项目研发的机会,开发一个自己的Modbus协议栈。
1.2、版权说明
本套软件最初虽然是为了我们自用而开发,但现已在GitHub上开源。所以任何人都可以Copy、传播和使用,无论是个人学习还是商业应用都没有限制。对应用方法及修改欢迎探讨,但对于在使用过程中出现了任何问题我们均不负责。
软件源码及其说明可以上GitHub自由Download,Downloadaddress:https://github.com/foxclever/Modbus
1.3、更新记录
前一个版本我们已经实现了基于串行链路的Modbus RTU和基于以太网的Modbus TCP两种。在这一个版本中,我们添加了基于串行链路的Modbus ASCII方式。并对上一个版本中已知的问题做了修正。
软件设计及本Document更新记录如下:
| 版本 | 更新说明 | Author | 日期 |
| V1.0.0 | 初版,共5章,介绍了主要API函数 | 木南 | 2015年5月8日 |
| V1.1.0 | 添加了第6、7两章 | 木南 | 2016年12月23日 |
| V1.1.5 | 修改了3、4、5三章的大部分内容 | 木南 | 2018年2月20日 |
| V2.0.0 | 增加了ASCIIRelated内容,并修改已知问题 | 木南 | 2018年9月18日 |
| V2.1.0 | 增加了RTU和ASCII多主站Operation的类容;增加了TCP客户端多网段Operation的内容。 | 木南 | 2019年4月29日 |
第2章、PDU函数
在应用data单元我们处理Modbusdata通讯的基本messageformat,这些基本是通用的,目前版本只支持01、02、03、04、05、06、15、16function code。
4.1.1、function code枚举
/*定义Modbus的Operationfunction code,支持01、02、03、04、05、06、15、16function code*/
typedef enum {
ReadCoilStatus=0x01, /*读Coil status(读多个输出位的状态)*/
ReadInputStatus=0x02, /*读输入位状态(读多个输入位的状态)*/
ReadHoldingRegister=0x03, /*读保持register(读多个保持register的numerical value)*/
ReadInputRegister=0x04, /*读输入register(读多个输入register的numerical value)*/
WriteSingleCoil=0x05, /*强制单个线圈(强制单个输出位的状态)*/
WriteSingleRegister=0x06, /*预制单个register(设定一个register的numerical value)*/
WriteMultipleCoil=0x0F, /*强制多个线圈(强制多个输出位的状态)*/
WriteMultipleRegister=0x10 /*预制多个register(设定多个register的numerical value)*/
}FunctionCode;
4.1.2、Modbus状态枚举
/*定义receive到指令检测Error时的Error码*/
typedef enum{
MB_OK=0x00,
InvalidFunctionCode=0x01,//不合法Function代码
IllegalDataAddress=0x02,//非法的dataaddress
IllegalDataValues=0x03,//非法的data值或者范围
OperationFail=0x04
}ModbusStatus;
4.1.3、站信息结构
/*定义用于传递要访问从站(服务器)的信息*/
typedef struct{
uint8_t unitID;
FunctionCode functionCode;
uint16_t startingAddress;
uint16_t quantity;
}ObjAccessInfo;
定义用于传递从站(服务器)访问的各种信息,包括站号、function code、starting address和quantity。
4.1.4、生成访问从站PDU单元函数
/*作为RTU主站(TCP客户端)时,生成读写RTU从站(TCP服务器)对象的命令*/
uint16_t GenerateReadWriteCommand(ObjAccessInfo objInfo,bool *statusList,uint16_t *registerList,uint8_t commandBytes[]);
参数:ObjAccessInfo objInfo,要访问的从站对象
bool *statusList,需要往下写的状态量对象data列表
uint16_t *registerList,需要往下写的register量对象的data列表
uint8_t commandBytes[],生成的访问命令
返回值:生成的访问命令的Length,以byte为单位。
4.1.5、Parse读取的返回data函数
/*Parse主站(客户端)从服务器读取的data*/
void TransformClientReceivedData(uint8_t * receivedMessage,uint16_t quantity,bool *statusList,uint16_t *registerLister);
参数:uint8_t * receivedMessage,receive到的信息message
uint16_t quantity,读取的对象quantity
bool *statusList,Parse出来的读取到的状态对象的data列表
uint16_t *registerLister,Parse出来的读取到的register对象的data列表
返回值:无
4.1.6、从站生成读data命令的Responsemessage函数
/*生成主站读访问的Response,包括0x01、0x02、0x03、0x04function code,返回相应信息的Length*/
uint16_t GenerateMasterAccessRespond(uint8_t *receivedMesasage,bool *statusList,uint16_t *registerList,uint8_t *respondBytes);
参数:uint8_t *receivedMesasage,receive到的主战读Operationmessage
bool *statusList,读取的从站状态对象data列表
uint16_t *registerList,读取到的从站register对象data列表
uint8_t *respondBytes,生成的从站Responsemessage信息
返回值:Responsemessage的Length,以byte为单位
4.1.7、function code检验函数
/*检查function code是否正确*/
ModbusStatus CheckFunctionCode(FunctionCode fc);
参数:FunctionCode fc,function code,由枚举定义
返回值:ModbusOperation状态,由枚举定义
4.1.8、生成TCP客户端命令函数
//生成读写服务器对象的命令
uint16_t SyntheticReadWriteTCPServerCommand(ObjAccessInfo objInfo,bool *statusList,uint16_t *registerList,uint8_t *commandBytes);
参数:ObjAccessInfo objInfo,TCP服务器访问信息对象
bool *statusList,写服务器状态量对象data列表
uint16_t *registerList,写服务器register量对象data列表
uint8_t *commandBytes,Generated commands信息message
返回值:命令的Length,以byte为单位
4.1.9、生成TCP服务器Response函数
/*合成对服务器访问的Response*/
uint16_t SyntheticServerAccessRespond(uint8_t *receivedMesasage,bool *statusList,uint16_t *registerList,uint8_t *respondBytes);
参数:uint8_t *receivedMesasage,receive到的客户端命令信息message
bool *statusList,读TCP服务器的状态量对象data列表
uint16_t *registerList,读TCP服务器的register量对象data列表
uint8_t *respondBytes,生成的Response客户端命令的Response信息message
返回值:Response信息messageLength,以byte为单位
4.1.10、CRC check检查
/*通过CRC checkreceive的信息是否正确*/
bool CheckRTUMessageIntegrity (uint8_t *message,uint8_t length);
参数:uint8_t *message,待校验的datamessage
uint8_t length,带教言的datamessageLength,以byte为单位
返回值:返回校验是否通过的状态信号
4.1.11、生成读写RTU从站的主站命令函数
/*生成读写从站data对象的命令,命令Length包括2个校验byte*/
uint16_t SyntheticReadWriteSlaveCommand(ObjAccessInfo slaveInfo,bool *statusList,uint16_t *registerList,uint8_t *commandBytes);
参数:ObjAccessInfo slaveInfo,从站访问信息对象,由结构体定义
bool *statusList,写从站状态量data列表
uint16_t *registerList,写从站register量data列表
uint8_t *commandBytes,生成的访问命令message
返回值:访问命令的Length,以byte为单位
4.1.12、生成从站应答信息message函数
/*生成从站应答主站的Response*/
uint16_t SyntheticSlaveAccessRespond(uint8_t *receivedMesasage,bool *statusList,uint16_t *registerList,uint8_t *respondBytes);
参数:uint8_t *receivedMesasage,
bool *statusList,
uint16_t *registerList,
uint8_t *respondBytes,
返回值:生成的Response信息message的Length,以byte为单位
4.1.13、LRC verification检查函数
/*判断ASCIIdata信息是否正确*/
bool CheckASCIIMessageIntegrity(uint8_t *usMsg, uint16_t usLength)
参数:uint8_t *usMsg,待校验的消息列表,hexadecimaldata
uint16_t usLength,待校验的消息列表的Length
返回值:校验结果,校验正确返回“true”,否则返回“false”
4.1.14、将ASCII消息转换为hexadecimal
/*receive到的ASCII消息转换为hexadecimal*/
bool CovertAsciiMessageToHex(uint8_t *aMsg, uint8_t *hMsg, uint16_t aLen);
参数:uint8_t *aMsg,ASCII码信息
uint8_t *hMsg,转换后的hexadecimal信息
uint16_t aLen,ASCII码信息的Length
返回值:转换是否正确,转换正确返回“true”,否则返回“false”
4.1.15、生成读写ASCII从站的命令函数
/*生成读写从站的命令,应用于主站,含校验及startEnd符*/
uint16_t SyntheticReadWriteAsciiSlaveCommand(ObjAccessInfo slaveInfo, bool *statusList, uint16_t *registerList, uint8_t *commandBytes)
参数:ObjAccessInfo slaveInfo,从站访问信息对象,由结构体定义
bool *statusList,写从站状态量data列表
uint16_t *registerList,写从站register量data列表
uint8_t *commandBytes,生成的访问命令message
返回值:访问命令的Length,以byte为单位
4.1.16、生成ASCII从站应答主站命令的函数
/*生成应答主站的Response,应用于从站*/
uint16_t SyntheticAsciiSlaveAccessRespond(uint8_t *receivedMessage, bool *statusList, uint16_t *registerList, uint8_t *respondBytes)
参数:uint8_t *receivedMesasage,接受到主站message信息
bool *statusList,主站命令要读取的状态量值列表
uint16_t *registerList,主站命令要读取的register量值列表
uint8_t *respondBytes,生成的Response信息message
返回值:生成的Response信息message的Length,以byte为单位
第3章、应用封装函数
对应用级封装,我们只封装RTU主站应用,RTU从站应用、TCP客户端应用和TCP服务器端应用四类。
4.2.1、RTU主站对象与从站对象
/* 定义被访问RTU从站对象Type */
typedef struct AccessedRTUSlaveType{
uint8_t stationAddress; //站address
uint8_t cmdOrder; //当前命令在命令列表中的位置
uint16_t commandNumber; //命令列表中命令的总数
uint8_t (*pReadCommand)[8]; //读命令列表
uint8_t *pLastCommand; //上一次send的命令
uint32_t flagPresetCoil; //预置线圈控制标志位
uint32_t flagPresetReg; //预置register控制标志位
}RTUAccessedSlaveType;
/* 定义本地RTU主站对象Type */
typedef struct LocalRTUMasterType{
uint32_t flagWriteSlave[8]; //写一个站控制标志位,最多256个站,与站address对应。
uint16_t slaveNumber; //从站列表中从站的quantity
uint16_t readOrder; //当前从站在从站列表中的位置
RTUAccessedSlaveType *pSlave; //从站列表
UpdateCoilStatusType pUpdateCoilStatus; //更新线圈量函数
UpdateInputStatusType pUpdateInputStatus; //更新input state量函数
UpdateHoldingRegisterType pUpdateHoldingRegister; //更新保持register量函数
UpdateInputResgisterType pUpdateInputResgister; //更新输入register量函数
}RTULocalMasterType;
4.2.2、RTU主站对象初始化函数
/*初始化RTU主站对象*/
void InitializeRTUMasterObject(RTULocalMasterType *master,uint16_t slaveNumber,RTUAccessedSlaveType *pSlave,UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHoldingRegisterType pUpdateHoldingRegister,UpdateInputResgisterType pUpdateInputResgister);
参数:RTULocalMasterType *master,本地主站对象
uint16_t slaveNumber,从站的quantity
RTUAccessedSlaveType *pSlave,从站列表
UpdateCoilStatusType pUpdateCoilStatus,更新线圈量函数指针
UpdateInputStatusType pUpdateInputStatus,更新状态量函数指针
UpdateHoldingRegisterType pUpdateHoldingRegister,更新保持register量函数指针
UpdateInputResgisterType pUpdateInputResgister,更新输入register量函数指针
返回值:无返回值
4.2.3、生成RTU主站访问从站命令函数
/*生成访问服务器的命令*/
uint16_t CreateAccessSlaveCommand(ObjAccessInfo objInfo,void *dataList,uint8_t *commandBytes);
参数:ObjAccessInfo objInfo,从站访问信息对象,由结构体定义
void *dataList,写从站对象的data列表
uint8_t *commandBytes,Generated commandsmessage
返回值:生成的访问命令的Length,以byte为单位
4.2.4、RTU主站Parse从站的Response函数
/*Parse收到的服务器Response信息*/
void ParsingSlaveRespondMessage(uint8_t *recievedMessage,uint8_t *command);
参数:uint8_t *recievedMessage,receive到的返回信息
uint8_t *command,已经下发到从站的命令列表
返回值:无
4.2.5、RTU主站Parse从站返回消息命令匹配函数
/*receive到返回信息后,判断是否是send command列表中命令的返回信息*/
int FindCommandForRecievedMessage(uint8_t *recievedMessage,uint8_t (*commandList)[8],uint16_t commandNumber);
参数:uint8_t *recievedMessage,receive的从站返回信息
uint8_t (*commandList)[8],主站下发过的命令列表
uint16_t commandNumber,存储的命令的条数
返回值:返回匹配命令所在的位置,无匹配时,返回“-1”
本函数只在RTU主站中,访问的data量大且频繁,或者访问多个从站时使用,便于作正确的dataParse。
4.2.6、RTU从站Parse主站访问命令函数
/*Parsereceive到的信息,并返回合成的回复信息和信息的byteLength,通过回调函数*/
uint16_t ParsingMasterAccessCommand(uint8_t *receivedMesasage,uint8_t *respondBytes,uint16_t rxLength);
参数:uint8_t *receivedMesasage,receive到的主站message信息
uint8_t *respondBytes,Generate response信息message
uint16_t rxLength,receive到的message的Length
返回值:生成的Response信息的Length,以byte为单位
4.2.7、TCP客户端对象与TCP服务器对象
/* 定义被访问TCP服务器对象Type */
typedef struct AccessedTCPServerType{
union {
uint32_t ipNumber;
uint8_t ipSegment[4];
}ipAddress; //服务器的IPaddress
uint32_t flagPresetServer; //写服务器Request标志
WritedCoilListHeadNode pWritedCoilHeadNode; //可写的线圈量列表
WritedRegisterListHeadNode pWritedRegisterHeadNode; //可写的保持register列表
struct AccessedTCPServerType *pNextNode; //下一个TCP服务器节点
}TCPAccessedServerType;
/* 定义服务器链表头Type */
typedef struct ServerListHeadType {
TCPAccessedServerType *pServerNode; //服务器节点指针
uint32_t serverNumber; //服务器的quantity
}ServerListHeadNode;
/* 定义本地TCP客户端对象Type */
typedef struct LocalTCPClientType{
uint32_t transaction; //Transaction identifier
uint16_t cmdNumber; //读服务器命令的quantity
uint16_t cmdOrder; //当前从站在从站列表中的位置
uint8_t (*pReadCommand)[12]; //读命令列表
ServerListHeadNode ServerHeadNode; //Server对象链表的头节点
UpdateCoilStatusType pUpdateCoilStatus; //更新线圈量函数
UpdateInputStatusType pUpdateInputStatus; //更新input state量函数
UpdateHoldingRegisterType pUpdateHoldingRegister; //更新保持register量函数
UpdateInputResgisterType pUpdateInputResgister; //更新输入register量函数
}TCPLocalClientType;
4.2.8、TCP客户端对象初始化函数
/*初始化TCP客户端对象*/
void InitializeTCPClientObject(TCPLocalClientType *client,uint16_t cmdNumber,uint8_t (*pReadCommand)[12],UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHoldingRegisterType pUpdateHoldingRegister,UpdateInputResgisterType pUpdateInputResgister);
参数:TCPLocalClientType *client,客户端对象
uint16_t cmdNumber,读命令的quantity
uint8_t (*pReadCommand)[12],读命令列表
UpdateCoilStatusType pUpdateCoilStatus,更新线圈量函数指针
UpdateInputStatusType pUpdateInputStatus,更新状态量函数指针
UpdateHoldingRegisterType pUpdateHoldingRegister,更新保持register函数指针
UpdateInputResgisterType pUpdateInputResgister,更新输入register量函数指针
返回值:无返回值
4.2.9、生成TCP客户端访问服务器命令函数
/*生成访问服务器的命令*/
uint16_t CreateAccessServerCommand(ObjAccessInfo objInfo,void *dataList,uint8_t *commandBytes);
参数:ObjAccessInfo objInfo,访问服务器信息对象
void *dataList,些服务器对象data列表
uint8_t *commandBytes,生成的访问服务器命令message
返回值:访问命令的Length,以byte为单位
4.2.10、TCP客户端Parse服务器返回信息函数
/*Parse收到的服务器相应信息*/
void ParsingServerRespondMessage(uint8_t *recievedMessage);
参数:uint8_t *recievedMessage,接受到的服务器Response信息
返回值:无
4.2.11、TCP服务器Parse客户端命令函数
/*Parsereceive到的信息,返回Response命令的Length*/
uint16_t ParsingClientAccessCommand(uint8_t *receivedMessage,uint8_t *respondBytes);
参数:uint8_t *receivedMessage,接受到的客户端访问命令
uint8_t *respondBytes,生成的服务器Response信息
返回值:生成的Response信息message的Length,以byte为单位
4.2.12、ASCII主站对象与从站对象
/* 定义被访问ASCII从站对象Type */
typedef struct AccessedASCIISlaveType{
uint8_t stationAddress; //站address
uint8_t cmdOrder; //当前命令在命令列表中的位置
uint16_t commandNumber; //命令列表中命令的总数
uint8_t (*pReadCommand)[17]; //读命令列表
uint8_t *pLastCommand; //上一次send的命令
uint32_t flagPresetCoil; //预置线圈控制标志位
uint32_t flagPresetReg; //预置register控制标志位
}AsciiAccessedSlaveType;
/* 定义本地ASCII主站对象Type */
typedef struct LocalASCIIMasterType{
uint32_t flagWriteSlave[8]; //写一个站控制标志位,最多256个站,与站address对应。
uint16_t slaveNumber; //从站列表中从站的quantity
uint16_t readOrder; //当前从站在从站列表中的位置
AsciiAccessedSlaveType *pSlave; //从站列表
UpdateCoilStatusType pUpdateCoilStatus; //更新线圈量函数
UpdateInputStatusType pUpdateInputStatus; //更新input state量函数
UpdateHoldingRegisterType pUpdateHoldingRegister; //更新保持register量函数
UpdateInputResgisterType pUpdateInputResgister; //更新输入register量函数
}AsciiLocalMasterType;
4.2.13、ASCII主站对象初始化函数
/*初始化RTU主站对象*/
void InitializeASCIIMasterObject(AsciiLocalMasterType *master,uint16_t slaveNumber,AsciiAccessedSlaveType *pSlave,UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHoldingRegisterType pUpdateHoldingRegister,UpdateInputResgisterType pUpdateInputResgister);
参数:AsciiLocalMasterType *master,ASCII主站对象
uint16_t slaveNumber,从站的quantity
AsciiAccessedSlaveType *pSlave,从站列表
UpdateCoilStatusType pUpdateCoilStatus,更新线圈量回调函数
UpdateInputStatusType pUpdateInputStatus,更新状态量回调函数
UpdateHoldingRegisterType pUpdateHoldingRegister,更新保持register量回调函数
UpdateInputResgisterType pUpdateInputResgister,更新输入register量回调函数
返回值:无返回值
4.2.14、生成访问ASCII从站的命令
/*生成访问ASCII从站的命令*/
uint16_t CreateAccessAsciiSlaveCommand(ObjAccessInfo objInfo,void *dataList,uint8_t *commandBytes);
参数:ObjAccessInfo objInfo,从站访问信息对象,由结构体定义
void *dataList,写从站对象的data列表
uint8_t *commandBytes,Generated commandsmessage
返回值:生成的访问命令的Length,以byte为单位
4.2.15、ASCII主站Parse从站的Response函数
/*Parse收到的服务器相应信息*/
void ParsingAsciiSlaveRespondMessage(uint8_t *recievedMessage, uint8_t *command,uint16_t rxLength);
参数:uint8_t *recievedMessage,receive到的返回信息
uint8_t *command,已经下发到从站的命令列表
uint16_t rxLength,receive到的消息的Length
返回值:无
4.2.16、ASCII主站Parse从站返回消息命令匹配函数
/*receive到返回信息后,判断是否是send command列表中命令的返回信息*/
int FindAsciiCommandForRecievedMessage(uint8_t *recievedMessage,uint8_t (*commandList)[17],uint16_t commandNumber);
参数:uint8_t *recievedMessage,receive的从站返回信息
uint8_t (*commandList)[17],主站下发过的命令列表
uint16_t commandNumber,存储的命令的条数
返回值:返回匹配命令所在的位置,无匹配时,返回“-1”
本函数只在RTU主站中,访问的data量大且频繁,或者访问多个从站时使用,便于作正确的dataParse。
4.2.17、ASCII从站Parse主站访问命令函数
/*Parsereceive到的信息,并返回合成的回复信息和信息的byteLength,通过回调函数*/
uint16_t ParsingAsciiMasterAccessCommand(uint8_t *receivedMessage, uint8_t *respondBytes, uint16_t rxLength, uint8_t StationAddress);
参数:uint8_t *receivedMesasage,receive到的主站message信息
uint8_t *respondBytes,Generate response信息message
uint16_t rxLength,receive到的message的Length
返回值:生成的Response信息的Length,以byte为单位
第4章、data处理函数
具体应用中还涉及到对data对想的处理,不同的应用data结构与处理方式千差万别,所以定义一些回调函数(实际使用弱化的函数__weak关键字)用于data的处理。
4.3.1、获取线圈量值的函数
/*获取想要读取的Coil量的值*/
__weak void GetCoilStatus(uint16_t startAddress,uint16_t quantity,bool *statusList)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,要读取对象的starting address
uint16_t quantity,要读取对象的quantity
bool *statusList,获取的线圈量的data值列表
返回值:无
4.3.2、获取input state值的函数
/*获取想要读取的InputStatus量的值*/
__weak void GetInputStatus(uint16_t startAddress,uint16_t quantity,bool *statusValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,要读取对象的starting address
uint16_t quantity,要读取对象的quantity
bool *statusValue,获取的input state量的data值列表
返回值:无
4.3.3、获取保持register value的函数
/*获取想要读取的保持register的值*/
__weak void GetHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,要读取的保持register对象的starting address
uint16_t quantity,要读取的保持register的quantity
uint16_t *registerValue,获取的保持register的值
返回值:无
4.3.4、获取输入register value的函数
/*获取想要读取的输入register的值*/
__weak void GetInputRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,要读取的输入register的starting address
uint16_t quantity,要读取的输入register的quantity
uint16_t *registerValue,获取的输入register的值
返回值:无
4.3.5、设置单个线圈的值函数
/*设置单个线圈的值*/
__weak void SetSingleCoil(uint16_t coilAddress,bool coilValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t coilAddress,所需要预置值的Coil address
bool coilValue,所预置的值
返回值:无
4.3.6、设置单个register value的函数
/*设置单个register的值*/
__weak void SetSingleRegister(uint16_t registerAddress,uint16_t registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t registerAddress,所预置的保持register的address
uint16_t registerValue,所预置的保持register的值
返回值:无
4.3.7、设置Multiple coil values的函数
/*设置多个线圈的值*/
__weak void SetMultipleCoil(uint16_t startAddress,uint16_t quantity,bool *statusValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,要预置的多个线圈的starting address
uint16_t quantity,所要预知的线圈的quantity
bool *statusValue,要预知的线圈值的列表
返回值:无
4.3.8、设置Multiple register values的函数
/*设置多个register的值*/
__weak void SetMultipleRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//如果需要Modbus TCP Server/RTU Slave应用中实现具体内容
}
参数:uint16_t startAddress,所预置的多个保持register的starting address
uint16_t quantity,所要预置的保持register的quantity
uint16_t *registerValue,预知的保持register value的列表
返回值:无
4.3.9、从站更新obtained的线圈量值的函数
/*更新读回来的Coil status*/
__weak void UpdateCoilStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)
{
//在客户端(主站)应用中实现
}
参数:uint16_t startAddress,读取值的线圈对象的starting address
uint16_t quantity,所读取的线圈的quantity
bool *stateValue,读取的Coil address的列表
返回值:无
本程序为默认处理函数,各个主站对象可以单独定义更新函数,若没有定义则调用本函数。
4.3.10、从站更新obtained的input state值的函数
/*更新读回来的input state值*/
__weak void UpdateInputStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)
{
//在客户端(主站)应用中实现
}
参数:uint16_t startAddress,所读取的input state对象的starting address
uint16_t quantity,所读取的input state对象的quantity
bool *stateValue,读取到的input state对象的值
返回值:无
本程序为默认处理函数,各个主站对象可以单独定义更新函数,若没有定义则调用本函数。
4.3.11、从站更新保持register value的函数
/*更新读回来的保持register*/
__weak void UpdateHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//在客户端(主站)应用中实现
}
参数:uint16_t startAddress,所读取的保持register对象的starting address
uint16_t quantity,所读取的保持register对象的data
uint16_t *registerValue,读取到的保持register对象值列表
返回值:无
本程序为默认处理函数,各个主站对象可以单独定义更新函数,若没有定义则调用本函数。
4.3.12、从站更新输入register value得函数
/*更新读回来的输入register*/
__weak void UpdateInputResgister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)
{
//在客户端(主站)应用中实现
}
参数:uint16_t startAddress,所读取的输入register对象的starting address
uint16_t quantity,所读取的输入register对象的quantity
uint16_t *registerValue,读取到的输入register value得列表
返回值:无
本程序为默认处理函数,各个主站对象可以单独定义更新函数,若没有定义则调用本函数。
第5章 一些Related说明
对于Modbus协议栈的整个开发内容,前面已经说得很清楚了,接下来我们说明一下与开发没有直接关系的内容。
首先,关于我为什么开发这个协议栈的问题。我们的初衷只是想能够在开发产品时不用每次都重写这一部分,而是可以不断的改进和使用达到复用的目的。当然在后来,我们觉得不只是我们自己可以使用,也可以将其公开,让任何愿意使用的人使用。源码网址是:https://github.com/foxclever/Modbus
其次,Modbus协议有国标,包括三个文件。我们这个协议栈就是按照国标开发的标准协议,包括有读写各种Type对象data的Function,在一般的工业应用场合是完全够的。三个标准文件:
GB/T 19582.1-2008 《基于Modbus协议的Automation网络规范 第1部分:Modbus应用协议》
GB/T 19582.2-2008 《基于Modbus协议的Automation网络规范 第1部分:Modbus协议在串行链路上的实现指南》
GB/T 19582.3-2008 《基于Modbus协议的Automation网络规范 第1部分:Modbus协议在TCP/IP上的实现指南》
最后,欢迎大家使用这个协议栈,但我们不就使用的最终结果负责。当然如果发现任何的不足,我们非常并欢迎大家将发现的问题告知我们,以便我们持续的改进之。
感谢您关注本软件,有需要的同仁可以上GitHubDownload,同时欢迎给我们提出改进意见,有兴趣的同仁可以关注我们的公众号:
| Modbus协议栈综合实例参数列表 | ||||||||
| 站address:1;Baud rate:115200;data bit:8;stop bit:1;无校验 | ||||||||
| Serial number | data type | 变量名称 | 参数名称 | address | 读写属性 | 取值范围 | 缺省值 | 描述 |
| 1 | uint32_t | beatTime | 心跳检测 | 40001 | 只读 | 每秒增加1次,监视system是否正常运行 | ||
| 2 | float | mbAI1 | 模拟量测试 | 40003 | 只读 | mbAO1*3 | ||
| 3 | float | mbAO1 | 模拟量测试 | 40005 | 读写 | 0~100.0 | 1.101 | |
| 4 | uint16_t | mbAI2 | 模拟量测试 | 40007 | 只读 | mbAO2*2 | ||
| 5 | uint16_t | mbAO2 | 模拟量测试 | 40008 | 读写 | 0~100 | 1 | 本站变量 |
| 1 | float | mbSalve1AI1 | 目标从站1的模拟量输入参数1 | 40009 | 只读 | 目标从站1模拟参数 | ||
| 2 | uint32_t | mbSalve1AI2 | 目标从站1的模拟量输入参数2 | 40011 | 只读 | 目标从站1模拟参数 | ||
| 5 | uint16_t | mbSalve1AI3 | 目标从站1的模拟量输入参数3 | 40013 | 只读 | 0 | 目标从站1模拟参数 | |
| 6 | uint16_t | mbSalve1AO1 | 目标从站1的模拟量输出参数1 | 40014 | 读写 | 101 | 目标从站1模拟参数 | |
| 7 | uint16_t | mbSalve1AO2 | 目标从站1的模拟量输出参数2 | 40015 | 读写 | 102 | 目标从站1模拟参数 | |
| 8 | uint16_t | mbSalve1AO3 | 目标从站1的模拟量输出参数3 | 40016 | 读写 | 103 | 目标从站1模拟参数 | |
| 1 | float | mbSalve2AI1 | 目标从站2的模拟量输入参数1 | 40017 | 只读 | 目标从站2模拟参数 | ||
| 2 | uint32_t | mbSalve2AI2 | 目标从站2的模拟量输入参数2 | 40019 | 只读 | 目标从站2模拟参数 | ||
| 5 | uint16_t | mbSalve2AI3 | 目标从站2的模拟量输入参数3 | 40021 | 只读 | 0 | 目标从站2模拟参数 | |
| 6 | uint16_t | mbSalve2AO1 | 目标从站2的模拟量输出参数1 | 40022 | 读写 | 目标从站2模拟参数 | ||
| 7 | uint16_t | mbSalve2AO2 | 目标从站2的模拟量输出参数2 | 40023 | 读写 | 0 | 目标从站2模拟参数 | |
| 8 | uint16_t | mbSalve2AO3 | 目标从站2的模拟量输出参数3 | 40024 | 读写 | 0 | 目标从站2模拟参数 | |
| 1 | float | mbSalve3AI1 | 目标从站3的模拟量输入参数1 | 40025 | 只读 | 目标从站3模拟参数 | ||
| 2 | uint32_t | mbSalve3AI2 | 目标从站3的模拟量输入参数2 | 40027 | 只读 | 目标从站3模拟参数 | ||
| 5 | uint16_t | mbSalve3AI3 | 目标从站3的模拟量输入参数3 | 40029 | 只读 | 0 | 目标从站3模拟参数 | |
| 6 | uint16_t | mbSalve3AO1 | 目标从站3的模拟量输出参数1 | 40030 | 读写 | 目标从站3模拟参数 | ||
| 7 | uint16_t | mbSalve3AO2 | 目标从站3的模拟量输出参数2 | 40031 | 读写 | 0 | 目标从站3模拟参数 | |
| 8 | uint16_t | mbSalve3AO3 | 目标从站3的模拟量输出参数3 | 40032 | 读写 | 0 | 目标从站3模拟参数 | |
| 1 | float | mbSalve4AI1 | 目标从站4的模拟量输入参数1 | 40033 | 只读 | 目标从站4模拟参数 | ||
| 2 | uint32_t | mbSalve4AI2 | 目标从站4的模拟量输入参数2 | 40035 | 只读 | 目标从站4模拟参数 | ||
| 5 | uint16_t | mbSalve4AI3 | 目标从站4的模拟量输入参数3 | 40037 | 只读 | 0 | 目标从站4模拟参数 | |
| 6 | uint16_t | mbSalve4AO1 | 目标从站4的模拟量输出参数1 | 40038 | 读写 | 目标从站4模拟参数 | ||
| 7 | uint16_t | mbSalve4AO2 | 目标从站4的模拟量输出参数2 | 40039 | 读写 | 0 | 目标从站4模拟参数 | |
| 8 | uint16_t | mbSalve4AO3 | 目标从站4的模拟量输出参数3 | 40040 | 读写 | 0 | 目标从站4模拟参数 | |
| 1 | bool | mbDI1 | 数字量输入参数1 | 1 | 只读 | 数字量参数 | ||
| 2 | bool | mbDI2 | 数字量输入参数2 | 2 | 只读 | 数字量参数 | ||
| 3 | bool | mbDI3 | 数字量输入参数3 | 3 | 只读 | 数字量参数 | ||
| 4 | bool | mbDI4 | 数字量输入参数4 | 4 | 只读 | 数字量参数 | ||
| 5 | bool | mbDO1 | 数字量输出参数1 | 5 | 读写 | 数字量参数 | ||
| 6 | bool | mbDO2 | 数字量输出参数2 | 6 | 读写 | 数字量参数 | ||
| 7 | bool | mbDO3 | 数字量输出参数3 | 7 | 读写 | 数字量参数 | ||
| 8 | bool | mbDO4 | 数字量输出参数4 | 8 | 读写 | 数字量参数 | ||
| 1 | bool | mbSalve1DI1 | 目标从站1的数字量输入参数1 | 9 | 只读 | 目标从站1数字量参数 | ||
| 2 | bool | mbSalve1DI2 | 目标从站1的数字量输入参数2 | 10 | 只读 | 目标从站1数字量参数 | ||
| 3 | bool | mbSalve1DI3 | 目标从站1的数字量输入参数3 | 11 | 只读 | 目标从站1数字量参数 | ||
| 4 | bool | mbSalve1DI4 | 目标从站1的数字量输入参数4 | 12 | 只读 | 目标从站1数字量参数 | ||
| 5 | bool | mbSalve1DO1 | 目标从站1的数字量输出参数1 | 13 | 读写 | 目标从站1数字量参数 | ||
| 6 | bool | mbSalve1DO2 | 目标从站1的数字量输出参数2 | 14 | 读写 | 目标从站1数字量参数 | ||
| 7 | bool | mbSalve1DO3 | 目标从站1的数字量输出参数3 | 15 | 读写 | 目标从站1数字量参数 | ||
| 8 | bool | mbSalve1DO4 | 目标从站1的数字量输出参数4 | 16 | 读写 | 目标从站1数字量参数 | ||
| 1 | bool | mbSalve2DI1 | 目标从站2的数字量输入参数1 | 17 | 只读 | 目标从站2数字量参数 | ||
| 2 | bool | mbSalve2DI2 | 目标从站2的数字量输入参数2 | 18 | 只读 | 目标从站2数字量参数 | ||
| 3 | bool | mbSalve2DI3 | 目标从站2的数字量输入参数3 | 19 | 只读 | 目标从站2数字量参数 | ||
| 4 | bool | mbSalve2DI4 | 目标从站2的数字量输入参数4 | 20 | 只读 | 目标从站2数字量参数 | ||
| 5 | bool | mbSalve2DO1 | 目标从站2的数字量输出参数1 | 21 | 读写 | 目标从站2数字量参数 | ||
| 6 | bool | mbSalve2DO2 | 目标从站2的数字量输出参数2 | 22 | 读写 | 目标从站2数字量参数 | ||
| 7 | bool | mbSalve2DO3 | 目标从站2的数字量输出参数3 | 23 | 读写 | 目标从站2数字量参数 | ||
| 8 | bool | mbSalve2DO4 | 目标从站2的数字量输出参数4 | 24 | 读写 | 目标从站2数字量参数 | ||
| 1 | bool | mbSalve3DI1 | 目标从站3的数字量输入参数1 | 25 | 只读 | 目标从站3数字量参数 | ||
| 2 | bool | mbSalve3DI2 | 目标从站3的数字量输入参数2 | 26 | 只读 | 目标从站3数字量参数 | ||
| 3 | bool | mbSalve3DI3 | 目标从站3的数字量输入参数3 | 27 | 只读 | 目标从站3数字量参数 | ||
| 4 | bool | mbSalve3DI4 | 目标从站3的数字量输入参数4 | 28 | 只读 | 目标从站3数字量参数 | ||
| 5 | bool | mbSalve3DO1 | 目标从站3的数字量输出参数1 | 29 | 读写 | 目标从站3数字量参数 | ||
| 6 | bool | mbSalve3DO2 | 目标从站3的数字量输出参数2 | 30 | 读写 | 目标从站3数字量参数 | ||
| 7 | bool | mbSalve3DO3 | 目标从站3的数字量输出参数3 | 31 | 读写 | 目标从站3数字量参数 | ||
| 8 | bool | mbSalve3DO4 | 目标从站3的数字量输出参数4 | 32 | 读写 | 目标从站3数字量参数 | ||
| 1 | bool | mbSalve4DI1 | 目标从站4的数字量输入参数1 | 33 | 只读 | 目标从站4数字量参数 | ||
| 2 | bool | mbSalve4DI2 | 目标从站4的数字量输入参数2 | 34 | 只读 | 目标从站4数字量参数 | ||
| 3 | bool | mbSalve4DI3 | 目标从站4的数字量输入参数3 | 35 | 只读 | 目标从站4数字量参数 | ||
| 4 | bool | mbSalve4DI4 | 目标从站4的数字量输入参数4 | 36 | 只读 | 目标从站4数字量参数 | ||
| 5 | bool | mbSalve4DO1 | 目标从站4的数字量输出参数1 | 37 | 读写 | 目标从站4数字量参数 | ||
| 6 | bool | mbSalve4DO2 | 目标从站4的数字量输出参数2 | 38 | 读写 | 目标从站4数字量参数 | ||
| 7 | bool | mbSalve4DO3 | 目标从站4的数字量输出参数3 | 39 | 读写 | 目标从站4数字量参数 | ||
| 8 | bool | mbSalve4DO4 | 目标从站4的数字量输出参数4 | 40 | 读写 | 目标从站4数字量参数 | ||
| 目标从站1参数列表 | ||||||||
| 站address:1;Baud rate:9600;data bit:8;stop bit:1;无校验 | ||||||||
| Serial number | data type | 变量名称 | 参数名称 | address | 读写属性 | 取值范围 | 缺省值 | 描述 |
| 1 | float | mbSalve1AI1 | 目标从站1的模拟量输入参数1 | 40001 | 只读 | 目标从站1模拟参数 | ||
| 2 | uint32_t | mbSalve1AI2 | 目标从站1的模拟量输入参数2 | 40003 | 只读 | 目标从站1模拟参数 | ||
| 5 | uint16_t | mbSalve1AI3 | 目标从站1的模拟量输入参数3 | 40005 | 只读 | 0 | 目标从站1模拟参数 | |
| 6 | uint16_t | mbSalve1AO1 | 目标从站1的模拟量输出参数1 | 40006 | 读写 | 目标从站1模拟参数 | ||
| 7 | uint16_t | mbSalve1AO2 | 目标从站1的模拟量输出参数2 | 40007 | 读写 | 0 | 目标从站1模拟参数 | |
| 8 | uint16_t | mbSalve1AO3 | 目标从站1的模拟量输出参数3 | 40008 | 读写 | 0 | 目标从站1模拟参数 | |
| 1 | bool | mbSalve1DI1 | 目标从站1的数字量输入参数1 | 1 | 只读 | 目标从站1数字量参数 | ||
| 2 | bool | mbSalve1DI2 | 目标从站1的数字量输入参数2 | 2 | 只读 | 目标从站1数字量参数 | ||
| 3 | bool | mbSalve1DI3 | 目标从站1的数字量输入参数3 | 3 | 只读 | 目标从站1数字量参数 | ||
| 4 | bool | mbSalve1DI4 | 目标从站1的数字量输入参数4 | 4 | 只读 | 目标从站1数字量参数 | ||
| 5 | bool | mbSalve1DO1 | 目标从站1的数字量输出参数1 | 5 | 读写 | 目标从站1数字量参数 | ||
| 6 | bool | mbSalve1DO2 | 目标从站1的数字量输出参数2 | 6 | 读写 | 目标从站1数字量参数 | ||
| 7 | bool | mbSalve1DO3 | 目标从站1的数字量输出参数3 | 7 | 读写 | 目标从站1数字量参数 | ||
| 8 | bool | mbSalve1DO4 | 目标从站1的数字量输出参数4 | 8 | 读写 | 目标从站1数字量参数 | ||
| 目标从站2参数列表 | ||||||||
| 站address:2;Baud rate:9600;data bit:8;stop bit:1;无校验 | ||||||||
| Serial number | data type | 变量名称 | 参数名称 | address | 读写属性 | 取值范围 | 缺省值 | 描述 |
| 1 | float | mbSalve2AI1 | 目标从站2的模拟量输入参数1 | 40001 | 只读 | 目标从站2模拟参数 | ||
| 2 | uint32_t | mbSalve2AI2 | 目标从站2的模拟量输入参数2 | 40003 | 只读 | 目标从站2模拟参数 | ||
| 5 | uint16_t | mbSalve2AI3 | 目标从站2的模拟量输入参数3 | 40005 | 只读 | 0 | 目标从站2模拟参数 | |
| 6 | uint16_t | mbSalve2AO1 | 目标从站2的模拟量输出参数1 | 40006 | 读写 | 目标从站2模拟参数 | ||
| 7 | uint16_t | mbSalve2AO2 | 目标从站2的模拟量输出参数2 | 40007 | 读写 | 0 | 目标从站2模拟参数 | |
| 8 | uint16_t | mbSalve2AO3 | 目标从站2的模拟量输出参数3 | 40008 | 读写 | 0 | 目标从站2模拟参数 | |
| 1 | bool | mbSalve2DI1 | 目标从站2的数字量输入参数1 | 1 | 只读 | 目标从站2数字量参数 | ||
| 2 | bool | mbSalve2DI2 | 目标从站2的数字量输入参数2 | 2 | 只读 | 目标从站2数字量参数 | ||
| 3 | bool | mbSalve2DI3 | 目标从站2的数字量输入参数3 | 3 | 只读 | 目标从站2数字量参数 | ||
| 4 | bool | mbSalve2DI4 | 目标从站2的数字量输入参数4 | 4 | 只读 | 目标从站2数字量参数 | ||
| 5 | bool | mbSalve2DO1 | 目标从站2的数字量输出参数1 | 5 | 读写 | 目标从站2数字量参数 | ||
| 6 | bool | mbSalve2DO2 | 目标从站2的数字量输出参数2 | 6 | 读写 | 目标从站2数字量参数 | ||
| 7 | bool | mbSalve2DO3 | 目标从站2的数字量输出参数3 | 7 | 读写 | 目标从站2数字量参数 | ||
| 8 | bool | mbSalve2DO4 | 目标从站2的数字量输出参数4 | 8 | 读写 | 目标从站2数字量参数 | ||
| 目标从站1参数列表 | ||||||||
| 站address:3;Baud rate:9600;data bit:8;stop bit:1;无校验 | ||||||||
| Serial number | data type | 变量名称 | 参数名称 | address | 读写属性 | 取值范围 | 缺省值 | 描述 |
| 1 | float | mbSalve3AI1 | 目标从站3的模拟量输入参数1 | 40001 | 只读 | 目标从站3模拟参数 | ||
| 2 | uint32_t | mbSalve3AI2 | 目标从站3的模拟量输入参数2 | 40003 | 只读 | 目标从站3模拟参数 | ||
| 5 | uint16_t | mbSalve3AI3 | 目标从站3的模拟量输入参数3 | 40005 | 只读 | 0 | 目标从站3模拟参数 | |
| 6 | uint16_t | mbSalve3AO1 | 目标从站3的模拟量输出参数1 | 40006 | 读写 | 目标从站3模拟参数 | ||
| 7 | uint16_t | mbSalve3AO2 | 目标从站3的模拟量输出参数2 | 40007 | 读写 | 0 | 目标从站3模拟参数 | |
| 8 | uint16_t | mbSalve3AO3 | 目标从站3的模拟量输出参数3 | 40008 | 读写 | 0 | 目标从站3模拟参数 | |
| 1 | bool | mbSalve3DI1 | 目标从站3的数字量输入参数1 | 1 | 只读 | 目标从站3数字量参数 | ||
| 2 | bool | mbSalve3DI2 | 目标从站3的数字量输入参数2 | 2 | 只读 | 目标从站3数字量参数 | ||
| 3 | bool | mbSalve3DI3 | 目标从站3的数字量输入参数3 | 3 | 只读 | 目标从站3数字量参数 | ||
| 4 | bool | mbSalve3DI4 | 目标从站3的数字量输入参数4 | 4 | 只读 | 目标从站3数字量参数 | ||
| 5 | bool | mbSalve3DO1 | 目标从站3的数字量输出参数1 | 5 | 读写 | 目标从站3数字量参数 | ||
| 6 | bool | mbSalve3DO2 | 目标从站3的数字量输出参数2 | 6 | 读写 | 目标从站3数字量参数 | ||
| 7 | bool | mbSalve3DO3 | 目标从站3的数字量输出参数3 | 7 | 读写 | 目标从站3数字量参数 | ||
| 8 | bool | mbSalve3DO4 | 目标从站3的数字量输出参数4 | 8 | 读写 | 目标从站3数字量参数 | ||
| 目标从站1参数列表 | ||||||||
| 站address:4;Baud rate:9600;data bit:8;stop bit:1;无校验 | ||||||||
| Serial number | data type | 变量名称 | 参数名称 | address | 读写属性 | 取值范围 | 缺省值 | 描述 |
| 1 | float | mbSalve4AI1 | 目标从站4的模拟量输入参数1 | 40001 | 只读 | 目标从站4模拟参数 | ||
| 2 | uint32_t | mbSalve4AI2 | 目标从站4的模拟量输入参数2 | 40003 | 只读 | 目标从站4模拟参数 | ||
| 5 | uint16_t | mbSalve4AI3 | 目标从站4的模拟量输入参数3 | 40005 | 只读 | 0 | 目标从站4模拟参数 | |
| 6 | uint16_t | mbSalve4AO1 | 目标从站4的模拟量输出参数1 | 40006 | 读写 | 目标从站4模拟参数 | ||
| 7 | uint16_t | mbSalve4AO2 | 目标从站4的模拟量输出参数2 | 40007 | 读写 | 0 | 目标从站4模拟参数 | |
| 8 | uint16_t | mbSalve4AO3 | 目标从站4的模拟量输出参数3 | 40008 | 读写 | 0 | 目标从站4模拟参数 | |
| 1 | bool | mbSalve4DI1 | 目标从站4的数字量输入参数1 | 1 | 只读 | 目标从站4数字量参数 | ||
| 2 | bool | mbSalve4DI2 | 目标从站4的数字量输入参数2 | 2 | 只读 | 目标从站4数字量参数 | ||
| 3 | bool | mbSalve4DI3 | 目标从站4的数字量输入参数3 | 3 | 只读 | 目标从站4数字量参数 | ||
| 4 | bool | mbSalve4DI4 | 目标从站4的数字量输入参数4 | 4 | 只读 | 目标从站4数字量参数 | ||
| 5 | bool | mbSalve4DO1 | 目标从站4的数字量输出参数1 | 5 | 读写 | 目标从站4数字量参数 | ||
| 6 | bool | mbSalve4DO2 | 目标从站4的数字量输出参数2 | 6 | 读写 | 目标从站4数字量参数 | ||
| 7 | bool | mbSalve4DO3 | 目标从站4的数字量输出参数3 | 7 | 读写 | 目标从站4数字量参数 | ||
| 8 | bool | mbSalve4DO4 | 目标从站4的数字量输出参数4 | 8 | 读写 | 目标从站4数字量参数 | ||
发表回复