You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.2 KiB
154 lines
4.2 KiB
#pragma once
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
/**
|
|
* @brief
|
|
*
|
|
* dep:
|
|
* basic_type.h
|
|
*
|
|
*
|
|
* TODO:
|
|
* 目前测试通过的功能码
|
|
* 0x04
|
|
* 0x10
|
|
*
|
|
*/
|
|
|
|
/*定义Modbus的操作功能码,支持01、02、03、04、05、06、15、16功能码*/
|
|
typedef enum {
|
|
// ReadCoilStatus 读线圈状态(读多个输出位的状态)
|
|
ModbusOrder01 = 0x01,
|
|
// ReadInputStatus 读输入位状态(读多个输入位的状态)
|
|
ModbusOrder02 = 0x02,
|
|
// ReadHoldingRegister 读保持寄存器(读多个保持寄存器的数值)
|
|
ModbusOrder03 = 0x03,
|
|
// ReadInputRegister 读输入寄存器(读多个输入寄存器的数值)
|
|
ModbusOrder04 = 0x04,
|
|
// WriteSingleCoil 强制单个线圈(强制单个输出位的状态)
|
|
ModbusOrder05 = 0x05,
|
|
// WriteSingleRegister 预制单个寄存器(设定一个寄存器的数值)
|
|
ModbusOrder06 = 0x06,
|
|
// WriteMultipleCoil 强制多个线圈(强制多个输出位的状态)
|
|
ModbusOrder0F = 0x0F,
|
|
// WriteMultipleRegister 预制多个寄存器(设定多个寄存器的数值)
|
|
ModbusOrder10 = 0x10,
|
|
// ReadFileRecord 读文件记录
|
|
ModbusOrder14 = 0x14,
|
|
// WriteFileRecord 写文件记录
|
|
ModbusOrder15 = 0x15,
|
|
// MaskWriteRegister 屏蔽写寄存器
|
|
ModbusOrder16 = 0x16,
|
|
// ReadWriteMultiRegister 读写多个寄存器
|
|
ModbusOrder17 = 0x17,
|
|
// ReadDeviceID读设备识别码
|
|
ModbusOrder2B = 0x2B,
|
|
} ModbusFunctionCode;
|
|
|
|
/*定义接收到指令检测错误时的错误码*/
|
|
typedef enum {
|
|
Modbus_OK = 0x00,
|
|
InvalidFunctionCode = 0x01, // 不合法功能代码
|
|
IllegalDataAddress = 0x02, // 非法的数据地址
|
|
IllegalDataValues = 0x03, // 非法的数据值或者范围
|
|
SlaveFailure = 0x04, // 从站设备故障
|
|
Acknowledgement = 0x05, // 确认
|
|
SlaveDeviceBusy = 0x06, // 从属设备忙
|
|
MemoryParityError = 0x08, // 存储奇偶性差错
|
|
GatewayDisabled = 0x0A, // 不可用网关路径
|
|
GatewayResponseFailed = 0x0B // 网关目标设备响应失败
|
|
} ModbusStatus;
|
|
|
|
typedef struct {
|
|
uint8_t deviceid;
|
|
ModbusFunctionCode functionCode;
|
|
union {
|
|
/**********read************/
|
|
struct {
|
|
uint16_t startbit; // bit
|
|
uint16_t numbit; // bit
|
|
} O01; // ReadCoilStatus
|
|
struct {
|
|
uint16_t startbit; // bit
|
|
uint16_t numbit; // bit
|
|
} O02; // ReadInputStatus
|
|
struct {
|
|
uint16_t startreg; // byte
|
|
uint16_t numreg; // reg(一个reg==16bit)
|
|
} O03; // ReadInputStatus
|
|
struct {
|
|
uint16_t startreg; // byte
|
|
uint16_t numreg; // reg(一个reg==16bit)
|
|
} O04; // ReadInputStatus
|
|
/**********write************/
|
|
struct {
|
|
uint16_t startbit; // bit
|
|
uint16_t numbit; // bit
|
|
uint8_t bytenum;
|
|
uint8_t *bit;
|
|
} O0F; // WriteMultipleCoil
|
|
struct {
|
|
uint16_t startreg; // byte
|
|
uint16_t numreg; // byte
|
|
uint8_t bytenum; // numreg*2
|
|
uint8_t *reg;
|
|
} O10; // WriteMultipleCoil
|
|
} d;
|
|
} ModbusMasterData_t;
|
|
|
|
typedef struct {
|
|
ModbusFunctionCode functionCode;
|
|
uint8_t deviceId;
|
|
union {
|
|
/**********read_receipt************/
|
|
struct {
|
|
uint8_t bytenum; // bit
|
|
uint8_t *byte_table;
|
|
} O01; // ReadCoilStatus
|
|
struct {
|
|
uint8_t bytenum; // byte_table
|
|
uint8_t *byte_table;
|
|
} O02; // ReadInputStatus
|
|
struct {
|
|
uint8_t bytenum; // byte
|
|
uint8_t *reg;
|
|
} O03; // ReadInputStatus
|
|
struct {
|
|
uint8_t bytenum; // byte
|
|
uint8_t *reg;
|
|
} O04; // ReadInputStatus
|
|
/**********write_receipt************/
|
|
struct {
|
|
uint16_t startbit;
|
|
uint16_t bitnum; // bit
|
|
} O0F; // WriteMultipleCoil-->对应01
|
|
struct {
|
|
uint16_t startreg;
|
|
uint16_t regnum; // byte
|
|
} O10; // --->对应03
|
|
} d;
|
|
} ModbusSlaveData_t;
|
|
/**
|
|
* @brief 生成CRC16校验码
|
|
*
|
|
* @param puckMsg 数据指针
|
|
* @param usDataLen 数据长度(不包含CRC16)
|
|
* @return uint16_t
|
|
*/
|
|
uint16_t modbus_gen_crc16(uint8_t *puckMsg, uint8_t usDataLen);
|
|
/**
|
|
* @brief 将CRC16校验码添加到数据包中
|
|
*
|
|
* @param puckMsg 数据指针,数据中预留两个位置给CRC16
|
|
* @param packetlen 数据长度
|
|
*/
|
|
void modbus_pack_crc_to_packet(uint8_t *puckMsg, uint8_t packetlen);
|
|
/**
|
|
* @brief 检查CRC16校验码
|
|
*
|
|
* @param message 数据指针
|
|
* @param length 数据长度(包含CRC16)
|
|
* @return true 校验成功
|
|
* @return false 校验失败
|
|
*/
|
|
bool modbus_checkcrc16(uint8_t *message, uint8_t length);
|