基于mnModbus的Modbus프로토콜栈적용手册

무료무료 기술 자료

이 글은 바로 읽을 수 있으며 기초 학습과 검색 유입에 적합합니다.

基于mnModbus的Modbus协议栈应用手册

第1章 前言

Modbus是全球第一个真正用于工业现场的总线프로토콜。Modbus通讯在工业네트워크通讯中적용十分广泛,而且方便,受到大家的欢迎。

1.1、编写原因

一直以来,在我们自己的产品和项目中都多次使用Modbus통신 프로토콜。每次都是使用者自行개발或者网上검색符合要求的源码。但每次的적용都有不同,每次都需要很多的重复劳动。而且프로토콜站如적용软件的紧密结合也使得代码有些混乱。所以一直以来都想要개발一个比较通用的프로토콜栈能在后续的项目中复用,而不必每次都写一遍。现在利用项目研发的机会,개발一个自己的Modbus프로토콜栈。

1.2、版权설명

本套软件最初虽然是为了我们自用而개발,但现已在GitHub上오픈소스。所以任何人都可以복사、传播和使用,无论是个人학습还是商业적용都没有限制。对적용方法及修改欢迎探讨,但对于在使用过程中出现了任何문제我们均不负责。

软件源码及其설명可以上GitHub自由下载,下载주소:https://github.com/foxclever/Modbus

1.3、更新记录

前一个버전我们已经实现了基于串行链路的Modbus RTU和基于以太网的Modbus TCP两种。在这一个버전中,我们추가了基于串行链路的Modbus ASCII방식。并对上一个버전中已知的문제做了修正。

软件设计及本문서更新记录如下:

버전更新설명作者日期
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추가了ASCII相关콘텐츠,并修改已知문제木南2018年9月18日
V2.1.0추가了RTU和ASCII多마스터操作的类容;추가了TCP클라이언트多网段操作的콘텐츠。木南2019年4月29日

第2章、PDU函数

在적용데이터单元我们处理Modbus데이터通讯的基本프레임형식,这些基本是通用的,目前버전只支持01、02、03、04、05、06、15、16기능 코드。

4.1.1、기능 코드枚举

/*定义Modbus的操作기능 코드,支持01、02、03、04、05、06、15、16기능 코드*/

typedef enum {

  ReadCoilStatus=0x01,        /*读코일 상태(读多个출력位的状态)*/

  ReadInputStatus=0x02,       /*读입력位状态(读多个입력位的状态)*/

  ReadHolding회원가입=0x03,   /*读유지 레지스터(读多个유지 레지스터的数值)*/

  ReadInput회원가입=0x04,     /*读입력 레지스터(读多个입력 레지스터的数值)*/

  WriteSingleCoil=0x05,       /*强制单个코일(强制单个출력位的状态)*/

  WriteSingle회원가입=0x06,   /*预制单个레지스터(设定一个레지스터的数值)*/

  WriteMultipleCoil=0x0F,     /*强制多个코일(强制多个출력位的状态)*/

  WriteMultiple회원가입=0x10 /*预制多个레지스터(设定多个레지스터的数值)*/

}기능Code;

4.1.2、Modbus状态枚举

/*定义수신到指令检测错误时的错误码*/

typedef enum{

  MB_OK=0x00,

  Invalid기능Code=0x01,//不合法功能代码

  Illegal데이터주소=0x02,//非法的데이터주소

  Illegal데이터Values=0x03,//非法的데이터值或者范围

  작업Fail=0x04

}ModbusStatus;

4.1.3、站信息结构

/*定义用于传递要访问슬레이브(服务器)的信息*/

typedef struct{

  uint8_t unitID;

  기능Code functionCode;

  uint16_t 시작ing주소;

  uint16_t 수량;

}ObjAccessInfo;

定义用于传递슬레이브(服务器)访问的各种信息,包括站号、기능 코드、시작주소和数量。

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,需要往下写的状态量对象데이터列表

uint16_t *registerList,需要往下写的레지스터量对象的데이터列表

uint8_t commandBytes[],生成的访问命令

返回值:生成的访问命令的길이,以바이트为单位。

4.1.5、분석읽기的返回데이터函数

/*분석마스터(클라이언트)从服务器읽기的데이터*/

void TransformClientReceived데이터(uint8_t * receivedMessage,uint16_t 수량,bool *statusList,uint16_t *registerLister);

매개변수:uint8_t * receivedMessage,수신到的信息프레임

uint16_t 수량,읽기的对象数量

bool *statusList,분석出来的읽기到的状态对象的데이터列表

uint16_t *registerLister,분석出来的읽기到的레지스터对象的데이터列表

返回值:无

4.1.6、슬레이브生成读데이터命令的响应프레임函数

/*生成마스터读访问的响应,包括0x01、0x02、0x03、0x04기능 코드,返回相应信息的길이*/

uint16_t GenerateMasterAccessRespond(uint8_t *receivedMesasage,bool *statusList,uint16_t *registerList,uint8_t *respondBytes);

매개변수:uint8_t *receivedMesasage,수신到的主战读操作프레임

bool *statusList,읽기的슬레이브状态对象데이터列表

uint16_t *registerList,읽기到的슬레이브레지스터对象데이터列表

uint8_t *respondBytes,生成的슬레이브响应프레임信息

返回值:响应프레임的길이,以바이트为单位

4.1.7、기능 코드检验函数

/*检查기능 코드是否正确*/

ModbusStatus Check기능Code(기능Code fc);

매개변수:기능Code fc,기능 코드,由枚举定义

返回值:Modbus操作状态,由枚举定义

4.1.8、生成TCP클라이언트命令函数

//生成读写服务器对象的命令

uint16_t SyntheticReadWriteTCPServerCommand(ObjAccessInfo objInfo,bool *statusList,uint16_t *registerList,uint8_t *commandBytes);

매개변수:ObjAccessInfo objInfo,TCP服务器访问信息对象

bool *statusList,写服务器状态量对象데이터列表

