Рефакторинг modbus_core енумов и структур
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** MODBUS_LEGACY_API
|
||||
* @}
|
||||
*/
|
||||
@@ -21,7 +22,7 @@
|
||||
/** @cond Заглушки отключенных модулей */
|
||||
|
||||
#ifndef MODBUS_ENABLE_COILS
|
||||
#define MB_Coil_Write_Global(Addr, WriteVal) ILLEGAL_FUNCTION
|
||||
#define MB_Coil_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Coil_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Coils(modbus_msg) 0
|
||||
#define MB_Process_Write_Single_Coil(modbus_msg) 0
|
||||
@@ -29,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_HOLDINGS
|
||||
#define MB_Holding_Write_Global(Addr, WriteVal) ILLEGAL_FUNCTION
|
||||
#define MB_Holding_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Holding_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Hold_Regs(modbus_msg) 0
|
||||
#define MB_Process_Write_Single_Reg(modbus_msg) 0
|
||||
@@ -37,7 +38,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_INPUTS
|
||||
#define MB_Input_Write_Global(Addr, WriteVal) ILLEGAL_FUNCTION
|
||||
#define MB_Input_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Input_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Input_Regs(modbus_msg) 0
|
||||
#endif
|
||||
@@ -111,4 +112,4 @@
|
||||
#define MB_Slave_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
/** @endcond */
|
||||
|
||||
@@ -138,4 +138,5 @@ HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
|
||||
/** MODBUS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -115,4 +115,4 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
*/
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
#endif //__MODBUS_COILS_H_
|
||||
#endif //__MODBUS_COILS_H_
|
||||
|
||||
@@ -40,23 +40,23 @@
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
//-------------DEFINES FOR STRUCTURE----------------
|
||||
/* defines for structure of modbus message */
|
||||
#define ID_Transaction_size 2 ///< size of (ID_Transaction)
|
||||
#define ID_Protocol_size 2 ///< size of (ID_Protocol)
|
||||
#define PDU_Len_size 2 ///< size of (PDU Length)
|
||||
#define TransactionID_size 2 ///< size of (Transaction ID)
|
||||
#define ProtocolID_size 2 ///< size of (Protocol ID)
|
||||
#define PDULength_size 2 ///< size of (PDU Length)
|
||||
#define MbAddr_SIZE 1 ///< size of (Slave Addr)
|
||||
#define Func_Code_SIZE 1 ///< size of (Function Code)
|
||||
#define Addr_SIZE 2 ///< size of (Address)
|
||||
#define Qnt_SIZE 2 ///< size of (Quantity)
|
||||
#define ByteCnt_SIZE 1 ///< size of (Byte Count)
|
||||
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
|
||||
#define CRC_SIZE 2 ///< size of (MbCRC) in bytes
|
||||
|
||||
#ifndef MODBUS_PROTOCOL_TCP
|
||||
/** @brief Size of whole RTU message */
|
||||
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
||||
#else
|
||||
/** @brief Size of whole TCP message */
|
||||
#define INFO_SIZE_MAX (ID_Transaction_size+ID_Protocol_size+PDU_Len_size+MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE)
|
||||
#define INFO_SIZE_MAX (TransactionID_size+ProtocolID_size+PDULength_size+MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE)
|
||||
#endif
|
||||
|
||||
/** @brief Size of first part of message that will be received
|
||||
@@ -66,100 +66,104 @@ first receive info part of message, than defines size of rest message*/
|
||||
/** @brief Size of buffer: max size of whole message */
|
||||
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
||||
|
||||
/** @brief Structure for modbus exception codes */
|
||||
/**
|
||||
* @brief Enum for modbus exception codes
|
||||
* @details Prefix ET for Error Type
|
||||
*/
|
||||
typedef enum //MB_ExceptionTypeDef
|
||||
{
|
||||
// reading
|
||||
NO_ERRORS = 0x00, ///< no errors
|
||||
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ACKNOWLEDGE = 0x05, ///< idk
|
||||
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
ET_NO_ERRORS = 0x00, ///< no errors
|
||||
ET_ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ET_ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ET_ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
ET_SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ET_ACKNOWLEDGE = 0x05, ///< idk
|
||||
// ET_SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// ET_MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
}MB_ExceptionTypeDef;
|
||||
|
||||
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/** @brief Structure for modbus func codes */
|
||||
#define FC_ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/**
|
||||
* @brief Enum for modbus func codes
|
||||
* @details Prefix FC for Function Code
|
||||
*/
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
/* COMMANDS */
|
||||
// reading
|
||||
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
//FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
#else
|
||||
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
FC_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
FC_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
#endif
|
||||
|
||||
// writting
|
||||
MB_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
FC_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
FC_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
FC_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
FC_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
|
||||
MB_R_DIAGNOSTIC = 0x08, ///< Чтение диагностической информации устройства
|
||||
MB_R_DEVICE_INFO = 0x2B, ///< Чтение информации об устройстве
|
||||
FC_R_DIAGNOSTICS = 0x08, ///< Чтение диагностической информации устройства
|
||||
FC_R_DEVICE_ID = 0x2B, ///< Чтение информации об устройстве
|
||||
|
||||
/* ERRORS */
|
||||
// error reading
|
||||
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
//FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
|
||||
// error writting
|
||||
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
FC_ERR_W_COIL = FC_W_COIL + FC_ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
FC_ERR_W_HOLD_REG = FC_W_HOLD_REG + FC_ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
|
||||
MB_ERR_R_DIAGNOSTIC = MB_R_DIAGNOSTIC + ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||
MB_ERR_R_DEVICE_INFO = MB_R_DEVICE_INFO + ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||
MB_FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||
}MB_FunctonTypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
/** @brief Enum for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
|
||||
}MB_MEITypeDef;
|
||||
|
||||
/** @brief Structure for comformity */
|
||||
/**
|
||||
* @brief Enum for Read Device Id codes
|
||||
* @details Prefix RID for Read ID
|
||||
*/
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MB_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
||||
RID_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
||||
@details All objects of this category are mandatory:
|
||||
VendorName,Product code, and revision number */
|
||||
VendorName, Product code, and revision number */
|
||||
|
||||
MB_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
||||
RID_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
||||
@details The device provides additional and optional
|
||||
identifications and description data objects */
|
||||
|
||||
MB_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
||||
RID_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
||||
@details The device provides additional and optional
|
||||
identifications and description private data about the physical
|
||||
device itself. All of these data are device dependent. */
|
||||
|
||||
MB_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
||||
RID_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
||||
@details The device provides one specific identifications object. */
|
||||
|
||||
/* ERRORS */
|
||||
MB_ERR_BASIC_IDENTIFICATIONS = MB_BASIC_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_REGULAR_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_EXTENDED_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_SPEDIFIC_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
}MB_ConformityTypeDef;
|
||||
}ReadDevId;
|
||||
|
||||
/** @brief Structure for decive identifications message type */
|
||||
/** @brief Structure for device identifications message type */
|
||||
typedef struct
|
||||
{
|
||||
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
|
||||
MB_ConformityTypeDef ReadDevId;
|
||||
MB_ConformityTypeDef Conformity;
|
||||
ReadDevId ReadDevId;
|
||||
uint8_t Conformity; ///< Identification conformity level of the device and type of supported access @ref MODBUS_DEVICE_CONFORMITY
|
||||
uint8_t MoreFollows;
|
||||
uint8_t NextObjId;
|
||||
uint8_t NumbOfObj;
|
||||
@@ -170,22 +174,22 @@ typedef struct
|
||||
typedef struct // RS_MsgTypeDef
|
||||
{
|
||||
#ifdef MODBUS_PROTOCOL_TCP
|
||||
uint16_t ID_Transaction; ///< Modbus TCP: ID Transaction
|
||||
uint16_t ID_Protocol; ///< Modbus TCP: ID Protocol
|
||||
uint16_t PDU_Length; ///< Modbus TCP: PDU_Length
|
||||
uint16_t TransactionID; ///< Modbus TCP: ID Transaction
|
||||
uint16_t ProtocolID; ///< Modbus TCP: ID Protocol
|
||||
uint16_t PDULength; ///< Modbus TCP: PDU Length
|
||||
#endif
|
||||
|
||||
uint8_t MbAddr; ///< Modbus Slave Address
|
||||
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
|
||||
MB_FunctonTypeDef FuncCode; ///< Modbus Function Code
|
||||
MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
|
||||
uint16_t Addr; ///< Modbus Address of data
|
||||
uint16_t Qnt; ///< Quantity of modbus data
|
||||
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
||||
|
||||
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
|
||||
uint16_t MbData[DATA_SIZE]; ///< Modbus Data
|
||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||
|
||||
uint16_t MB_CRC; ///< Modbus CRC
|
||||
uint16_t MbCRC; ///< Modbus CRC
|
||||
}RS_MsgTypeDef;
|
||||
//--------------------------------------------------
|
||||
extern RS_MsgTypeDef MODBUS_MSG;
|
||||
@@ -306,4 +310,4 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
||||
#endif //__MODBUS_CORE_H_
|
||||
/** MODBUS_INTERNAL
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if MODBUS_NUMB_OF_USEROBJECTS > 0
|
||||
#define MODBUS_DEVICE_CONFORMITY 0x83
|
||||
#else
|
||||
#define MODBUS_DEVICE_CONFORMITY 0x82
|
||||
#endif
|
||||
|
||||
/** @brief Структура для объекта (идентификатора устройства модбас) */
|
||||
typedef struct
|
||||
{
|
||||
@@ -113,3 +119,4 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
#endif //__MODBUS_DEVID_H_
|
||||
|
||||
|
||||
@@ -119,4 +119,5 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
/** MODBUS_DIAG
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -117,7 +117,7 @@ ProjectRoot/
|
||||
```c
|
||||
#include "modbus.h"
|
||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||
RS_MsgTypeDef read_hold_cmd = MB_MASTER_READ_HOLDING_REGS(1, 0, 10);
|
||||
RS_MsgTypeDef read_hold_cmd = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
||||
// коллбек, вызовется при получении ответа от слейва
|
||||
read_hold[10];
|
||||
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||
|
||||
@@ -6,4 +6,3 @@
|
||||
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
||||
******************************************************************************/
|
||||
#include "modbus.h"
|
||||
|
||||
|
||||
@@ -206,4 +206,4 @@ RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modb
|
||||
{
|
||||
return MB_Master_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @brief Выставить/сбросить коил по глобальному адресу.
|
||||
* @param Addr Адрес коила.
|
||||
* @param WriteVal Что записать в коил: 0 или 1.
|
||||
* @return ExceptionCode Код исключения если коила по адресу не существует, и NO_ERRORS если все ок.
|
||||
* @return ExceptionCode Код исключения если коила по адресу не существует, и ET_NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||
Вне зависимости от того как коилы размещены в памяти.
|
||||
@@ -26,13 +26,13 @@
|
||||
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
//------------WRITE COIL-------------
|
||||
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
|
||||
if(Exception == NO_ERRORS)
|
||||
if(Exception == ET_NO_ERRORS)
|
||||
{
|
||||
switch(WriteVal)
|
||||
{
|
||||
@@ -75,7 +75,7 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||||
|
||||
//------------READ COIL--------------
|
||||
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
|
||||
if(*Exception == NO_ERRORS)
|
||||
if(*Exception == ET_NO_ERRORS)
|
||||
{
|
||||
return ((*coils)&(1<<start_shift));
|
||||
}
|
||||
@@ -99,7 +99,7 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------READING COIL------------
|
||||
@@ -127,14 +127,14 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
shift = 0; // set shift to zero for the next step
|
||||
|
||||
//-----------READ COILS--------------
|
||||
modbus_msg->DATA[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
||||
modbus_msg->MbData[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
||||
if(ind > 0)
|
||||
modbus_msg->DATA[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
||||
modbus_msg->MbData[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
||||
|
||||
}
|
||||
// т.к. DATA 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
||||
// т.к. MbData 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
||||
for(; ind >= 0; --ind)
|
||||
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]);
|
||||
modbus_msg->MbData[ind] = ByteSwap16(modbus_msg->MbData[ind]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -150,14 +150,14 @@ uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
|
||||
{
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -181,14 +181,14 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
|
||||
{ // if quantity too large OR if quantity and bytes count arent match
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils; // pointer to coils
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//----------WRITTING COILS-----------
|
||||
@@ -218,10 +218,10 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
// get current coils
|
||||
temp_reg = *(coils+ind);
|
||||
// set coils
|
||||
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift;
|
||||
setted_coils = ByteSwap16(modbus_msg->MbData[ind]) << start_shift;
|
||||
if(ind > 0)
|
||||
{
|
||||
setted_coils |= ((ByteSwap16(modbus_msg->DATA[ind-1]) << start_shift) >> 16);
|
||||
setted_coils |= ((ByteSwap16(modbus_msg->MbData[ind-1]) << start_shift) >> 16);
|
||||
}
|
||||
// write coils
|
||||
|
||||
@@ -237,4 +237,4 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_COILS
|
||||
#endif //MODBUS_ENABLE_COILS
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
В текущей реализации этот файл служит заглушкой для будущего расширения
|
||||
функциональности ядра Modbus протокола.
|
||||
******************************************************************************/
|
||||
#include "modbus_core.h"
|
||||
#include "modbus_core.h"
|
||||
|
||||
@@ -47,7 +47,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
||||
{
|
||||
MB_DeviceObjectTypeDef *obj = (MB_DeviceObjectTypeDef *)&MB_DEVID;
|
||||
unsigned objidtmp = modbus_msg->DevId.NextObjId;
|
||||
modbus_msg->Except_Code = NO_ERRORS;
|
||||
modbus_msg->Except_Code = ET_NO_ERRORS;
|
||||
|
||||
/* Define number of object in one message */
|
||||
unsigned lastobjid = 0;
|
||||
@@ -73,7 +73,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
||||
|
||||
|
||||
/* Fill message with objects data */
|
||||
char *mbdata = (char *)&modbus_msg->DATA;
|
||||
char *mbdata = (char *)&modbus_msg->MbData;
|
||||
unsigned ind = 0;
|
||||
unsigned objid = modbus_msg->DevId.NextObjId;
|
||||
for(; objid <= lastobjid; objid++)
|
||||
@@ -98,7 +98,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
||||
}
|
||||
else
|
||||
{
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,9 +111,11 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
||||
*/
|
||||
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
modbus_msg->DevId.Conformity = MODBUS_DEVICE_CONFORMITY;
|
||||
|
||||
switch(modbus_msg->DevId.ReadDevId)
|
||||
{
|
||||
case MB_BASIC_IDENTIFICATIONS:
|
||||
case RID_BASIC_IDENTIFICATIONS:
|
||||
if (modbus_msg->DevId.NextObjId == 0)
|
||||
{
|
||||
modbus_msg->DevId.NextObjId = 0;
|
||||
@@ -123,7 +125,7 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||
modbus_msg->DevId.NumbOfObj = 3;
|
||||
break;
|
||||
|
||||
case MB_REGULAR_IDENTIFICATIONS:
|
||||
case RID_REGULAR_IDENTIFICATIONS:
|
||||
if (modbus_msg->DevId.NextObjId == 0)
|
||||
{
|
||||
modbus_msg->DevId.NextObjId = 3;
|
||||
@@ -133,10 +135,10 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||
modbus_msg->DevId.NumbOfObj = 4;
|
||||
break;
|
||||
|
||||
case MB_EXTENDED_IDENTIFICATIONS:
|
||||
case RID_EXTENDED_IDENTIFICATIONS:
|
||||
if(MODBUS_NUMB_OF_USEROBJECTS <= 0 || MODBUS_NUMB_OF_USEROBJECTS > 128)
|
||||
{
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -149,7 +151,7 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||
modbus_msg->DevId.NumbOfObj = MODBUS_NUMB_OF_USEROBJECTS;
|
||||
break;
|
||||
|
||||
case MB_SPEDIFIC_IDENTIFICATIONS:
|
||||
case RID_SPEDIFIC_IDENTIFICATIONS:
|
||||
MB_WriteObjectsToMessage(modbus_msg, modbus_msg->DevId.NextObjId);
|
||||
modbus_msg->DevId.NumbOfObj = 1;
|
||||
break;
|
||||
@@ -157,7 +159,7 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -568,4 +570,4 @@ void MB_DeviceInentificationInit(void)
|
||||
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
|
||||
@@ -74,8 +74,8 @@ int MB_Diagnostics_GetBit(int bit_num)
|
||||
*/
|
||||
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
uint16_t sub_function = modbus_msg->DATA[0];
|
||||
uint16_t request_data = modbus_msg->DATA[1];
|
||||
uint16_t sub_function = modbus_msg->MbData[0];
|
||||
uint16_t request_data = modbus_msg->MbData[1];
|
||||
|
||||
// Если устройство в режиме Listen Only, отвечаем только на sub-function 0x01
|
||||
if (MB_DIAG.DeviceMode == MODBUS_LISTEN_ONLY_MODE && sub_function != 0x0001)
|
||||
@@ -87,8 +87,8 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
case 0x0000: // Return Query Data
|
||||
// Эхо-ответ с теми же данными
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = request_data;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = request_data;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
@@ -114,21 +114,21 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
||||
}
|
||||
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = request_data;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = request_data;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x0002: // Return Diagnostic Register
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.DiagnosticRegister;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.DiagnosticRegister;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x0003: // Change ASCII Input Delimiter
|
||||
// В RTU режиме не поддерживается
|
||||
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||
modbus_msg->Except_Code = ILLEGAL_FUNCTION;
|
||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
|
||||
return 0;
|
||||
|
||||
case 0x0004: // Force Listen Only Mode
|
||||
@@ -138,56 +138,56 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||
|
||||
case 0x000A: // Clear Counters and Diagnostic Register
|
||||
MB_DiagnosticsInit(); // Полный сброс
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = 0;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = 0;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x000B: // Return Bus Message Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.BusMessage;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusMessage;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x000C: // Return Bus Communication Error Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCommunicationErr;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusCommunicationErr;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x000D: // Return Bus Exception Error Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.BusExceptionErr;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusExceptionErr;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x000E: // Return Server Message Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveMessage;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveMessage;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x000F: // Return Slave No Response Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNoResponse;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNoResponse;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x0010: // Return Slave NAK Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNAK;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNAK;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x0011: // Return Slave Busy Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveBusy;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveBusy;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
case 0x0012: // Return Bus Character Overrun Count
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCharacterOverrun;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusCharacterOverrun;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
@@ -195,14 +195,14 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
||||
// Сбрасываем флаг переполнения в DiagnosticRegister
|
||||
MB_DIAG.DiagnosticRegister &= ~(1<<0);
|
||||
modbus_msg->DATA[0] = sub_function;
|
||||
modbus_msg->DATA[1] = 0;
|
||||
modbus_msg->MbData[0] = sub_function;
|
||||
modbus_msg->MbData[1] = 0;
|
||||
modbus_msg->ByteCnt = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||
modbus_msg->Except_Code = ILLEGAL_FUNCTION;
|
||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
||||
modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -293,4 +293,4 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
|
||||
return MB_DIAG.DeviceMode;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* @brief Записать регистр хранения по глобальному адресу.
|
||||
* @param Addr Адрес регистра.
|
||||
* @param WriteVal Число для записи.
|
||||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и NO_ERRORS если все ок.
|
||||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
||||
Вне зависимости от того как регистры размещены в памяти.
|
||||
@@ -37,12 +37,12 @@
|
||||
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
|
||||
uint16_t *pHoldRegs;
|
||||
|
||||
//------------WRITE COIL-------------
|
||||
Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
|
||||
if(Exception == NO_ERRORS)
|
||||
if(Exception == ET_NO_ERRORS)
|
||||
{
|
||||
*(pHoldRegs) = WriteVal;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||||
if(Exception) // if exception is not given to func fill it
|
||||
*Exception = Exception_tmp;
|
||||
|
||||
if(Exception_tmp == NO_ERRORS)
|
||||
if(Exception_tmp == ET_NO_ERRORS)
|
||||
{
|
||||
return *(pHoldRegs);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
int i;
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
modbus_msg->DATA[i] = *(pHoldRegs++);
|
||||
modbus_msg->MbData[i] = *(pHoldRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REG------------
|
||||
@@ -148,15 +148,15 @@ uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REGS-----------
|
||||
for (int i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
*(pHoldRegs++) = modbus_msg->DATA[i];
|
||||
*(pHoldRegs++) = modbus_msg->MbData[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_HOLDINGS
|
||||
#endif //MODBUS_ENABLE_HOLDINGS
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* @brief Записать входной регистр по глобальному адресу.
|
||||
* @param Addr Адрес регистра.
|
||||
* @param WriteVal Число для записи.
|
||||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и NO_ERRORS если все ок.
|
||||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
||||
Вне зависимости от того как регистры размещены в памяти.
|
||||
@@ -27,12 +27,12 @@
|
||||
MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
|
||||
uint16_t *pInRegs;
|
||||
|
||||
//------------WRITE COIL-------------
|
||||
Exception = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input);
|
||||
if(Exception == NO_ERRORS)
|
||||
if(Exception == ET_NO_ERRORS)
|
||||
{
|
||||
*(pInRegs) = WriteVal;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||||
if(Exception) // if exception is not given to func fill it
|
||||
*Exception = Exception_tmp;
|
||||
|
||||
if(Exception_tmp == NO_ERRORS)
|
||||
if(Exception_tmp == ET_NO_ERRORS)
|
||||
{
|
||||
return *(pInRegs);
|
||||
}
|
||||
@@ -85,7 +85,7 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
// get origin address for data
|
||||
uint16_t *pInRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -97,11 +97,11 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
if(*((int16_t *)pInRegs) > 0)
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
modbus_msg->MbData[i] = (*pInRegs++);
|
||||
else
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
modbus_msg->MbData[i] = (*pInRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_INPUTS
|
||||
#endif //MODBUS_ENABLE_INPUTS
|
||||
|
||||
@@ -29,9 +29,9 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с регистрами
|
||||
if((modbus_msg->Func_Code != MB_R_DISC_IN) &&
|
||||
(modbus_msg->Func_Code != MB_R_HOLD_REGS) &&
|
||||
(modbus_msg->Func_Code != MB_R_IN_REGS))
|
||||
if((modbus_msg->FuncCode != FC_R_DISC_IN) &&
|
||||
(modbus_msg->FuncCode != FC_R_HOLD_REGS) &&
|
||||
(modbus_msg->FuncCode != FC_R_IN_REGS))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
||||
return 0;
|
||||
|
||||
// Получаем значение регистра
|
||||
*reg_value = modbus_msg->DATA[reg_index];
|
||||
*reg_value = modbus_msg->MbData[reg_index];
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с коилами
|
||||
if(modbus_msg->Func_Code != MB_R_COILS)
|
||||
if(modbus_msg->FuncCode != FC_R_COILS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -91,9 +91,9 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
|
||||
|
||||
// Получаем байт и проверяем бит
|
||||
if(bit_index < 8)
|
||||
*coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
|
||||
*coil_state = (modbus_msg->MbData[data_index] >> (bit_index+8)) & 0x01;
|
||||
else
|
||||
*coil_state = ((modbus_msg->DATA[data_index]&0xFF) >> bit_index-8) & 0x01;
|
||||
*coil_state = ((modbus_msg->MbData[data_index]&0xFF) >> bit_index-8) & 0x01;
|
||||
|
||||
|
||||
return 1;
|
||||
@@ -112,7 +112,7 @@ int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
|
||||
return 0;
|
||||
}
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -134,12 +134,12 @@ int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_d
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||
uint8_t *data = (uint8_t*)modbus_msg->MbData;
|
||||
unsigned ind = 0;
|
||||
|
||||
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
|
||||
@@ -185,7 +185,7 @@ int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -193,7 +193,7 @@ int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_
|
||||
if(index >= modbus_msg->DevId.NumbOfObj)
|
||||
return 0;
|
||||
|
||||
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||
uint8_t *data = (uint8_t*)modbus_msg->MbData;
|
||||
unsigned ind = 0;
|
||||
|
||||
for(int i = 0; i <= index; i++)
|
||||
@@ -227,7 +227,7 @@ int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_
|
||||
|
||||
|
||||
/**
|
||||
* @brief Получить данные диагностики из сообщения (DATA[1])
|
||||
* @brief Получить данные диагностики из сообщения (MbData[1])
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @param data Указатель куда положить данные
|
||||
* @return 1 - успех, 0 - ошибка
|
||||
@@ -238,14 +238,14 @@ int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
|
||||
if(modbus_msg->FuncCode != FC_R_DIAGNOSTICS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
*data = modbus_msg->DATA[1];
|
||||
*data = modbus_msg->MbData[1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -264,24 +264,24 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
|
||||
|
||||
|
||||
// Master mode - calculating response size from slave
|
||||
if (modbus_msg->Func_Code & ERR_VALUES_START)
|
||||
if (modbus_msg->FuncCode & FC_ERR_VALUES_START)
|
||||
{
|
||||
// Error response: [Addr][Func|0x80][ExceptCode][CRC]
|
||||
mb_func_size = -1; // Only Exception Code
|
||||
}
|
||||
else if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
else if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||
mb_func_size = 1;
|
||||
}
|
||||
else if (modbus_msg->Func_Code == MB_R_DEVICE_INFO)
|
||||
else if (modbus_msg->FuncCode == FC_R_DEVICE_ID)
|
||||
{
|
||||
// Device identifications: variable size, need to read first to determine
|
||||
mb_func_size = 0; // Will be determined after reading header
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (modbus_msg->Func_Code & ~ERR_VALUES_START)
|
||||
switch (modbus_msg->FuncCode & ~FC_ERR_VALUES_START)
|
||||
{
|
||||
case 0x01: // Read Coils
|
||||
case 0x02: // Read Discrete Inputs
|
||||
@@ -329,25 +329,30 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||
|
||||
// set function code
|
||||
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||
modbus_uart_buff[ind++] = modbus_msg->FuncCode;
|
||||
|
||||
if(modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||
if(modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
|
||||
{
|
||||
// fill modbus header
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications request
|
||||
if(0) {}
|
||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // device identifications request
|
||||
{
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
||||
}
|
||||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
// Diagnostics: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] >> 8; // Sub-function HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
|
||||
}
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
else // classic modbus request
|
||||
{
|
||||
// set address
|
||||
@@ -359,12 +364,12 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
||||
modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF;
|
||||
|
||||
// for write multiple functions
|
||||
if((modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||||
if((modbus_msg->FuncCode == 0x0F) || (modbus_msg->FuncCode == 0x10))
|
||||
{
|
||||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||||
|
||||
// write data bytes
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||
{
|
||||
modbus_uart_buff[ind++] = tmp_data_addr[i];
|
||||
@@ -379,7 +384,7 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
||||
//---------------CRC----------------
|
||||
//---------[last 2 bytes]----------
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
modbus_msg->MB_CRC = CRC_VALUE;
|
||||
modbus_msg->MbCRC = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE & 0xFF;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||
|
||||
@@ -404,15 +409,17 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
||||
|
||||
// get function code (check if error response)
|
||||
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||
modbus_msg->FuncCode = modbus_uart_buff[ind++];
|
||||
|
||||
if(modbus_msg->Func_Code & ERR_VALUES_START) // error response
|
||||
if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // error response
|
||||
{
|
||||
modbus_msg->Except_Code = modbus_uart_buff[ind++];
|
||||
}
|
||||
else if(modbus_msg->Func_Code < ERR_VALUES_START) // normal response
|
||||
else if(modbus_msg->FuncCode < FC_ERR_VALUES_START) // normal response
|
||||
{
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications response
|
||||
if(0) {}
|
||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // device identifications response
|
||||
{
|
||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||
@@ -424,7 +431,7 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
modbus_msg->ByteCnt = 0;
|
||||
|
||||
// Парсинг объектов идентификации устройства
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
||||
int data_index = 0;
|
||||
|
||||
for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++)
|
||||
@@ -446,24 +453,27 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
modbus_msg->ByteCnt += (2 + object_length); // ID + длина + данные
|
||||
}
|
||||
}
|
||||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
|
||||
}
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
else // classic modbus response
|
||||
{
|
||||
// get byte count for read functions
|
||||
if((modbus_msg->Func_Code == 0x01) || (modbus_msg->Func_Code == 0x02) ||
|
||||
(modbus_msg->Func_Code == 0x03) || (modbus_msg->Func_Code == 0x04))
|
||||
if((modbus_msg->FuncCode == 0x01) || (modbus_msg->FuncCode == 0x02) ||
|
||||
(modbus_msg->FuncCode == 0x03) || (modbus_msg->FuncCode == 0x04))
|
||||
{
|
||||
modbus_msg->ByteCnt = modbus_uart_buff[ind++];
|
||||
|
||||
// read data bytes
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||
{
|
||||
if(i % 2 == 0) // HI byte
|
||||
@@ -473,8 +483,8 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
}
|
||||
}
|
||||
// for write functions - echo address and quantity
|
||||
else if((modbus_msg->Func_Code == 0x05) || (modbus_msg->Func_Code == 0x06) ||
|
||||
(modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||||
else if((modbus_msg->FuncCode == 0x05) || (modbus_msg->FuncCode == 0x06) ||
|
||||
(modbus_msg->FuncCode == 0x0F) || (modbus_msg->FuncCode == 0x10))
|
||||
{
|
||||
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
||||
@@ -488,10 +498,10 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
//---------------CRC----------------
|
||||
//----------[last 2 bytes]----------
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbCRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
|
||||
|
||||
if(modbus_msg->MB_CRC != CRC_VALUE)
|
||||
if(modbus_msg->MbCRC != CRC_VALUE)
|
||||
{
|
||||
TrackerCnt_Err(hmodbus->rs_err);
|
||||
return RS_PARSE_MSG_ERR;
|
||||
@@ -507,58 +517,58 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
||||
/** @brief Сформировать запрос на чтение коилов */
|
||||
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на чтение дискретных регистров */
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на чтение холдинг регистров */
|
||||
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на чтение инпут регистров */
|
||||
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на запись одного коила */
|
||||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на запись одного регистра */
|
||||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
/** @brief Сформировать запрос на запись нескольких регистров */
|
||||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
|
||||
// Calculate byte count and prepare data
|
||||
uint8_t byte_count = (quantity + 7) / 8;
|
||||
msg.ByteCnt = byte_count;
|
||||
|
||||
// Copy coil data to message DATA array
|
||||
// Copy coil data to message MbData array
|
||||
for(int i = 0; i < byte_count; i++) {
|
||||
if(i < DATA_SIZE) {
|
||||
msg.DATA[i] = coils_data[i];
|
||||
msg.MbData[i] = coils_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,13 +578,13 @@ RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start
|
||||
/** @brief Сформировать запрос на запись нескольких коилов */
|
||||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||
|
||||
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
|
||||
|
||||
// Copy register data to message DATA array
|
||||
// Copy register data to message MbData array
|
||||
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
|
||||
msg.DATA[i] = regs_data[i];
|
||||
msg.MbData[i] = regs_data[i];
|
||||
}
|
||||
|
||||
return msg;
|
||||
@@ -583,7 +593,7 @@ RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_
|
||||
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
||||
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DIAGNOSTIC, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DIAGNOSTICS, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
|
||||
@@ -654,26 +664,26 @@ RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr)
|
||||
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id)
|
||||
{
|
||||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||
return msg;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_MASTER
|
||||
#endif //MODBUS_ENABLE_MASTER
|
||||
|
||||
@@ -37,26 +37,26 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
}
|
||||
MB_Diagnostics_SlaveMessageCnt();
|
||||
|
||||
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
|
||||
if(modbus_msg->FuncCode < FC_ERR_VALUES_START)// if no errors after parsing
|
||||
{
|
||||
switch (modbus_msg->Func_Code)
|
||||
switch (modbus_msg->FuncCode)
|
||||
{
|
||||
// Read Coils
|
||||
case MB_R_COILS:
|
||||
case FC_R_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
// Read Hodling Registers
|
||||
case MB_R_HOLD_REGS:
|
||||
case FC_R_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
case MB_R_IN_REGS:
|
||||
case FC_R_IN_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
// Write Single Coils
|
||||
case MB_W_COIL:
|
||||
case FC_W_COIL:
|
||||
hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -66,7 +66,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_W_HOLD_REG:
|
||||
case FC_W_HOLD_REG:
|
||||
hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -77,7 +77,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
break;
|
||||
|
||||
// Write Multiple Coils
|
||||
case MB_W_COILS:
|
||||
case FC_W_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
break;
|
||||
|
||||
// Write Multiple Registers
|
||||
case MB_W_HOLD_REGS:
|
||||
case FC_W_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -98,12 +98,12 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_R_DEVICE_INFO:
|
||||
case FC_R_DEVICE_ID:
|
||||
hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
// Добавить в switch-case после других case:
|
||||
case MB_R_DIAGNOSTIC:
|
||||
case FC_R_DIAGNOSTICS:
|
||||
hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
@@ -126,7 +126,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
||||
{
|
||||
MB_Diagnostics_ExceptionErrorCnt();
|
||||
TrackerCnt_Warn(hmodbus->rs_err);
|
||||
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,26 +174,28 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
||||
{
|
||||
//------INFO ABOUT DATA/MESSAGE------
|
||||
#ifdef MODBUS_PROTOCOL_TCP
|
||||
modbus_uart_buff[ind++] = modbus_msg->ID_Transaction >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->ID_Transaction& 0xFF;
|
||||
modbus_uart_buff[ind++] = modbus_msg->TransactionID >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->TransactionID& 0xFF;
|
||||
|
||||
modbus_uart_buff[ind++] = modbus_msg->ID_Protocol >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->ID_Protocol& 0xFF;
|
||||
modbus_uart_buff[ind++] = modbus_msg->ProtocolID >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->ProtocolID& 0xFF;
|
||||
|
||||
modbus_uart_buff[ind++] = modbus_msg->PDU_Length >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->PDU_Length& 0xFF;
|
||||
modbus_uart_buff[ind++] = modbus_msg->PDULength >> 8;
|
||||
modbus_uart_buff[ind++] = modbus_msg->PDULength& 0xFF;
|
||||
#endif
|
||||
//-----------[first bytes]-----------
|
||||
// set ID of message/user
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||
|
||||
// set dat or err response
|
||||
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||
modbus_uart_buff[ind++] = modbus_msg->FuncCode;
|
||||
|
||||
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||
if (modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
|
||||
{
|
||||
// fill modbus header
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identifications header
|
||||
if(0) {}
|
||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // devide identifications header
|
||||
{
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||
@@ -211,7 +213,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||
@@ -219,14 +221,17 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
||||
}
|
||||
|
||||
}
|
||||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
// Diagnostics special format: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] >> 8; // Sub-function HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
|
||||
}
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
else // modbus data header
|
||||
{
|
||||
// set size of received data
|
||||
@@ -240,7 +245,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
if (i%2 == 0) // HI byte
|
||||
@@ -269,7 +274,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// write crc to message structure and modbus-uart buffer
|
||||
modbus_msg->MB_CRC = CRC_VALUE;
|
||||
modbus_msg->MbCRC = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||
#endif
|
||||
@@ -291,15 +296,15 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
|
||||
RS_StatusTypeDef MB_RES = 0;
|
||||
int mb_func_size = 0;
|
||||
|
||||
if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
mb_func_size = 1;
|
||||
}
|
||||
else if(modbus_msg->Func_Code == MB_R_DEVICE_INFO)
|
||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID)
|
||||
{
|
||||
mb_func_size = 0;
|
||||
}
|
||||
else if ((modbus_msg->Func_Code & ~ERR_VALUES_START) < 0x0F)
|
||||
else if ((modbus_msg->FuncCode & ~FC_ERR_VALUES_START) < 0x0F)
|
||||
{
|
||||
mb_func_size = 1;
|
||||
}
|
||||
@@ -330,14 +335,14 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
int expected_size = 0;
|
||||
//-----INFO ABOUT DATA/MESSAGE-------
|
||||
#ifdef MODBUS_PROTOCOL_TCP
|
||||
modbus_msg->ID_Transaction =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->ID_Transaction |=modbus_uart_buff[ind++];
|
||||
modbus_msg->TransactionID =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->TransactionID |=modbus_uart_buff[ind++];
|
||||
|
||||
modbus_msg->ID_Protocol =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->ID_Protocol |=modbus_uart_buff[ind++];
|
||||
modbus_msg->ProtocolID =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->ProtocolID |=modbus_uart_buff[ind++];
|
||||
|
||||
modbus_msg->PDU_Length =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->PDU_Length |=modbus_uart_buff[ind++];
|
||||
modbus_msg->PDULength =modbus_uart_buff[ind++]<<8;
|
||||
modbus_msg->PDULength |=modbus_uart_buff[ind++];
|
||||
#endif
|
||||
//-----------[first bits]------------
|
||||
// get ID of message/user
|
||||
@@ -352,33 +357,38 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
}
|
||||
|
||||
// get func code
|
||||
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->Func_Code & ERR_VALUES_START) // явная херня
|
||||
modbus_msg->FuncCode = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // явная херня
|
||||
{
|
||||
MB_Diagnostics_SlaveNAKCnt();
|
||||
modbus_msg->MbAddr = 0;
|
||||
return RS_SKIP;
|
||||
}
|
||||
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identifications request
|
||||
|
||||
if(0) {}
|
||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // if it device identifications request
|
||||
{
|
||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
||||
modbus_msg->ByteCnt = 0;
|
||||
}
|
||||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
||||
{
|
||||
// Diagnostics: читаем 4 байта в DATA[0] и DATA[1]
|
||||
// Diagnostics: читаем 4 байта в MbData[0] и MbData[1]
|
||||
// Sub-function
|
||||
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
|
||||
// Data
|
||||
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
|
||||
modbus_msg->Addr = 0; // не использует Addr
|
||||
modbus_msg->Qnt = 0; // не использует Qnt
|
||||
}
|
||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
||||
else // if its classic modbus request
|
||||
{
|
||||
// get address from CMD
|
||||
@@ -390,7 +400,7 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
||||
}
|
||||
|
||||
if((hmodbus->pMessagePtr->Func_Code == 0x0F) || (hmodbus->pMessagePtr->Func_Code == 0x10))
|
||||
if((hmodbus->pMessagePtr->FuncCode == 0x0F) || (hmodbus->pMessagePtr->FuncCode == 0x10))
|
||||
hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
|
||||
else
|
||||
hmodbus->pMessagePtr->ByteCnt = 0;
|
||||
@@ -417,11 +427,11 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2)
|
||||
{
|
||||
TrackerCnt_Err(hmodbus->rs_err);
|
||||
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
||||
MB_Diagnostics_CommunicationErrorCnt();
|
||||
return RS_PARSE_MSG_ERR;
|
||||
}
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||
{ // set data
|
||||
if (i%2 == 0)
|
||||
@@ -440,18 +450,18 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// get crc of received data
|
||||
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->MbCRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
|
||||
// compare crc
|
||||
if (modbus_msg->MB_CRC != CRC_VALUE)
|
||||
if (modbus_msg->MbCRC != CRC_VALUE)
|
||||
{
|
||||
MB_Diagnostics_CommunicationErrorCnt();
|
||||
TrackerCnt_Err(hmodbus->rs_err);
|
||||
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
||||
}
|
||||
#endif
|
||||
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
#endif //MODBUS_ENABLE_SLAVE
|
||||
#endif //MODBUS_ENABLE_SLAVE
|
||||
|
||||
@@ -67,4 +67,4 @@
|
||||
|
||||
|
||||
|
||||
#endif //_MODBUS_CONFIG_H_
|
||||
#endif //_MODBUS_CONFIG_H_
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
* @param Qnt Количество запрашиваемых элементов.
|
||||
* @param R_ARR_ADDR Начальный адресс массива R_ARR.
|
||||
* @param R_ARR_NUMB Количество элементов в массиве R_ARR.
|
||||
* @return ExceptionCode - ILLEGAL DATA ADRESS если адресс недействителен, и NO_ERRORS если все ок.
|
||||
* @return ExceptionCode - ET_ILLEGAL_DATA_ADRESS если адресс недействителен, и ET_NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
||||
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ILLEGAL_DATA_ADDRESSю.
|
||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ET_ILLEGAL_DATA_ADDRESSю.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
||||
{
|
||||
@@ -43,14 +43,14 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
||||
// if quantity too big return error
|
||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
// if all ok - return no errors
|
||||
return NO_ERRORS;
|
||||
return ET_NO_ERRORS;
|
||||
}
|
||||
// if address isnt from this array return error
|
||||
else
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for Input/Holding Registers
|
||||
@@ -58,7 +58,7 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
||||
* @param Addr Адрес начального регистра.
|
||||
* @param Qnt Количество запрашиваемых регистров.
|
||||
* @param WriteFlag Флаг регистр нужны для чтения или записи.
|
||||
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет.
|
||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра.
|
||||
* @note WriteFlag пока не используется.
|
||||
@@ -68,41 +68,41 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
||||
/* check quantity error */
|
||||
if (Qnt > DATA_SIZE)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
if(RegisterType == RegisterType_Holding)
|
||||
{
|
||||
// Default holding registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == NO_ERRORS)
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else if(RegisterType == RegisterType_Input)
|
||||
{
|
||||
// Default input registers
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == NO_ERRORS)
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ILLEGAL_FUNCTION;
|
||||
return ET_ILLEGAL_FUNCTION;
|
||||
}
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
return ET_NO_ERRORS; // return no errors
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for coils
|
||||
@@ -111,7 +111,7 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
||||
* @param Qnt Количество запрашиваемых коилов.
|
||||
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
||||
* @param WriteFlag Флаг коилы нужны для чтения или записи.
|
||||
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет.
|
||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра запрашиваемых коилов.
|
||||
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
||||
@@ -121,21 +121,21 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
||||
/* check quantity error */
|
||||
if (Qnt > 2000)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
// Default coils
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_COILS_ADDR, C_COILS_QNT) == NO_ERRORS)
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_COILS_ADDR, C_COILS_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr - C_COILS_ADDR); // указатель на выбранный по Addr массив коилов
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
|
||||
*start_shift = Addr % 16; // set shift to requested coil
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
}
|
||||
return ET_NO_ERRORS; // return no errors
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@
|
||||
uint16_t user_regs[16];
|
||||
|
||||
//...
|
||||
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_USER_ADDR, R_USER_QNT) == NO_ERRORS)
|
||||
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_USER_ADDR, R_USER_QNT) == ET_NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&user_regs, Addr-R_USER_ADDR); // ВАЖНО!
|
||||
// -R_USER_ADDR нужен чтобы взять адрес относительно начала массива
|
||||
}
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
return ET_ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
@endcode
|
||||
******************************************************************************/
|
||||
@@ -156,4 +156,4 @@ extern MB_DataStructureTypeDef MB_DATA;
|
||||
#endif //_MODBUS_DATA_H_
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
///////////////////////TEMP/OUTDATE/OTHER////////////////////
|
||||
///////////////////////TEMP/OUTDATE/OTHER////////////////////
|
||||
|
||||
Reference in New Issue
Block a user