#ifndef __MODBUS_DEF_H__ #define __MODBUS_DEF_H__ #include "config.h" #include "serial.h" //---------------------------------------------------------------- // modbus 协议定义 /* */ //------------------------------------------------------------------ /*modbus地址规则,支持的寻址空间为256个 * ---------------------------------- * | 0 | 1-247 | 248-255 | * |--------------------------------- * |广播地址|子节点地址| 保留 | * |--------------------------------- */ #ifndef MODBUS_IDXMAX #define MODBUS_IDXMAX 247 // 支持的最大站号数 #endif #define MODBUS_LENMAX 50 // 数据包中数据最大值(单位: 字) #define MDBSRXLEN_A (MODBUS_LENMAX*4 + 21) // ASCII 方式 #define MDBSRXLEN_R (MODBUS_LENMAX*2 + 10) // RTU 方式 #define MDBSRXLEN_MAX MDBSRXLEN_A // 单位字节 //------------------------------------------------------------------ //------------------------------------------------------------------ // 支持的命令 #define READ_COIL_STATUS 0x01 // 读取线圈状态(位操作) #define READ_INPUT_STATUS 0x02 // 读取输入状态(位操作) #define READ_HOLDING_REGISTER 0x03 // 读取保持寄存器 #define READ_INPUT_REGISTER 0x04 // 读取输入寄存器 #define WRITE_SINGLE_COIL 0x05 // 写单个线圈(位操作) #define WRITE_SINGLE_REGISTER 0x06 // 写单个保持寄存器 #define WRITE_MULTIPLE_COIL 0x0F // 写多个线圈(位操作) #define WRITE_MULTIPLE_REGISTER 0x10 // 写多个保持寄存器 //------------------------------------------------------------------ #define MODBUS_RD READ_HOLDING_REGISTER // 读命令 #define MODBUS_WR WRITE_SINGLE_REGISTER // 写命令 #define MODBUS_WR_MULTI WRITE_MULTIPLE_REGISTER // 写多字命令 //------------------------------------------------------------------ #ifndef MODBUS_MAX_WR #define MODBUS_MAX_WR 10 #endif #ifndef MODBUS_MAX_RD #define MODBUS_MAX_RD 10 #endif typedef struct { // 命令数据 u8 midx; // 主站序号 u8 index; // 站号,1~247(十进制) u8 cmd; // 命令码 u16 addr; // 数据地址 u16 wrdat[MODBUS_MAX_WR]; // 写数据 u16 wlen; // 写数据长度 u16 rddat[MODBUS_MAX_RD]; // 读到的数据 u16 rlen; // 读取数据长度 }Rs485Cmd; #ifndef MAX_485CMD #define MAX_485CMD 20 #endif typedef void (*Resv485ExProc)(Rs485Cmd * pcmd); // 收到数据处理函数 typedef struct { int init; // 1:初始化完成 u8 idxNum; u8 idxList[MODBUS_IDXMAX]; // 站号列表,用于模拟多个从站的动作,1~247(十进制) Rs485Cmd cmdbuf[MAX_485CMD]; // 收发控制 int working; // 正在读写中; = 1, 工作中,不能收发新命令 int bufCmdNum; // 命令个数; != 0, 有新命令 int bufHead; int bufTail; int steps; u32 stepTime; Resv485ExProc resv485exproc; // 收到数据处理函数 int modrsvTimout; // 读取超时时间 }Rs485Ctrl; //------------------------------------------------------------------ typedef void (*OnOffFunc)(void); // 控制数据结构 typedef struct { int modBusMode; // 通讯模式, = 0, RTU模式; = 1, ASCII模式 int filterChk; // 过滤数据校验位标志, = 0, 不过滤; = 1, 过滤 u32 modBusWait; // 通讯延时, 单位us,发送一个字节所需时间 // 通讯函数指针 UsartSendData ModBusCommSend; // 发送数据 UsartGetData ModBusCommReceive; // 接收数据 UsartCleanRsBuf ModBusCommCleanRsBuf; // 清空接收缓冲区 IsUsartSendOver IsModBusCommSendOver; // 判断发送缓冲区是否为空 OnOffFunc CommOutEn; // 数据发送允许 OnOffFunc CommOutDis; // 数据发送禁止 }ModbusCtrl; // 注册modbus通讯函数 void RegisterModbusCommFunc(ModbusCtrl* pCtrl, UsartSendData send, UsartGetData get, UsartCleanRsBuf clean, IsUsartSendOver sdover, OnOffFunc outen, OnOffFunc outdis); //------------------------------------------------------------------ // 默认函数 int DefSendData(u8 * pDatBuf, int len); int DefGetData(u8 * pDat, int expectLen); int DefCleanRsBuf(void); int DefIsSendOver(void); void DefOutEn(void); void DefOutDis(void); u16 ModbusCrc16(u8 * puchMsg, u16 usDataLen); u8 AsciiToRtu(u8 ascii); u8 RtuToAscii(u8 rtu); #endif