uint16_t *registerList,写服务器레지스터量对象데이터列表

uint8_t *commandBytes,生成的命令信息프레임

返回值:命令的길이,以바이트为单位

4.1.9、生成TCP服务器响应函数

/*合成对服务器访问的响应*/

uint16_t SyntheticServerAccessRespond(uint8_t *receivedMesasage,bool *statusList,uint16_t *registerList,uint8_t *respondBytes);

매개변수:uint8_t *receivedMesasage,수신到的클라이언트命令信息프레임

bool *statusList,读TCP服务器的状态量对象데이터列表

uint16_t *registerList,读TCP服务器的레지스터量对象데이터列表

uint8_t *respondBytes,생성된 응답클라이언트命令的响应信息프레임

返回值:响应信息프레임길이,以바이트为单位

4.1.10、CRC 검증检查

/*通过CRC 검증수신的信息是否正确*/

bool CheckRTUMessageIntegrity (uint8_t *message,uint8_t length);

매개변수:uint8_t *message,待체크섬的데이터프레임

uint8_t length,带教言的데이터프레임길이,以바이트为单位

返回值:返回체크섬是否通过的状态信号

4.1.11、生成读写RTU슬레이브的마스터命令函数

/*生成读写슬레이브데이터对象的命令,命令길이包括2个체크섬바이트*/

uint16_t SyntheticReadWriteSlaveCommand(ObjAccessInfo slaveInfo,bool *statusList,uint16_t *registerList,uint8_t *commandBytes);

매개변수:ObjAccessInfo slaveInfo,슬레이브访问信息对象,由结构体定义

bool *statusList,写슬레이브状态量데이터列表

uint16_t *registerList,写슬레이브레지스터量데이터列表

uint8_t *commandBytes,生成的访问命令프레임

返回值:访问命令的길이,以바이트为单位

4.1.12、生成슬레이브应答信息프레임函数

/*生成슬레이브应答마스터的响应*/

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,

返回值:생성된 응답信息프레임的길이,以바이트为单位

4.1.13、LRC체크섬检查函数

/*判断ASCII데이터信息是否正确*/

bool CheckASCIIMessageIntegrity(uint8_t *usMsg, uint16_t usLength)

매개변수:uint8_t *usMsg,待체크섬的消息列表,16진법데이터

uint16_t usLength,待체크섬的消息列表的길이

返回值:체크섬结果,체크섬正确返回“true”,否则返回“false”

4.1.14、将ASCII消息转换为16진법

/*수신到的ASCII消息转换为16진법*/

bool CovertAsciiMessageToHex(uint8_t *aMsg, uint8_t *hMsg, uint16_t aLen);

매개변수:uint8_t *aMsg,ASCII码信息

uint8_t *hMsg,转换后的16진법信息

      uint16_t aLen,ASCII码信息的길이

返回值:转换是否正确,转换正确返回“true”,否则返回“false”

4.1.15、生成读写ASCII슬레이브的命令函数

/*生成读写슬레이브的命令,적용于마스터,含체크섬及시작종료符*/

uint16_t SyntheticReadWriteAsciiSlaveCommand(ObjAccessInfo slaveInfo, bool *statusList, uint16_t *registerList, uint8_t *commandBytes)

매개변수:ObjAccessInfo slaveInfo,슬레이브访问信息对象,由结构体定义

bool *statusList,写슬레이브状态量데이터列表

uint16_t *registerList,写슬레이브레지스터量데이터列表

uint8_t *commandBytes,生成的访问命令프레임

返回值:访问命令的길이,以바이트为单位

4.1.16、生成ASCII슬레이브应答마스터命令的函数

/*生成应答마스터的响应,적용于슬레이브*/

uint16_t SyntheticAsciiSlaveAccessRespond(uint8_t *receivedMessage, bool *statusList, uint16_t *registerList, uint8_t *respondBytes)

매개변수:uint8_t *receivedMesasage,接受到마스터프레임信息

bool *statusList,마스터命令要읽기的状态量值列表

uint16_t *registerList,마스터命令要읽기的레지스터量值列表

uint8_t *respondBytes,생성된 응답信息프레임

返回值:생성된 응답信息프레임的길이,以바이트为单位

第3章、적용封装函数

对적용级封装,我们只封装RTU마스터적용,RTU슬레이브적용、TCP클라이언트적용和TCP服务器端적용四类。

4.2.1、RTU마스터对象与슬레이브对象

/* 定义被访问RTU슬레이브对象유형 */

typedef struct AccessedRTUSlaveType{

  uint8_t station주소;       //站주소

  uint8_t cmdOrder;             //当前命令在명령 목록中的位置

  uint16_t commandNumber;       //명령 목록中命令的总数

  uint8_t (*pReadCommand)[8];   //读명령 목록

  uint8_t *pLastCommand;        //上一次보내기的命令

  uint32_t flagPresetCoil;      //预置코일控制标志位

  uint32_t flagPresetReg;       //预置레지스터控制标志位

}RTUAccessedSlaveType;

/* 定义本地RTU마스터对象유형 */

typedef struct LocalRTUMasterType{

  uint32_t flagWriteSlave[8];   //写一个站控制标志位,最多256个站,与站주소对应。

  uint16_t slaveNumber;         //슬레이브列表中슬레이브的数量

  uint16_t readOrder;           //当前슬레이브在슬레이브列表中的位置

  RTUAccessedSlaveType *pSlave;         //슬레이브列表

  UpdateCoilStatusType pUpdateCoilStatus;       //更新코일量函数

  UpdateInputStatusType pUpdateInputStatus;     //更新입력 상태量函数

  UpdateHolding회원가입Type pUpdateHolding회원가입;     //更新유지 레지스터量函数

  UpdateInputResgisterType pUpdateInputResgister;       //更新입력 레지스터量函数

}RTULocalMasterType;

4.2.2、RTU마스터对象初始化函数

/*初始化RTU마스터对象*/

void InitializeRTUMasterObject(RTULocalMasterType *master,uint16_t slaveNumber,RTUAccessedSlaveType *pSlave,UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHolding회원가입Type pUpdateHolding회원가입,UpdateInputResgisterType pUpdateInputResgister);

매개변수:RTULocalMasterType *master,本地마스터对象

uint16_t slaveNumber,슬레이브的数量

RTUAccessedSlaveType *pSlave,슬레이브列表

UpdateCoilStatusType pUpdateCoilStatus,更新코일量函数指针

UpdateInputStatusType pUpdateInputStatus,更新状态量函数指针

UpdateHolding회원가입Type pUpdateHolding회원가입,更新유지 레지스터量函数指针

UpdateInputResgisterType pUpdateInputResgister,更新입력 레지스터量函数指针

返回值:无返回值

4.2.3、生成RTU마스터访问슬레이브命令函数

/*生成访问服务器的命令*/

uint16_t CreateAccessSlaveCommand(ObjAccessInfo objInfo,void *데이터List,uint8_t *commandBytes);

매개변수:ObjAccessInfo objInfo,슬레이브访问信息对象,由结构体定义

void *데이터List,写슬레이브对象的데이터列表

uint8_t *commandBytes,生成的命令프레임

返回值:生成的访问命令的길이,以바이트为单位

4.2.4、RTU마스터분석슬레이브的响应函数

/*분석收到的服务器响应信息*/

void 분석SlaveRespondMessage(uint8_t *recievedMessage,uint8_t *command);

매개변수:uint8_t *recievedMessage,수신到的返回信息

uint8_t *command,已经下发到슬레이브的명령 목록

返回值:无

4.2.5、RTU마스터분석슬레이브返回消息命令일치函数

/*수신到返回信息后,判断是否是명령 보내기列表中命令的返回信息*/

int FindCommandForRecievedMessage(uint8_t *recievedMessage,uint8_t (*commandList)[8],uint16_t commandNumber);

매개변수:uint8_t *recievedMessage,수신的슬레이브返回信息

uint8_t (*commandList)[8],마스터下发过的명령 목록

uint16_t commandNumber,存储的命令的条数

返回值:返回일치命令所在的位置,无일치时,返回“-1”

本函数只在RTU마스터中,访问的데이터量大且频繁,或者访问多个슬레이브时使用,便于作正确的데이터분석。

4.2.6、RTU슬레이브분석마스터访问命令函数

/*분석수신到的信息,并返回合成的回复信息和信息的바이트길이,通过回调函数*/

uint16_t 분석MasterAccessCommand(uint8_t *receivedMesasage,uint8_t *respondBytes,uint16_t rxLength);

매개변수:uint8_t *receivedMesasage,수신到的마스터프레임信息

uint8_t *respondBytes,응답 생성信息프레임

uint16_t rxLength,수신到的프레임的길이

返回值:생성된 응답信息的길이,以바이트为单位

4.2.7、TCP클라이언트对象与TCP服务器对象

/* 定义被访问TCP服务器对象유형 */

typedef struct AccessedTCPServerType{

  union {

    uint32_t ipNumber;

    uint8_t ipSegment[4];

  }ip주소;                                           //服务器的IP주소

  uint32_t flagPresetServer;                            //写服务器请求标志

  WritedCoilListHeadNode pWritedCoilHeadNode;          //可写的코일量列表

  Writed회원가입ListHeadNode pWrited회원가입HeadNode;  //可写的유지 레지스터列表

  struct AccessedTCPServerType *pNextNode;              //下一个TCP服务器节点

}TCPAccessedServerType;

/* 定义服务器链表头유형 */

typedef struct ServerListHeadType {

  TCPAccessedServerType *pServerNode;           //服务器节点指针

  uint32_t serverNumber;                        //服务器的数量

}ServerListHeadNode;

/* 定义本地TCP클라이언트对象유형 */

typedef struct LocalTCPClientType{

  uint32_t transaction;                                 //트랜잭션 식별자

  uint16_t cmdNumber;                                  //读服务器命令的数量

  uint16_t cmdOrder;                                   //当前슬레이브在슬레이브列表中的位置

  uint8_t (*pReadCommand)[12];                         //读명령 목록

  ServerListHeadNode ServerHeadNode;                    //Server对象链表的头节点

  UpdateCoilStatusType pUpdateCoilStatus;               //更新코일量函数

  UpdateInputStatusType pUpdateInputStatus;             //更新입력 상태量函数

  UpdateHolding회원가입Type pUpdateHolding회원가입;     //更新유지 레지스터量函数

  UpdateInputResgisterType pUpdateInputResgister;       //更新입력 레지스터量函数

}TCPLocalClientType;

4.2.8、TCP클라이언트对象初始化函数

/*初始化TCP클라이언트对象*/

void InitializeTCPClientObject(TCPLocalClientType *client,uint16_t cmdNumber,uint8_t (*pReadCommand)[12],UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHolding회원가입Type pUpdateHolding회원가입,UpdateInputResgisterType pUpdateInputResgister);

매개변수:TCPLocalClientType *client,클라이언트对象

uint16_t cmdNumber,读命令的数量

uint8_t (*pReadCommand)[12],读명령 목록

UpdateCoilStatusType pUpdateCoilStatus,更新코일量函数指针

UpdateInputStatusType pUpdateInputStatus,更新状态量函数指针

UpdateHolding회원가입Type pUpdateHolding회원가입,更新유지 레지스터函数指针

UpdateInputResgisterType pUpdateInputResgister,更新입력 레지스터量函数指针

返回值:无返回值

4.2.9、生成TCP클라이언트访问服务器命令函数

/*生成访问服务器的命令*/

uint16_t CreateAccessServerCommand(ObjAccessInfo objInfo,void *데이터List,uint8_t *commandBytes);

매개변수:ObjAccessInfo objInfo,访问服务器信息对象

void *데이터List,些服务器对象데이터列表

uint8_t *commandBytes,生成的访问服务器命令프레임

返回值:访问命令的길이,以바이트为单位

4.2.10、TCP클라이언트분석服务器返回信息函数

/*분석收到的服务器相应信息*/

void 분석ServerRespondMessage(uint8_t *recievedMessage);

매개변수:uint8_t *recievedMessage,接受到的服务器响应信息

返回值:无

4.2.11、TCP服务器분석클라이언트命令函数

/*분석수신到的信息,返回响应命令的길이*/

uint16_t 분석ClientAccessCommand(uint8_t *receivedMessage,uint8_t *respondBytes);

매개변수:uint8_t *receivedMessage,接受到的클라이언트访问命令

uint8_t *respondBytes,生成的服务器响应信息

返回值:생성된 응답信息프레임的길이,以바이트为单位

4.2.12、ASCII마스터对象与슬레이브对象

/* 定义被访问ASCII슬레이브对象유형 */

typedef  struct AccessedASCIISlaveType{

  uint8_t station주소;       //站주소

  uint8_t cmdOrder;             //当前命令在명령 목록中的位置

  uint16_t commandNumber;       //명령 목록中命令的总数

  uint8_t (*pReadCommand)[17];   //读명령 목록

  uint8_t *pLastCommand;        //上一次보내기的命令

  uint32_t flagPresetCoil;      //预置코일控制标志位

  uint32_t flagPresetReg;       //预置레지스터控制标志位

}AsciiAccessedSlaveType;

/* 定义本地ASCII마스터对象유형 */

typedef struct LocalASCIIMasterType{

  uint32_t flagWriteSlave[8];   //写一个站控制标志位,最多256个站,与站주소对应。

  uint16_t slaveNumber;         //슬레이브列表中슬레이브的数量

  uint16_t readOrder;           //当前슬레이브在슬레이브列表中的位置

  AsciiAccessedSlaveType *pSlave;         //슬레이브列表

  UpdateCoilStatusType pUpdateCoilStatus;       //更新코일量函数

  UpdateInputStatusType pUpdateInputStatus;     //更新입력 상태量函数

  UpdateHolding회원가입Type pUpdateHolding회원가입;     //更新유지 레지스터量函数

  UpdateInputResgisterType pUpdateInputResgister;       //更新입력 레지스터量函数

}AsciiLocalMasterType;

4.2.13、ASCII마스터对象初始化函数

/*初始化RTU마스터对象*/

void InitializeASCIIMasterObject(AsciiLocalMasterType *master,uint16_t slaveNumber,AsciiAccessedSlaveType *pSlave,UpdateCoilStatusType pUpdateCoilStatus,UpdateInputStatusType pUpdateInputStatus,UpdateHolding회원가입Type pUpdateHolding회원가입,UpdateInputResgisterType pUpdateInputResgister);

매개변수:AsciiLocalMasterType *master,ASCII마스터对象

uint16_t slaveNumber,슬레이브的数量

AsciiAccessedSlaveType *pSlave,슬레이브列表

UpdateCoilStatusType pUpdateCoilStatus,更新코일量回调函数

UpdateInputStatusType pUpdateInputStatus,更新状态量回调函数

UpdateHolding회원가입Type pUpdateHolding회원가입,更新유지 레지스터量回调函数

UpdateInputResgisterType pUpdateInputResgister,更新입력 레지스터量回调函数

返回值:无返回值

4.2.14、生成访问ASCII슬레이브的命令

/*生成访问ASCII슬레이브的命令*/

uint16_t CreateAccessAsciiSlaveCommand(ObjAccessInfo objInfo,void *데이터List,uint8_t *commandBytes);

매개변수:ObjAccessInfo objInfo,슬레이브访问信息对象,由结构体定义

void *데이터List,写슬레이브对象的데이터列表

uint8_t *commandBytes,生成的命令프레임

返回值:生成的访问命令的길이,以바이트为单位

4.2.15、ASCII마스터분석슬레이브的响应函数

/*분석收到的服务器相应信息*/

void 분석AsciiSlaveRespondMessage(uint8_t *recievedMessage, uint8_t *command,uint16_t rxLength);

매개변수:uint8_t *recievedMessage,수신到的返回信息

uint8_t *command,已经下发到슬레이브的명령 목록

uint16_t rxLength,수신到的消息的길이

返回值:无

4.2.16、ASCII마스터분석슬레이브返回消息命令일치函数

/*수신到返回信息后,判断是否是명령 보내기列表中命令的返回信息*/

int FindAsciiCommandForRecievedMessage(uint8_t *recievedMessage,uint8_t (*commandList)[17],uint16_t commandNumber);

매개변수:uint8_t *recievedMessage,수신的슬레이브返回信息

uint8_t (*commandList)[17],마스터下发过的명령 목록

uint16_t commandNumber,存储的命令的条数

返回值:返回일치命令所在的位置,无일치时,返回“-1”

本函数只在RTU마스터中,访问的데이터量大且频繁,或者访问多个슬레이브时使用,便于作正确的데이터분석。

4.2.17、ASCII슬레이브분석마스터访问命令函数

/*분석수신到的信息,并返回合成的回复信息和信息的바이트길이,通过回调函数*/

uint16_t 분석AsciiMasterAccessCommand(uint8_t *receivedMessage, uint8_t *respondBytes, uint16_t rxLength, uint8_t Station주소);

매개변수:uint8_t *receivedMesasage,수신到的마스터프레임信息

uint8_t *respondBytes,응답 생성信息프레임

uint16_t rxLength,수신到的프레임的길이

返回值:생성된 응답信息的길이,以바이트为单位

第4章、데이터处理函数

具体적용中还涉及到对데이터对想的处理,不同的적용데이터结构与处理방식千差万别,所以定义一些回调函数(实际使用弱化的函数__weak关键字)用于데이터的处理。

4.3.1、获取코일量值的函数

/*获取想要읽기的Coil量的值*/

__weak void GetCoilStatus(uint16_t 시작주소,uint16_t 수량,bool *statusList)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,要읽기对象的시작주소

uint16_t 수량,要읽기对象的数量

bool *statusList,获取的코일量的데이터值列表

返回值:无

4.3.2、获取입력 상태值的函数

/*获取想要읽기的InputStatus量的值*/

__weak void GetInputStatus(uint16_t 시작주소,uint16_t 수량,bool *statusValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,要읽기对象的시작주소

uint16_t 수량,要읽기对象的数量

bool *statusValue,获取的입력 상태量的데이터值列表

返回值:无

4.3.3、获取유지 레지스터值的函数

/*获取想要읽기的유지 레지스터的值*/

__weak void GetHolding회원가입(uint16_t 시작주소,uint16_t 수량,uint16_t *registerValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,要읽기的유지 레지스터对象的시작주소

uint16_t 수량,要읽기的유지 레지스터的数量

uint16_t *registerValue,获取的유지 레지스터的值

返回值:无

4.3.4、获取입력 레지스터值的函数

/*获取想要읽기的입력 레지스터的值*/

__weak void GetInput회원가입(uint16_t 시작주소,uint16_t 수량,uint16_t *registerValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,要읽기的입력 레지스터的시작주소

uint16_t 수량,要읽기的입력 레지스터的数量

uint16_t *registerValue,获取的입력 레지스터的值

返回值:无

4.3.5、设置单个코일的值函数

/*设置单个코일的值*/

__weak void SetSingleCoil(uint16_t coil주소,bool coilValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t coil주소,所需要预置值的코일주소

bool coilValue,所预置的值

返回值:无

4.3.6、设置单个레지스터 값的函数

/*设置单个레지스터的值*/

__weak void SetSingle회원가입(uint16_t register주소,uint16_t registerValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t register주소,所预置的유지 레지스터的주소

uint16_t registerValue,所预置的유지 레지스터的值

返回值:无

4.3.7、设置多个코일值的函数

/*设置多个코일的值*/

__weak void SetMultipleCoil(uint16_t 시작주소,uint16_t 수량,bool *statusValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,要预置的多个코일的시작주소

uint16_t 수량,所要预知的코일的数量

bool *statusValue,要预知的코일值的列表

返回值:无

4.3.8、设置多个레지스터 값的函数

/*设置多个레지스터的值*/

__weak void SetMultiple회원가입(uint16_t 시작주소,uint16_t 수량,uint16_t *registerValue)

{

  //如果需要Modbus TCP Server/RTU Slave적용中实现具体콘텐츠

}

매개변수:uint16_t 시작주소,所预置的多个유지 레지스터的시작주소

uint16_t 수량,所要预置的유지 레지스터的数量

uint16_t *registerValue,预知的유지 레지스터值的列表

返回值:无

4.3.9、슬레이브更新获取到的코일量值的函数

/*更新读回来的코일 상태*/

__weak void UpdateCoilStatus(uint16_t 시작주소,uint16_t 수량,bool *stateValue)

{

  //在클라이언트(마스터)적용中实现

}

매개변수:uint16_t 시작주소,읽기值的코일对象的시작주소

uint16_t 수량,所읽기的코일的数量

bool *stateValue,읽기的코일주소的列表

返回值:无

本程序为默认处理函数,各个마스터对象可以单独定义更新函数,若没有定义则调用本函数。

4.3.10、슬레이브更新获取到的입력 상태值的函数

/*更新读回来的입력 상태值*/

__weak void UpdateInputStatus(uint16_t 시작주소,uint16_t 수량,bool *stateValue)

{

  //在클라이언트(마스터)적용中实现

}

매개변수:uint16_t 시작주소,所읽기的입력 상태对象的시작주소

uint16_t 수량,所읽기的입력 상태对象的数量

bool *stateValue,읽기到的입력 상태对象的值

返回值:无

本程序为默认处理函数,各个마스터对象可以单独定义更新函数,若没有定义则调用本函数。

4.3.11、슬레이브更新유지 레지스터值的函数

/*更新读回来的유지 레지스터*/

__weak void UpdateHolding회원가입(uint16_t 시작주소,uint16_t 수량,uint16_t *registerValue)

{

  //在클라이언트(마스터)적용中实现

}

매개변수:uint16_t 시작주소,所읽기的유지 레지스터对象的시작주소

uint16_t 수량,所읽기的유지 레지스터对象的데이터

uint16_t *registerValue,읽기到的유지 레지스터对象值列表

返回值:无

本程序为默认处理函数,各个마스터对象可以单独定义更新函数,若没有定义则调用本函数。

4.3.12、슬레이브更新입력 레지스터值得函数

/*更新读回来的입력 레지스터*/

__weak void UpdateInputResgister(uint16_t 시작주소,uint16_t 수량,uint16_t *registerValue)

{

  //在클라이언트(마스터)적용中实现

}

매개변수:uint16_t 시작주소,所읽기的입력 레지스터对象的시작주소

uint16_t 수량,所읽기的입력 레지스터对象的数量

uint16_t *registerValue,읽기到的입력 레지스터值得列表

返回值:无

本程序为默认处理函数,各个마스터对象可以单独定义更新函数,若没有定义则调用本函数。

第5章 一些相关설명

对于Modbus프로토콜栈的整个개발콘텐츠,前面已经说得很清楚了,接下来我们설명一下与개발没有直接关系的콘텐츠。

首先,关于我为什么개발这个프로토콜栈的문제。我们的初衷只是想能够在개발产品时不用每次都重写这一部分,而是可以不断的改进和使用达到复用的目的。当然在后来,我们觉得不只是我们自己可以使用,也可以将其公开,让任何愿意使用的人使用。源码网址是:https://github.com/foxclever/Modbus

其次,Modbus프로토콜有国标,包括三个文件。我们这个프로토콜栈就是按照国标개발的표준프로토콜,包括有读写各种유형对象데이터的功能,在一般的工业적용场合是完全够的。三个표준文件:

GB/T 19582.1-2008 《基于Modbus프로토콜的산업 자동화네트워크사양 第1部分:Modbus적용프로토콜》

GB/T 19582.2-2008 《基于Modbus프로토콜的산업 자동화네트워크사양 第1部分:Modbus프로토콜在串行链路上的实现指南》

GB/T 19582.3-2008 《基于Modbus프로토콜的산업 자동화네트워크사양 第1部分:Modbus프로토콜在TCP/IP上的实现指南》

最后,欢迎大家使用这个프로토콜栈,但我们不就使用的最终结果负责。当然如果发现任何的不足,我们非常并欢迎大家将发现的문제告知我们,以便我们持续的改进之。

感谢您关注本软件,有需要的同仁可以上GitHub下载,同时欢迎给我们提出改进意见,有兴趣的同仁可以关注我们的公众号:

Modbus프로토콜栈综合实例매개변수列表
站주소:1;통신 속도:115200;데이터 비트:8;정지 비트:1;패리티 없음
순번데이터유형변수名称매개변수名称주소读写属性取值范围缺省值설명
1uint32_tbeatTime心跳检测40001只读每秒추가1次,监视系统是否正常运行
2floatmbAI1模拟量测试40003只读mbAO1*3
3floatmbAO1模拟量测试40005读写0~100.01.101
4uint16_tmbAI2模拟量测试40007只读mbAO2*2
5uint16_tmbAO2模拟量测试40008读写0~1001本站변수
1floatmbSalve1AI1目标슬레이브1的模拟量입력매개변수140009只读目标슬레이브1模拟매개변수
2uint32_tmbSalve1AI2目标슬레이브1的模拟量입력매개변수240011只读目标슬레이브1模拟매개변수
5uint16_tmbSalve1AI3目标슬레이브1的模拟量입력매개변수340013只读0目标슬레이브1模拟매개변수
6uint16_tmbSalve1AO1目标슬레이브1的模拟量출력매개변수140014读写101目标슬레이브1模拟매개변수
7uint16_tmbSalve1AO2目标슬레이브1的模拟量출력매개변수240015读写102目标슬레이브1模拟매개변수
8uint16_tmbSalve1AO3目标슬레이브1的模拟量출력매개변수340016读写103目标슬레이브1模拟매개변수
1floatmbSalve2AI1目标슬레이브2的模拟量입력매개변수140017只读目标슬레이브2模拟매개변수
2uint32_tmbSalve2AI2目标슬레이브2的模拟量입력매개변수240019只读目标슬레이브2模拟매개변수
5uint16_tmbSalve2AI3目标슬레이브2的模拟量입력매개변수340021只读0目标슬레이브2模拟매개변수
6uint16_tmbSalve2AO1目标슬레이브2的模拟量출력매개변수140022读写目标슬레이브2模拟매개변수
7uint16_tmbSalve2AO2目标슬레이브2的模拟量출력매개변수240023读写0目标슬레이브2模拟매개변수
8uint16_tmbSalve2AO3目标슬레이브2的模拟量출력매개변수340024读写0目标슬레이브2模拟매개변수
1floatmbSalve3AI1目标슬레이브3的模拟量입력매개변수140025只读目标슬레이브3模拟매개변수
2uint32_tmbSalve3AI2目标슬레이브3的模拟量입력매개변수240027只读目标슬레이브3模拟매개변수
5uint16_tmbSalve3AI3目标슬레이브3的模拟量입력매개변수340029只读0目标슬레이브3模拟매개변수
6uint16_tmbSalve3AO1目标슬레이브3的模拟量출력매개변수140030读写目标슬레이브3模拟매개변수
7uint16_tmbSalve3AO2目标슬레이브3的模拟量출력매개변수240031读写0目标슬레이브3模拟매개변수
8uint16_tmbSalve3AO3目标슬레이브3的模拟量출력매개변수340032读写0目标슬레이브3模拟매개변수
1floatmbSalve4AI1目标슬레이브4的模拟量입력매개변수140033只读目标슬레이브4模拟매개변수
2uint32_tmbSalve4AI2目标슬레이브4的模拟量입력매개변수240035只读目标슬레이브4模拟매개변수
5uint16_tmbSalve4AI3目标슬레이브4的模拟量입력매개변수340037只读0目标슬레이브4模拟매개변수
6uint16_tmbSalve4AO1目标슬레이브4的模拟量출력매개변수140038读写目标슬레이브4模拟매개변수
7uint16_tmbSalve4AO2目标슬레이브4的模拟量출력매개변수240039读写0目标슬레이브4模拟매개변수
8uint16_tmbSalve4AO3目标슬레이브4的模拟量출력매개변수340040读写0目标슬레이브4模拟매개변수
1boolmbDI1数字量입력매개변수11只读数字量매개변수
2boolmbDI2数字量입력매개변수22只读数字量매개변수
3boolmbDI3数字量입력매개변수33只读数字量매개변수
4boolmbDI4数字量입력매개변수44只读数字量매개변수
5boolmbDO1数字量출력매개변수15读写数字量매개변수
6boolmbDO2数字量출력매개변수26读写数字量매개변수
7boolmbDO3数字量출력매개변수37读写数字量매개변수
8boolmbDO4数字量출력매개변수48读写数字量매개변수
1boolmbSalve1DI1目标슬레이브1的数字量입력매개변수19只读目标슬레이브1数字量매개변수
2boolmbSalve1DI2目标슬레이브1的数字量입력매개변수210只读目标슬레이브1数字量매개변수
3boolmbSalve1DI3目标슬레이브1的数字量입력매개변수311只读目标슬레이브1数字量매개변수
4boolmbSalve1DI4目标슬레이브1的数字量입력매개변수412只读目标슬레이브1数字量매개변수
5boolmbSalve1DO1目标슬레이브1的数字量출력매개변수113读写目标슬레이브1数字量매개변수
6boolmbSalve1DO2目标슬레이브1的数字量출력매개변수214读写目标슬레이브1数字量매개변수
7boolmbSalve1DO3目标슬레이브1的数字量출력매개변수315读写目标슬레이브1数字量매개변수
8boolmbSalve1DO4目标슬레이브1的数字量출력매개변수416读写目标슬레이브1数字量매개변수
1boolmbSalve2DI1目标슬레이브2的数字量입력매개변수117只读目标슬레이브2数字量매개변수
2boolmbSalve2DI2目标슬레이브2的数字量입력매개변수218只读目标슬레이브2数字量매개변수
3boolmbSalve2DI3目标슬레이브2的数字量입력매개변수319只读目标슬레이브2数字量매개변수
4boolmbSalve2DI4目标슬레이브2的数字量입력매개변수420只读目标슬레이브2数字量매개변수
5boolmbSalve2DO1目标슬레이브2的数字量출력매개변수121读写目标슬레이브2数字量매개변수
6boolmbSalve2DO2目标슬레이브2的数字量출력매개변수222读写目标슬레이브2数字量매개변수
7boolmbSalve2DO3目标슬레이브2的数字量출력매개변수323读写目标슬레이브2数字量매개변수
8boolmbSalve2DO4目标슬레이브2的数字量출력매개변수424读写目标슬레이브2数字量매개변수
1boolmbSalve3DI1目标슬레이브3的数字量입력매개변수125只读目标슬레이브3数字量매개변수
2boolmbSalve3DI2目标슬레이브3的数字量입력매개변수226只读目标슬레이브3数字量매개변수
3boolmbSalve3DI3目标슬레이브3的数字量입력매개변수327只读目标슬레이브3数字量매개변수
4boolmbSalve3DI4目标슬레이브3的数字量입력매개변수428只读目标슬레이브3数字量매개변수
5boolmbSalve3DO1目标슬레이브3的数字量출력매개변수129读写目标슬레이브3数字量매개변수
6boolmbSalve3DO2目标슬레이브3的数字量출력매개변수230读写目标슬레이브3数字量매개변수
7boolmbSalve3DO3目标슬레이브3的数字量출력매개변수331读写目标슬레이브3数字量매개변수
8boolmbSalve3DO4目标슬레이브3的数字量출력매개변수432读写目标슬레이브3数字量매개변수
1boolmbSalve4DI1目标슬레이브4的数字量입력매개변수133只读目标슬레이브4数字量매개변수
2boolmbSalve4DI2目标슬레이브4的数字量입력매개변수234只读目标슬레이브4数字量매개변수
3boolmbSalve4DI3目标슬레이브4的数字量입력매개변수335只读目标슬레이브4数字量매개변수
4boolmbSalve4DI4目标슬레이브4的数字量입력매개변수436只读目标슬레이브4数字量매개변수
5boolmbSalve4DO1目标슬레이브4的数字量출력매개변수137读写目标슬레이브4数字量매개변수
6boolmbSalve4DO2目标슬레이브4的数字量출력매개변수238读写目标슬레이브4数字量매개변수
7boolmbSalve4DO3目标슬레이브4的数字量출력매개변수339读写目标슬레이브4数字量매개변수
8boolmbSalve4DO4目标슬레이브4的数字量출력매개변수440读写目标슬레이브4数字量매개변수
目标슬레이브1매개변수列表
站주소:1;통신 속도:9600;데이터 비트:8;정지 비트:1;패리티 없음
순번데이터유형변수名称매개변수名称주소读写属性取值范围缺省值설명
1floatmbSalve1AI1目标슬레이브1的模拟量입력매개변수140001只读目标슬레이브1模拟매개변수
2uint32_tmbSalve1AI2目标슬레이브1的模拟量입력매개변수240003只读目标슬레이브1模拟매개변수
5uint16_tmbSalve1AI3目标슬레이브1的模拟量입력매개변수340005只读0目标슬레이브1模拟매개변수
6uint16_tmbSalve1AO1目标슬레이브1的模拟量출력매개변수140006读写目标슬레이브1模拟매개변수
7uint16_tmbSalve1AO2目标슬레이브1的模拟量출력매개변수240007读写0目标슬레이브1模拟매개변수
8uint16_tmbSalve1AO3目标슬레이브1的模拟量출력매개변수340008读写0目标슬레이브1模拟매개변수
1boolmbSalve1DI1目标슬레이브1的数字量입력매개변수11只读目标슬레이브1数字量매개변수
2boolmbSalve1DI2目标슬레이브1的数字量입력매개변수22只读目标슬레이브1数字量매개변수
3boolmbSalve1DI3目标슬레이브1的数字量입력매개변수33只读目标슬레이브1数字量매개변수
4boolmbSalve1DI4目标슬레이브1的数字量입력매개변수44只读目标슬레이브1数字量매개변수
5boolmbSalve1DO1目标슬레이브1的数字量출력매개변수15读写目标슬레이브1数字量매개변수
6boolmbSalve1DO2目标슬레이브1的数字量출력매개변수26读写目标슬레이브1数字量매개변수
7boolmbSalve1DO3目标슬레이브1的数字量출력매개변수37读写目标슬레이브1数字量매개변수
8boolmbSalve1DO4目标슬레이브1的数字量출력매개변수48读写目标슬레이브1数字量매개변수
目标슬레이브2매개변수列表
站주소:2;통신 속도:9600;데이터 비트:8;정지 비트:1;패리티 없음
순번데이터유형변수名称매개변수名称주소读写属性取值范围缺省值설명
1floatmbSalve2AI1目标슬레이브2的模拟量입력매개변수140001只读目标슬레이브2模拟매개변수
2uint32_tmbSalve2AI2目标슬레이브2的模拟量입력매개변수240003只读目标슬레이브2模拟매개변수
5uint16_tmbSalve2AI3目标슬레이브2的模拟量입력매개변수340005只读0目标슬레이브2模拟매개변수
6uint16_tmbSalve2AO1目标슬레이브2的模拟量출력매개변수140006读写目标슬레이브2模拟매개변수
7uint16_tmbSalve2AO2目标슬레이브2的模拟量출력매개변수240007读写0目标슬레이브2模拟매개변수
8uint16_tmbSalve2AO3目标슬레이브2的模拟量출력매개변수340008读写0目标슬레이브2模拟매개변수
1boolmbSalve2DI1目标슬레이브2的数字量입력매개변수11只读目标슬레이브2数字量매개변수
2boolmbSalve2DI2目标슬레이브2的数字量입력매개변수22只读目标슬레이브2数字量매개변수
3boolmbSalve2DI3目标슬레이브2的数字量입력매개변수33只读目标슬레이브2数字量매개변수
4boolmbSalve2DI4目标슬레이브2的数字量입력매개변수44只读目标슬레이브2数字量매개변수
5boolmbSalve2DO1目标슬레이브2的数字量출력매개변수15读写目标슬레이브2数字量매개변수
6boolmbSalve2DO2目标슬레이브2的数字量출력매개변수26读写目标슬레이브2数字量매개변수
7boolmbSalve2DO3目标슬레이브2的数字量출력매개변수37读写目标슬레이브2数字量매개변수
8boolmbSalve2DO4目标슬레이브2的数字量출력매개변수48读写目标슬레이브2数字量매개변수
目标슬레이브1매개변수列表
站주소:3;통신 속도:9600;데이터 비트:8;정지 비트:1;패리티 없음
순번데이터유형변수名称매개변수名称주소读写属性取值范围缺省值설명
1floatmbSalve3AI1目标슬레이브3的模拟量입력매개변수140001只读目标슬레이브3模拟매개변수
2uint32_tmbSalve3AI2目标슬레이브3的模拟量입력매개변수240003只读目标슬레이브3模拟매개변수
5uint16_tmbSalve3AI3目标슬레이브3的模拟量입력매개변수340005只读0目标슬레이브3模拟매개변수
6uint16_tmbSalve3AO1目标슬레이브3的模拟量출력매개변수140006读写目标슬레이브3模拟매개변수
7uint16_tmbSalve3AO2目标슬레이브3的模拟量출력매개변수240007读写0目标슬레이브3模拟매개변수
8uint16_tmbSalve3AO3目标슬레이브3的模拟量출력매개변수340008读写0目标슬레이브3模拟매개변수
1boolmbSalve3DI1目标슬레이브3的数字量입력매개변수11只读目标슬레이브3数字量매개변수
2boolmbSalve3DI2目标슬레이브3的数字量입력매개변수22只读目标슬레이브3数字量매개변수
3boolmbSalve3DI3目标슬레이브3的数字量입력매개변수33只读目标슬레이브3数字量매개변수
4boolmbSalve3DI4目标슬레이브3的数字量입력매개변수44只读目标슬레이브3数字量매개변수
5boolmbSalve3DO1目标슬레이브3的数字量출력매개변수15读写目标슬레이브3数字量매개변수
6boolmbSalve3DO2目标슬레이브3的数字量출력매개변수26读写目标슬레이브3数字量매개변수
7boolmbSalve3DO3目标슬레이브3的数字量출력매개변수37读写目标슬레이브3数字量매개변수
8boolmbSalve3DO4目标슬레이브3的数字量출력매개변수48读写目标슬레이브3数字量매개변수
目标슬레이브1매개변수列表
站주소:4;통신 속도:9600;데이터 비트:8;정지 비트:1;패리티 없음
순번데이터유형변수名称매개변수名称주소读写属性取值范围缺省值설명
1floatmbSalve4AI1目标슬레이브4的模拟量입력매개변수140001只读目标슬레이브4模拟매개변수
2uint32_tmbSalve4AI2目标슬레이브4的模拟量입력매개변수240003只读目标슬레이브4模拟매개변수
5uint16_tmbSalve4AI3目标슬레이브4的模拟量입력매개변수340005只读0目标슬레이브4模拟매개변수
6uint16_tmbSalve4AO1目标슬레이브4的模拟量출력매개변수140006读写目标슬레이브4模拟매개변수
7uint16_tmbSalve4AO2目标슬레이브4的模拟量출력매개변수240007读写0目标슬레이브4模拟매개변수
8uint16_tmbSalve4AO3目标슬레이브4的模拟量출력매개변수340008读写0目标슬레이브4模拟매개변수
1boolmbSalve4DI1目标슬레이브4的数字量입력매개변수11只读目标슬레이브4数字量매개변수
2boolmbSalve4DI2目标슬레이브4的数字量입력매개변수22只读目标슬레이브4数字量매개변수
3boolmbSalve4DI3目标슬레이브4的数字量입력매개변수33只读目标슬레이브4数字量매개변수
4boolmbSalve4DI4目标슬레이브4的数字量입력매개변수44只读目标슬레이브4数字量매개변수
5boolmbSalve4DO1目标슬레이브4的数字量출력매개변수15读写目标슬레이브4数字量매개변수
6boolmbSalve4DO2目标슬레이브4的数字量출력매개변수26读写目标슬레이브4数字量매개변수
7boolmbSalve4DO3目标슬레이브4的数字量출력매개변수37读写目标슬레이브4数字量매개변수
8boolmbSalve4DO4目标슬레이브4的数字量출력매개변수48读写目标슬레이브4数字量매개변수
실제 프로젝트에 이 자료를 활용하시겠습니까?

도구 센터에서 프레임 분석, CRC 검증, 장비 디버깅을 진행하거나 요청을 제출하여 선정 및 연동 제안을 받아보세요.

엔지니어 회원

이 글을 실행 가능한 디버깅 자료로 활용하세요

가입하면 고급 프레임 분석, 자료 패키지 다운로드, 코드 예제, 엔지니어링 사례, 우선 기술 지원을 이용할 수 있어 실제 프로젝트 납품에 적합합니다.

고급 도구 무제한 이용
자료 패키지와 코드 패키지
완전한 엔지니어링 사례 라이브러리
우선 기술 지원 채널

답글 작성

이메일 주소는 공개되지 않습니다. 必填项已用 * 标注