Compare commits

10 Commits

Author SHA1 Message Date
Razvalyaev
0264ccd54e Фиксы табуляции 2025-11-06 18:15:42 +03:00
Razvalyaev
82cbdfe883 Документация отладки rs_message 2025-11-06 18:15:27 +03:00
Razvalyaev
920ceb1a3d Рефакторинг modbus_core енумов и структур 2025-11-06 17:53:37 +03:00
Razvalyaev
f7ab05d097 оптимизированы пользовательские объекты 2025-11-06 13:45:14 +03:00
Razvalyaev
8a2e7398e1 Перенос заглушек в modbus_compat и заготовки для TCP 2025-11-06 12:48:37 +03:00
Razvalyaev
510e8aec50 фикс чтения коилов в мастере 2025-11-06 10:18:18 +03:00
Razvalyaev
b71b799566 Добавлен протокол TCP, но не проверен 2025-11-05 18:18:55 +03:00
Razvalyaev
52143ce07c Мастер: коллбек вызывается и при таймауте
В коллбеке можно понять статус реквеста по hmodbus->RS_STATUS
2025-11-05 16:36:44 +03:00
Razvalyaev
5bbbbde3e6 Data Access API расширено функциями для чтения/записи регистров 2025-11-05 13:11:25 +03:00
Razvalyaev
fdf22949ed API для реквестов MB_RespGet.. перенесено в modbus_master 2025-11-05 12:49:05 +03:00
26 changed files with 1259 additions and 919 deletions

115
Inc/__modbus_compat.h Normal file
View File

@@ -0,0 +1,115 @@
/**
**************************************************************************
* @file __modbus_compat.h
* @brief Модуль для совместимости библиотеки MODBUS.
**************************************************************************
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
*************************************************************************/
#include "modbus.h"
/** @addtogroup MODBUS_LEGACY_API Legacy API
* @ingroup MODBUS_FUNCTIONS
* @{
*/
/** MODBUS_LEGACY_API
* @}
*/
/** @cond Заглушки отключенных модулей */
#ifndef MODBUS_ENABLE_COILS
#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
#define MB_Process_Write_Miltuple_Coils(modbus_msg) 0
#endif
#ifndef MODBUS_ENABLE_HOLDINGS
#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
#define MB_Process_Write_Miltuple_Regs(modbus_msg) 0
#endif
#ifndef MODBUS_ENABLE_INPUTS
#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
#ifndef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#define MB_WriteSingleObjectToMessage(mbdata, ind, obj)
#define MB_WriteObjectsToMessage(modbus_msg, maxidofobj)
#define MB_Process_Read_Device_Identifications(modbus_msg) 0
#define MB_DeviceInentificationInit()
#endif
#ifndef MODBUS_ENABLE_DIAGNOSTICS
#define MB_DiagnosticsInit()
#define MB_Diagnostics_WriteBit(bit_num, bit_state) 0
#define MB_Diagnostics_GetBit(bit_num) 0
#define MB_Process_Diagnostics(modbus_msg) 0
#define MB_Diagnostics_BusMessageCnt()
#define MB_Diagnostics_CommunicationErrorCnt()
#define MB_Diagnostics_ExceptionErrorCnt()
#define MB_Diagnostics_CharacterOverrunCnt()
#define MB_Diagnostics_SlaveMessageCnt()
#define MB_Diagnostics_SlaveNoResponseCnt()
#define MB_Diagnostics_SlaveNAKCnt()
#define MB_Diagnostics_SlaveBusyCnt()
#define MB_GetDeviceMode(void) MODBUS_NORMAL_MODE
#endif
#ifndef MODBUS_ENABLE_MASTER
#define MB_RespGet_RegisterValue(modbus_msg, reg_addr, reg_value) 0
#define MB_RespGet_CoilState(modbus_msg, coil_addr, coil_state) 0
#define MB_RespGet_NumberOfObjects(modbus_msg) 0
#define MB_RespGet_ObjectById(modbus_msg, obj_id, obj_data, obj_length) 0
#define MB_RespGet_ObjectByIndex(modbus_msg, index, obj_id, obj_data, obj_length) 0
#define MB_RespGet_Diagnostic(modbus_msg, data) 0
#define MB_REQUEST_READ_COILS(slave_addr, start_addr, quantity) {0}
#define MB_REQUEST_READ_DISCRETE_INPUTS(slave_addr, start_addr, quantity) {0}
#define MB_REQUEST_READ_HOLDING_REGS(slave_addr, start_addr, quantity) {0}
#define MB_REQUEST_READ_INPUT_REGS(slave_addr, start_addr, quantity) {0}
#define MB_REQUEST_WRITE_SINGLE_COIL(slave_addr, coil_addr, value) {0}
#define MB_REQUEST_WRITE_SINGLE_REG(slave_addr, reg_addr, value) {0}
#define MB_REQUEST_WRITE_MULTIPLE_COILS(slave_addr, start_addr, quantity, coils_data) {0}
#define MB_REQUEST_WRITE_MULTIPLE_REGS(slave_addr, start_addr, quantity, regs_data) {0}
#define MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, sub_function, data) {0}
#define MB_REQUEST_RETURN_QUERY_DATA(slave_addr) {0}
#define MB_REQUEST_RESTART_COMMUNICATIONS(slave_addr, data) {0}
#define MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(slave_addr) {0}
#define MB_REQUEST_FORCE_LISTEN_ONLY_MODE(slave_addr) {0}
#define MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(slave_addr) {0}
#define MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_SLAVE_NAK_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(slave_addr) {0}
#define MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(slave_addr) {0}
#define MB_REQUEST_READ_DEVICE_ID_BASIC(slave_addr) {0}
#define MB_REQUEST_READ_DEVICE_ID_REGULAR(slave_addr) {0}
#define MB_REQUEST_READ_DEVICE_ID_EXTENDED(slave_addr) {0}
#define MB_REQUEST_READ_DEVICE_ID_SPECIFIC(slave_addr, object_id) {0}
#define MB_Master_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
#define MB_Master_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
#endif
#ifndef MODBUS_ENABLE_SLAVE
#define MB_Slave_Response(hmodbus, modbus_msg) RS_ERR
#define MB_Slave_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
#define MB_Slave_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
#endif
/** @endcond */

View File

@@ -28,7 +28,7 @@
#include "modbus.h" #include "modbus.h"
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3); MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
MODBUS_Config(&hmodbus1, 1, 1000, MODBUS_MODE_SLAVE); MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
MODBUS_SlaveStart(&hmodbus1, NULL); MODBUS_SlaveStart(&hmodbus1, NULL);
@endverbatim @endverbatim
@verbatim @verbatim
@@ -36,14 +36,25 @@
#include "modbus.h" #include "modbus.h"
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3); MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER); // - если нужны другие настройки, не из modbus_config.h MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER);
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук // Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10); RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func); MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{ {
// modbus_msg содержит ответ от устройства // MB_RespGet_... Чтобы достать нужные данные из ответа
if(hmodbus->RS_STATUS == RS_OK)
{
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
{
uint16_t value;
if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
{
read_hold[i] = value;
}
}
}
} }
@endverbatim @endverbatim
@@ -73,15 +84,36 @@
#define __MODBUS_H_ #define __MODBUS_H_
#include "rs_message.h" #include "rs_message.h"
#ifdef MODBUS_ENABLE_MASTER
#include "modbus_master.h" #include "modbus_master.h"
#endif
#ifdef MODBUS_ENABLE_SLAVE
#include "modbus_slave.h" #include "modbus_slave.h"
#endif
#ifdef MODBUS_ENABLE_COILS
#include "modbus_coils.h" #include "modbus_coils.h"
#endif
#ifdef MODBUS_ENABLE_HOLDINGS
#include "modbus_holdregs.h" #include "modbus_holdregs.h"
#endif
#ifdef MODBUS_ENABLE_INPUTS
#include "modbus_inputregs.h" #include "modbus_inputregs.h"
#endif
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#include "modbus_devid.h" #include "modbus_devid.h"
#endif
#ifdef MODBUS_ENABLE_DIAGNOSTICS
#include "modbus_diag.h" #include "modbus_diag.h"
#endif
#ifdef MODBUS_ENABLE_MASTER
#define MODBUS_MODE_MASTER 1
#endif
#ifdef MODBUS_ENABLE_SLAVE
#define MODBUS_MODE_SLAVE 0
#endif
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
@@ -99,7 +131,7 @@ HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*)); HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*));
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_H_ #endif //__MODBUS_H_
@@ -107,3 +139,4 @@ HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
/** MODBUS_FUNCTIONS /** MODBUS_FUNCTIONS
* @} * @}
*/ */

View File

@@ -34,90 +34,11 @@ Coils упакованы в 16-битные слова для эффективн
//-------------------------------------------------- //--------------------------------------------------
/**
* @addtogroup MODBUS_COILS
* @{
*/
/**
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
* @param _parr_ - массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Mask
@verbatim Пояснение выражений
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
/**
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
@verbatim Пояснение выражений
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
Визуальный пример: 30 коил будет регистре[1], на 14 бите:
register = 30/16 = 1
bit = 30 - (16*30/16) = 30 - 16 = 14
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
/** MODBUS_COILS
* @}
*/
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_REQ_COILS_API API for Coils
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения coils из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
* int coil_state;
* if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
* {
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
* }
*
* // Пример: Получить состояние всех запрошенных coils
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
* {
* int state;
* if(MB_RespGet_CoilState(&MODBUS_MSG, addr, &state))
* {
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
* }
* }
* @endcode
* @{
*/
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
/** MODBUS_REQ_COILS_API
* @}
*/
/** /**
@@ -127,7 +48,7 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
* @{ * @{
*/ */
/** @brief Structure for coils operation */ /** @brief Enum for coils operation */
typedef enum typedef enum
{ {
SET_COIL, SET_COIL,
@@ -178,7 +99,6 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
* @} * @}
*/ */
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@{ @{
@@ -196,7 +116,3 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_COILS_H_ #endif //__MODBUS_COILS_H_
/** MODBUS_COILS
* @}
*/

View File

@@ -40,16 +40,24 @@
////////////////////---MODBUS MESSAGE DEFINES---///////////////////// ////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
//-------------DEFINES FOR STRUCTURE---------------- //-------------DEFINES FOR STRUCTURE----------------
/* defines for structure of modbus message */ /* defines for structure of modbus message */
#define MbAddr_SIZE 1 ///< size of (MbAddr) #define TransactionID_size 2 ///< size of (Transaction ID)
#define Func_Code_SIZE 1 ///< size of (Func_Code) #define ProtocolID_size 2 ///< size of (Protocol ID)
#define Addr_SIZE 2 ///< size of (Addr) #define PDULength_size 2 ///< size of (PDU Length)
#define Qnt_SIZE 2 ///< size of (Qnt) #define MbAddr_SIZE 1 ///< size of (Slave Addr)
#define ByteCnt_SIZE 1 ///< size of (ByteCnt) #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 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
/** @brief Size of whole message */ #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) #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 (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 /** @brief Size of first part of message that will be received
first receive info part of message, than defines size of rest message*/ first receive info part of message, than defines size of rest message*/
@@ -58,100 +66,104 @@ first receive info part of message, than defines size of rest message*/
/** @brief Size of buffer: max size of whole 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 #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 typedef enum //MB_ExceptionTypeDef
{ {
// reading // reading
NO_ERRORS = 0x00, ///< no errors ET_NO_ERRORS = 0x00, ///< no errors
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан ET_ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен ET_ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной ET_ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие ET_SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
// ACKNOWLEDGE = 0x05, ///< idk // ET_ACKNOWLEDGE = 0x05, ///< idk
// SLAVE_DEVICE_BUSY = 0x06, ///< idk // ET_SLAVE_DEVICE_BUSY = 0x06, ///< idk
// MEMORY_PARITY_ERROR = 0x08, ///< idk // ET_MEMORY_PARITY_ERROR = 0x08, ///< idk
}MB_ExceptionTypeDef; }MB_ExceptionTypeDef;
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes #define FC_ERR_VALUES_START 0x80U ///< from this value starts error func codes
/** @brief Structure for modbus func codes */ /**
* @brief Enum for modbus func codes
* @details Prefix FC for Function Code
*/
typedef enum //MB_FunctonTypeDef typedef enum //MB_FunctonTypeDef
{ {
/* COMMANDS */ /* COMMANDS */
// reading // reading
MB_R_COILS = 0x01, ///< Чтение битовых ячеек FC_R_COILS = 0x01, ///< Чтение битовых ячеек
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов //FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS #ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
#else #else
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров FC_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения FC_R_IN_REGS = 0x03, ///< Чтение регистров хранения
#endif #endif
// writting // writting
MB_W_COIL = 0x05, ///< Запись битовой ячейки FC_W_COIL = 0x05, ///< Запись битовой ячейки
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра FC_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек FC_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров FC_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
MB_R_DIAGNOSTIC = 0x08, ///< Чтение диагностической информации устройства FC_R_DIAGNOSTICS = 0x08, ///< Чтение диагностической информации устройства
MB_R_DEVICE_INFO = 0x2B, ///< Чтение информации об устройстве FC_R_DEVICE_ID = 0x2B, ///< Чтение информации об устройстве
/* ERRORS */ /* ERRORS */
// error reading // error reading
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов //FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
// error writting // error writting
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки FC_ERR_W_COIL = FC_W_COIL + FC_ERR_VALUES_START, ///< Ошибка записи битовой ячейки
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра FC_ERR_W_HOLD_REG = FC_W_HOLD_REG + FC_ERR_VALUES_START, ///< Ошибка записи одиночного регистра
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + 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, ///< Ошибка чтения диагностической информации устройства FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
MB_ERR_R_DEVICE_INFO = MB_R_DEVICE_INFO + ERR_VALUES_START, ///< Ошибка чтения информации об устройстве MB_FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
}MB_FunctonTypeDef; }MB_FunctonTypeDef;
/** @brief Structure for MEI func codes */ /** @brief Enum for MEI func codes */
typedef enum //MB_FunctonTypeDef typedef enum //MB_FunctonTypeDef
{ {
MEI_DEVICE_IDENTIFICATIONS = 0x0E, MEI_DEVICE_IDENTIFICATIONS = 0x0E,
}MB_MEITypeDef; }MB_MEITypeDef;
/** @brief Structure for comformity */ /**
* @brief Enum for Read Device Id codes
* @details Prefix RID for Read ID
*/
typedef enum //MB_FunctonTypeDef 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: @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 @details The device provides additional and optional
identifications and description data objects */ 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 @details The device provides additional and optional
identifications and description private data about the physical identifications and description private data about the physical
device itself. All of these data are device dependent. */ 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. */ @details The device provides one specific identifications object. */
/* ERRORS */ }ReadDevId;
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;
/** @brief Structure for decive identifications message type */ /** @brief Structure for device identifications message type */
typedef struct typedef struct
{ {
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
MB_ConformityTypeDef ReadDevId; ReadDevId ReadDevId;
MB_ConformityTypeDef Conformity; uint8_t Conformity; ///< Identification conformity level of the device and type of supported access @ref MODBUS_DEVICE_CONFORMITY
uint8_t MoreFollows; uint8_t MoreFollows;
uint8_t NextObjId; uint8_t NextObjId;
uint8_t NumbOfObj; uint8_t NumbOfObj;
@@ -161,17 +173,23 @@ typedef struct
/** @brief Structure for modbus messsage */ /** @brief Structure for modbus messsage */
typedef struct // RS_MsgTypeDef typedef struct // RS_MsgTypeDef
{ {
#ifdef MODBUS_PROTOCOL_TCP
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 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 MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
uint16_t Addr; ///< Modbus Address of data uint16_t Addr; ///< Modbus Address of data
uint16_t Qnt; ///< Quantity of modbus data uint16_t Qnt; ///< Quantity of modbus data
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive 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 MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
uint16_t MB_CRC; ///< Modbus CRC uint16_t MbCRC; ///< Modbus CRC
}RS_MsgTypeDef; }RS_MsgTypeDef;
//-------------------------------------------------- //--------------------------------------------------
extern RS_MsgTypeDef MODBUS_MSG; extern RS_MsgTypeDef MODBUS_MSG;
@@ -194,6 +212,42 @@ extern RS_MsgTypeDef MODBUS_MSG;
*/ */
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_)) #define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
/**
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
* @param _parr_ - массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Mask
@verbatim Пояснение выражений
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
/**
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
@verbatim Пояснение выражений
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
Визуальный пример: 30 коил будет регистре[1], на 14 бите:
register = 30/16 = 1
bit = 30 - (16*30/16) = 30 - 16 = 14
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endverbatim
*/
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
/** GENERAL_MODBUS_STUFF /** GENERAL_MODBUS_STUFF
* @} * @}
*/ */
@@ -233,7 +287,6 @@ extern RS_MsgTypeDef MODBUS_MSG;
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@{ @{
@@ -250,6 +303,9 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
/** MODBUS_CMD_PROCESS_FUNCTIONS /** MODBUS_CMD_PROCESS_FUNCTIONS
* @} * @}
*/ */
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_CORE_H_ #endif //__MODBUS_CORE_H_
/** MODBUS_INTERNAL /** MODBUS_INTERNAL

View File

@@ -31,6 +31,12 @@
* @{ * @{
*/ */
#if MODBUS_NUMB_OF_USEROBJECTS > 0
#define MODBUS_DEVICE_CONFORMITY 0x83
#else
#define MODBUS_DEVICE_CONFORMITY 0x82
#endif
/** @brief Структура для объекта (идентификатора устройства модбас) */ /** @brief Структура для объекта (идентификатора устройства модбас) */
typedef struct typedef struct
{ {
@@ -86,52 +92,6 @@ void MB_DeviceInentificationInit(void);
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения идентификторов из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример 1: Получить VendorName (ID = 0x00)
* uint8_t length;
* char vendor_name[64];
* if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
* {
* // получено
* }
*
* // Пример 2: Перебрать все объекты в сообщении
* uint8_t obj_id, obj_length;
* char obj_data[256];
*
* int obj_count = MB_RespGet_NumberOfObjects(&MODBUS_MSG);
* printf("Total objects: %d\n", obj_count);
*
* for(int i = 0; i < obj_count; i++)
* {
* if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
* {
* // получено
* }
* }
* @endcode
* @{
*/
/* Получить количество объектов в сообщении */
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg);
/* Найти объект по ID в сообщении */
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
/* Получить объект по индексу в сообщении */
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length);
/** MODBUS_REQ_DEFID_API
* @}
*/
/** /**
* @addtogroup MODBUS_DEVID * @addtogroup MODBUS_DEVID
* @{ * @{
@@ -145,7 +105,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj);
/** MODBUS_DEVID /** MODBUS_DEVID
* @} * @}
*/ */
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@{ @{
@@ -159,3 +119,4 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_DEVID_H_ #endif //__MODBUS_DEVID_H_

View File

@@ -65,29 +65,6 @@ void MB_DiagnosticsInit(void);
* @} * @}
*/ */
/**
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения диагностической информации из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Получить данные диагностики (значение счетчика)
* uint16_t counter_value;
* if(MB_RespGet_Diagnostic(&MODBUS_MSG, &counter_value))
* {
* printf("Counter value: %d\n", counter_value);
* }
* @endcode
* @{
*/
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data);
/** MODBUS_REQ_DIAG_API
* @}
*/
@@ -121,7 +98,6 @@ void MB_Diagnostics_SlaveBusyCnt(void);
* @} * @}
*/ */
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@{ @{
@@ -144,3 +120,4 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
/** MODBUS_DIAG /** MODBUS_DIAG
* @} * @}
*/ */

View File

@@ -23,7 +23,22 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
//---------PROCESS MODBUS COMMAND FUNCTIONS--------- /**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
* @{
*/
/* Записать регистр хранения по глобальному адресу. */
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal);
/* Считать регистр хранения по глобальному адресу. */
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
/** MODBUS_DATA_ACCESS_FUNCTIONS
* @}
*/
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@{ @{

View File

@@ -21,7 +21,21 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
//---------PROCESS MODBUS COMMAND FUNCTIONS--------- /**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
* @{
*/
/* Записать входной регистр по глобальному адресу. */
MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal);
/* Считать входной регистр по глобальному адресу. */
uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
/** MODBUS_DATA_ACCESS_FUNCTIONS
* @}
*/
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
* @ingroup MODBUS_INTERNAL * @ingroup MODBUS_INTERNAL

View File

@@ -14,10 +14,6 @@
#include "rs_message.h" #include "rs_message.h"
#ifdef MODBUS_ENABLE_MASTER
#define MODBUS_MODE_MASTER 1
#endif
/** /**
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests * @addtogroup MODBUS_REQUEST_MSG API for Master Requests
* @ingroup MODBUS_FUNCTIONS * @ingroup MODBUS_FUNCTIONS
@@ -109,6 +105,115 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
* @} * @}
*/ */
/**
* @addtogroup MODBUS_REQ_COILS_API API for Coils
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения coils из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
* int coil_state;
* if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
* {
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
* }
*
* // Пример: Получить состояние всех запрошенных coils
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
* {
* int state;
* if(MB_RespGet_CoilState(&MODBUS_MSG, addr, &state))
* {
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
* }
* }
* @endcode
* @{
*/
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
/** MODBUS_REQ_COILS_API
* @}
*/
/**
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения идентификторов из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример 1: Получить VendorName (ID = 0x00)
* uint8_t length;
* char vendor_name[64];
* if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
* {
* // получено
* }
*
* // Пример 2: Перебрать все объекты в сообщении
* uint8_t obj_id, obj_length;
* char obj_data[256];
*
* int obj_count = MB_RespGet_NumberOfObjects(&MODBUS_MSG);
* printf("Total objects: %d\n", obj_count);
*
* for(int i = 0; i < obj_count; i++)
* {
* if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
* {
* // получено
* }
* }
* @endcode
* @{
*/
/* Получить количество объектов в сообщении */
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg);
/* Найти объект по ID в сообщении */
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
/* Получить объект по индексу в сообщении */
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length);
/** MODBUS_REQ_DEFID_API
* @}
*/
/**
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения диагностической информации из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Получить данные диагностики (значение счетчика)
* uint16_t counter_value;
* if(MB_RespGet_Diagnostic(&MODBUS_MSG, &counter_value))
* {
* printf("Counter value: %d\n", counter_value);
* }
* @endcode
* @{
*/
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data);
/** MODBUS_REQ_DIAG_API
* @}
*/
/** /**
* @addtogroup MODBUS_MASTER * @addtogroup MODBUS_MASTER
* @{ * @{

View File

@@ -15,9 +15,6 @@
#include "rs_message.h" #include "rs_message.h"
#ifdef MODBUS_ENABLE_SLAVE
#define MODBUS_MODE_SLAVE 0
#endif
/** /**
* @addtogroup MODBUS_SLAVE * @addtogroup MODBUS_SLAVE
* @{ * @{

View File

@@ -76,48 +76,74 @@
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1) #define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
#ifndef printf_rs_err
#define printf_rs_err(...)
#endif
#ifndef printf_rs
#define printf_rs(...)
#endif
#ifndef __MYLIBS_CONFIG_H_
// дефайны из mylibs include
static int dummy;
#define TrackerTypeDef(num_user_vars) void *
#define num_of_usercnts(_user_) 0
#define assert_tracecnt(_cntstruct_, _uservarnumb_) 0
#define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(0)
#define tern_assert_usertracker(_cntstruct_, _uservarnumb_) 0
#define TrackerGet_Ok(_cntstruct_) dummy
#define TrackerGet_Err(_cntstruct_) dummy
#define TrackerGet_Warn(_cntstruct_) dummy
#define TrackerGet_User(_cntstruct_, _uservarnumb_) dummy
#define TrackerCnt_Ok(_cntstruct_)
#define TrackerCnt_Err(_cntstruct_)
#define TrackerCnt_Warn(_cntstruct_)
#define TrackerCnt_User(_cntstruct_, _uservarnumb_)
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
#define TrackerClear_All(_cntstruct_)
#define TrackerClear_Ok(_cntstruct_)
#define TrackerClear_Err(_cntstruct_)
#define TrackerClear_Warn(_cntstruct_)
#define TrackerClear_User(_cntstruct_)
#define TrackerClear_UserAll(_cntstruct_)
#else
#include "mylibs_include.h"
#endif
#ifndef RS_USER_VARS_NUMB #ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0 #define RS_USER_VARS_NUMB 0
#endif #endif
#ifndef local_time
#define local_time() uwTick
#endif
/** @endcond */ /** @endcond */
/**
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
* @ingroup RS_TOOLS
* @{
*/
#ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0 ///< Количество переменных в @ref TrackerTypeDef
#endif
/**
* @brief Тип структуры для счетчиков-переменных
* @param num_user_vars Есть возмоность добавления num_user_vars количества пользовательскиъх переменных
*/
#define TrackerTypeDef(num_user_vars) void *
/** @brief Инкрементировать переменную - успешных событий */
#define TrackerCnt_Ok(_cntstruct_)
/** @brief Инкрементировать переменную - ошибок */
#define TrackerCnt_Err(_cntstruct_)
/** @brief Инкрементировать переменную - предупреждений */
#define TrackerCnt_Warn(_cntstruct_)
#ifndef printf_rs
/** @brief Printf обычных событий RS/UART/TIM */
#define printf_rs(...)
#endif
#ifndef printf_rs_err
/** @brief Printf ошибок RS/UART/TIM */
#define printf_rs_err(...)
#endif
#ifndef RS_TIM_Handler_ENTER
/** @brief Действия при заходе в прерывания таймера */
#define RS_TIM_Handler_ENTER()
#endif
#ifndef RS_TIM_Handler_EXIT
/** @brief Действия при выходе из прерывания таймера */
#define RS_TIM_Handler_EXIT()
#endif
#ifndef RS_UART_Handler_ENTER
/** @brief Действия при заходе в прерывания UART */
#define RS_UART_Handler_ENTER()
#endif
#ifndef RS_UART_Handler_EXIT
/** @brief Действия при выходе из прерывания UART */
#define RS_UART_Handler_EXIT()
#endif
/** RS_TOOLS
* @}
*/
// направление передачи rs485 // направление передачи rs485
#ifndef RS_EnableReceive #ifndef RS_EnableReceive
#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485 #define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
@@ -141,9 +167,10 @@ typedef enum // RS_StatusTypeDef
/*0x03*/ RS_ABORTED, /*0x03*/ RS_ABORTED,
/*0x04*/ RS_BUSY, /*0x04*/ RS_BUSY,
/*0x05*/ RS_SKIP, /*0x05*/ RS_SKIP,
/*0x06*/ RS_TIMEOUT,
/*0x06*/ RS_COLLECT_MSG_ERR, /*0x07*/ RS_COLLECT_MSG_ERR,
/*0x07*/ RS_PARSE_MSG_ERR, /*0x08*/ RS_PARSE_MSG_ERR,
// reserved values // reserved values
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero) // /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)

View File

@@ -117,12 +117,14 @@ ProjectRoot/
```c ```c
#include "modbus.h" #include "modbus.h"
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук // Запрос на 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]; read_hold[10];
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{ {
// MB_RespGet_... Чтобы достать нужные данные из ответа // MB_RespGet_... Чтобы достать нужные данные из ответа
if(hmodbus->RS_STATUS == RS_OK)
{
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++) for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
{ {
uint16_t value; uint16_t value;
@@ -132,6 +134,7 @@ ProjectRoot/
} }
} }
} }
}
int main(void) int main(void)
{ {
// Инициализация HAL // Инициализация HAL

8
Src/__modbus_compat.c Normal file
View File

@@ -0,0 +1,8 @@
/**
**************************************************************************
* @file __modbus_compat.c
* @brief Модуль для совместимости библиотеки MODBUS.
**************************************************************************
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
******************************************************************************/
#include "modbus.h"

View File

@@ -18,7 +18,7 @@
* @brief Выставить/сбросить коил по глобальному адресу. * @brief Выставить/сбросить коил по глобальному адресу.
* @param Addr Адрес коила. * @param Addr Адрес коила.
* @param WriteVal Что записать в коил: 0 или 1. * @param WriteVal Что записать в коил: 0 или 1.
* @return ExceptionCode Код исключения если коила по адресу не существует, и NO_ERRORS если все ок. * @return ExceptionCode Код исключения если коила по адресу не существует, и ET_NO_ERRORS если все ок.
* *
* @details Позволяет обратиться к любому коилу по его глобальному адрессу. * @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти. Вне зависимости от того как коилы размещены в памяти.
@@ -26,13 +26,13 @@
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal) MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
{ {
//---------CHECK FOR ERRORS---------- //---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = NO_ERRORS; MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
uint16_t *coils; uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register uint16_t start_shift = 0; // shift in coils register
//------------WRITE COIL------------- //------------WRITE COIL-------------
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1); Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
if(Exception == NO_ERRORS) if(Exception == ET_NO_ERRORS)
{ {
switch(WriteVal) switch(WriteVal)
{ {
@@ -57,7 +57,7 @@ MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteV
/** /**
* @brief Считать коил по глобальному адресу. * @brief Считать коил по глобальному адресу.
* @param Addr Адрес коила. * @param Addr Адрес коила.
* @param Exception Указатель на переменную для кода исключения, в случа неудачи при чтении. * @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
* @return uint16_t Возвращает весь регистр с маской на запрошенном коиле. * @return uint16_t Возвращает весь регистр с маской на запрошенном коиле.
* *
* @details Позволяет обратиться к любому коилу по его глобальному адрессу. * @details Позволяет обратиться к любому коилу по его глобальному адрессу.
@@ -75,7 +75,7 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
//------------READ COIL-------------- //------------READ COIL--------------
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0); *Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
if(*Exception == NO_ERRORS) if(*Exception == ET_NO_ERRORS)
{ {
return ((*coils)&(1<<start_shift)); return ((*coils)&(1<<start_shift));
} }
@@ -86,51 +86,6 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
} }
/**
* @brief Получить состояние coil в ответе по его адресу
* @param modbus_msg Указатель на структуру сообщения
* @param coil_addr Адрес coil, состояние которого нужно получить
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
*/
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
{
if(modbus_msg == NULL || coil_state == NULL)
return 0;
// Проверяем что ответ связан с коилами
if(modbus_msg->Func_Code != MB_R_COILS)
{
return 0;
}
// Проверяем что coil_addr в пределах запрошенного диапазона
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0;
// Вычисляем индекс coil в полученных данных
uint16_t coil_index = coil_addr - modbus_msg->Addr;
// Вычисляем байт и бит
uint8_t byte_index = coil_index / 8;
uint8_t data_index = coil_index / 16;
uint8_t bit_index = coil_index % 16;
// Проверяем что байт существует в данных
if(byte_index >= modbus_msg->ByteCnt)
return 0;
// Получаем байт и проверяем бит
if(bit_index < 8)
*coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
else
*coil_state = (modbus_msg->DATA[data_index] >> bit_index) & 0x01;
return 1;
}
/** /**
* @brief Обработать функцию Read Coils (01 - 0x01). * @brief Обработать функцию Read Coils (01 - 0x01).
* @param modbus_msg Указатель на структуру собщения modbus. * @param modbus_msg Указатель на структуру собщения modbus.
@@ -144,7 +99,7 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
uint16_t start_shift = 0; // shift in coils register 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); 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; return 0;
//-----------READING COIL------------ //-----------READING COIL------------
@@ -172,14 +127,14 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
shift = 0; // set shift to zero for the next step shift = 0; // set shift to zero for the next step
//-----------READ COILS-------------- //-----------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) 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) for(; ind >= 0; --ind)
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]); modbus_msg->MbData[ind] = ByteSwap16(modbus_msg->MbData[ind]);
return 1; return 1;
} }
@@ -195,14 +150,14 @@ uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
//---------CHECK FOR ERRORS---------- //---------CHECK FOR ERRORS----------
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00)) 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; return 0;
} }
// define position of coil // define position of coil
uint16_t *coils; uint16_t *coils;
uint16_t start_shift = 0; // shift in coils register uint16_t start_shift = 0; // shift in coils register
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1); 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; return 0;
@@ -226,14 +181,14 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
//---------CHECK FOR ERRORS---------- //---------CHECK FOR ERRORS----------
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8)) if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
{ // if quantity too large OR if quantity and bytes count arent match { // 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; return 0;
} }
// define position of coil // define position of coil
uint16_t *coils; // pointer to coils uint16_t *coils; // pointer to coils
uint16_t start_shift = 0; // shift in coils register 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); 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; return 0;
//----------WRITTING COILS----------- //----------WRITTING COILS-----------
@@ -263,10 +218,10 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
// get current coils // get current coils
temp_reg = *(coils+ind); temp_reg = *(coils+ind);
// set coils // set coils
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift; setted_coils = ByteSwap16(modbus_msg->MbData[ind]) << start_shift;
if(ind > 0) 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 // write coils
@@ -281,14 +236,5 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
return 1; return 1;
} }
#else //MODBUS_ENABLE_COILS
#endif //MODBUS_ENABLE_COILS
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal) {return ILLEGAL_FUNCTION;}
uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;}
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
#endif

View File

@@ -1,7 +1,7 @@
/** /**
****************************************************************************** ******************************************************************************
* @file modbus_core.c * @file modbus_core.c
* @brief Базовая реализация ядра Modbus (заглушка) * @brief Базовая реализация ядра Modbus
****************************************************************************** ******************************************************************************
* @details * @details
В текущей реализации этот файл служит заглушкой для будущего расширения В текущей реализации этот файл служит заглушкой для будущего расширения

View File

@@ -21,132 +21,6 @@
MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная структура идентификаторов устройства MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная структура идентификаторов устройства
/**
* @brief Получить количество объектов в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @return int Количество объектов
*/
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
{
if(modbus_msg == NULL)
{
return 0;
}
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
return modbus_msg->DevId.NumbOfObj;
}
/**
* @brief Найти объект по ID в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @param obj_id ID искомого объекта
* @param obj_data Буфер для данных объекта (может быть NULL)
* @param obj_length Указатель для длины объекта
* @return int Найден ли объект (1 - да, 0 - нет)
*/
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
uint8_t *data = (uint8_t*)modbus_msg->DATA;
unsigned ind = 0;
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
{
uint8_t current_id = data[ind++];
uint8_t current_length = data[ind++];
if(current_id == obj_id)
{
if(obj_length)
*obj_length = current_length;
for(int j = 0; j < current_length; j++)
{
obj_data[j] = data[ind++];
}
obj_data[current_length] = '\0'; // добавляем \0
return 1;
}
else
{
// Пропускаем данные этого объекта
ind += current_length;
}
}
return 0;
}
/**
* @brief Получить объект по индексу в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @param index Индекс объекта (0..N-1)
* @param obj_id Указатель для ID объекта
* @param obj_data Буфер для данных объекта
* @param obj_length Указатель для длины объекта
* @return int Успешность получения (1 - получен, 0 - не найден)
*/
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
if(index >= modbus_msg->DevId.NumbOfObj)
return 0;
uint8_t *data = (uint8_t*)modbus_msg->DATA;
unsigned ind = 0;
for(int i = 0; i <= index; i++)
{
uint8_t current_id = data[ind++];
uint8_t current_length = data[ind++];
if(obj_id)
*obj_id = current_id;
if(obj_length)
*obj_length = current_length;
if(i == index)
{
for(int j = 0; j < current_length; j++)
{
obj_data[j] = data[ind++];
}
obj_data[current_length] = '\0'; // добавляем \0
return 1;
}
else
{
// Пропускаем данные этого объекта
ind += current_length;
}
}
return 0;
}
/** /**
@@ -173,11 +47,16 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
{ {
MB_DeviceObjectTypeDef *obj = (MB_DeviceObjectTypeDef *)&MB_DEVID; MB_DeviceObjectTypeDef *obj = (MB_DeviceObjectTypeDef *)&MB_DEVID;
unsigned objidtmp = modbus_msg->DevId.NextObjId; unsigned objidtmp = modbus_msg->DevId.NextObjId;
modbus_msg->Except_Code = ET_NO_ERRORS;
/* Define number of object in one message */ /* Define number of object in one message */
unsigned lastobjid = 0; unsigned lastobjid = 0;
for(int i = 0; i < DATA_SIZE*2;) for(int i = 0; i < DATA_SIZE*2;)
{ {
/* Если объект за пределами допутимого - выходим из цикла */
if(objidtmp >= 0xFF + MODBUS_NUMB_OF_USEROBJECTS)
break;
i += 2; i += 2;
i += obj[objidtmp].length; i += obj[objidtmp].length;
/* Если все еще помещается в массив переходим на следующий объект */ /* Если все еще помещается в массив переходим на следующий объект */
@@ -185,6 +64,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
{ {
objidtmp++; objidtmp++;
} }
/* Если объекты для записи закончились - выходим из цикла*/ /* Если объекты для записи закончились - выходим из цикла*/
if(objidtmp > maxidofobj) if(objidtmp > maxidofobj)
break; break;
@@ -193,7 +73,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
/* Fill message with objects data */ /* Fill message with objects data */
char *mbdata = (char *)&modbus_msg->DATA; char *mbdata = (char *)&modbus_msg->MbData;
unsigned ind = 0; unsigned ind = 0;
unsigned objid = modbus_msg->DevId.NextObjId; unsigned objid = modbus_msg->DevId.NextObjId;
for(; objid <= lastobjid; objid++) for(; objid <= lastobjid; objid++)
@@ -202,6 +82,9 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
MB_WriteSingleObjectToMessage(mbdata, &ind, &obj[objid]); MB_WriteSingleObjectToMessage(mbdata, &ind, &obj[objid]);
} }
objid--; objid--;
if(modbus_msg->ByteCnt != 0)
{
modbus_msg->ByteCnt = ind; modbus_msg->ByteCnt = ind;
modbus_msg->DevId.NextObjId = lastobjid+1; modbus_msg->DevId.NextObjId = lastobjid+1;
if(objid == maxidofobj) if(objid == maxidofobj)
@@ -213,6 +96,11 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
modbus_msg->DevId.MoreFollows = 0xFF; modbus_msg->DevId.MoreFollows = 0xFF;
} }
} }
else
{
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
}
}
/** /**
@@ -223,9 +111,11 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
*/ */
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
{ {
modbus_msg->DevId.Conformity = MODBUS_DEVICE_CONFORMITY;
switch(modbus_msg->DevId.ReadDevId) switch(modbus_msg->DevId.ReadDevId)
{ {
case MB_BASIC_IDENTIFICATIONS: case RID_BASIC_IDENTIFICATIONS:
if (modbus_msg->DevId.NextObjId == 0) if (modbus_msg->DevId.NextObjId == 0)
{ {
modbus_msg->DevId.NextObjId = 0; modbus_msg->DevId.NextObjId = 0;
@@ -235,7 +125,7 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
modbus_msg->DevId.NumbOfObj = 3; modbus_msg->DevId.NumbOfObj = 3;
break; break;
case MB_REGULAR_IDENTIFICATIONS: case RID_REGULAR_IDENTIFICATIONS:
if (modbus_msg->DevId.NextObjId == 0) if (modbus_msg->DevId.NextObjId == 0)
{ {
modbus_msg->DevId.NextObjId = 3; modbus_msg->DevId.NextObjId = 3;
@@ -245,10 +135,11 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
modbus_msg->DevId.NumbOfObj = 4; modbus_msg->DevId.NumbOfObj = 4;
break; break;
case MB_EXTENDED_IDENTIFICATIONS: case RID_EXTENDED_IDENTIFICATIONS:
if(MODBUS_NUMB_OF_USEROBJECTS <= 0 || MODBUS_NUMB_OF_USEROBJECTS > 128) if(MODBUS_NUMB_OF_USEROBJECTS <= 0 || MODBUS_NUMB_OF_USEROBJECTS > 128)
{ {
return 0; modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
break;
} }
if (modbus_msg->DevId.NextObjId == 0) if (modbus_msg->DevId.NextObjId == 0)
@@ -260,15 +151,23 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
modbus_msg->DevId.NumbOfObj = MODBUS_NUMB_OF_USEROBJECTS; modbus_msg->DevId.NumbOfObj = MODBUS_NUMB_OF_USEROBJECTS;
break; break;
case MB_SPEDIFIC_IDENTIFICATIONS: case RID_SPEDIFIC_IDENTIFICATIONS:
MB_WriteObjectsToMessage(modbus_msg, modbus_msg->DevId.NextObjId); MB_WriteObjectsToMessage(modbus_msg, modbus_msg->DevId.NextObjId);
modbus_msg->DevId.NumbOfObj = 1; modbus_msg->DevId.NumbOfObj = 1;
break; break;
default: default:
return 0; return 0;
} }
if(modbus_msg->Except_Code != ET_NO_ERRORS)
{
return 0;
}
else
{
return 1; return 1;
} }
}
@@ -284,402 +183,391 @@ void MB_DeviceInentificationInit(void)
MB_ObjectInit(&MB_DEVID.ProductName, MODBUS_PRODUCT_NAME); MB_ObjectInit(&MB_DEVID.ProductName, MODBUS_PRODUCT_NAME);
MB_ObjectInit(&MB_DEVID.ModelName, MODBUS_MODEL_NAME); MB_ObjectInit(&MB_DEVID.ModelName, MODBUS_MODEL_NAME);
#ifdef MODBUS_USEROBJECT_0_NAME #if defined(MODBUS_USEROBJECT_0_NAME) && MODBUS_NUMB_OF_USEROBJECTS>0
MB_ObjectInit(&MB_DEVID.User[0], MODBUS_USEROBJECT_0_NAME); MB_ObjectInit(&MB_DEVID.User[0], MODBUS_USEROBJECT_0_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_1_NAME #if defined(MODBUS_USEROBJECT_1_NAME) && MODBUS_NUMB_OF_USEROBJECTS>1
MB_ObjectInit(&MB_DEVID.User[1], MODBUS_USEROBJECT_1_NAME); MB_ObjectInit(&MB_DEVID.User[1], MODBUS_USEROBJECT_1_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_2_NAME #if defined(MODBUS_USEROBJECT_2_NAME) && MODBUS_NUMB_OF_USEROBJECTS>2
MB_ObjectInit(&MB_DEVID.User[2], MODBUS_USEROBJECT_2_NAME); MB_ObjectInit(&MB_DEVID.User[2], MODBUS_USEROBJECT_2_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_3_NAME #if defined(MODBUS_USEROBJECT_3_NAME) && MODBUS_NUMB_OF_USEROBJECTS>3
MB_ObjectInit(&MB_DEVID.User[3], MODBUS_USEROBJECT_3_NAME); MB_ObjectInit(&MB_DEVID.User[3], MODBUS_USEROBJECT_3_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_4_NAME #if defined(MODBUS_USEROBJECT_4_NAME) && MODBUS_NUMB_OF_USEROBJECTS>4
MB_ObjectInit(&MB_DEVID.User[4], MODBUS_USEROBJECT_4_NAME); MB_ObjectInit(&MB_DEVID.User[4], MODBUS_USEROBJECT_4_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_5_NAME #if defined(MODBUS_USEROBJECT_5_NAME) && MODBUS_NUMB_OF_USEROBJECTS>5
MB_ObjectInit(&MB_DEVID.User[5], MODBUS_USEROBJECT_5_NAME); MB_ObjectInit(&MB_DEVID.User[5], MODBUS_USEROBJECT_5_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_6_NAME #if defined(MODBUS_USEROBJECT_6_NAME) && MODBUS_NUMB_OF_USEROBJECTS>6
MB_ObjectInit(&MB_DEVID.User[6], MODBUS_USEROBJECT_6_NAME); MB_ObjectInit(&MB_DEVID.User[6], MODBUS_USEROBJECT_6_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_7_NAME #if defined(MODBUS_USEROBJECT_7_NAME) && MODBUS_NUMB_OF_USEROBJECTS>7
MB_ObjectInit(&MB_DEVID.User[7], MODBUS_USEROBJECT_7_NAME); MB_ObjectInit(&MB_DEVID.User[7], MODBUS_USEROBJECT_7_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_8_NAME #if defined(MODBUS_USEROBJECT_8_NAME) && MODBUS_NUMB_OF_USEROBJECTS>8
MB_ObjectInit(&MB_DEVID.User[8], MODBUS_USEROBJECT_8_NAME); MB_ObjectInit(&MB_DEVID.User[8], MODBUS_USEROBJECT_8_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_9_NAME #if defined(MODBUS_USEROBJECT_9_NAME) && MODBUS_NUMB_OF_USEROBJECTS>9
MB_ObjectInit(&MB_DEVID.User[9], MODBUS_USEROBJECT_9_NAME); MB_ObjectInit(&MB_DEVID.User[9], MODBUS_USEROBJECT_9_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_10_NAME #if defined(MODBUS_USEROBJECT_10_NAME) && MODBUS_NUMB_OF_USEROBJECTS>10
MB_ObjectInit(&MB_DEVID.User[10], MODBUS_USEROBJECT_10_NAME); MB_ObjectInit(&MB_DEVID.User[10], MODBUS_USEROBJECT_10_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_11_NAME #if defined(MODBUS_USEROBJECT_11_NAME) && MODBUS_NUMB_OF_USEROBJECTS>11
MB_ObjectInit(&MB_DEVID.User[11], MODBUS_USEROBJECT_11_NAME); MB_ObjectInit(&MB_DEVID.User[11], MODBUS_USEROBJECT_11_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_12_NAME #if defined(MODBUS_USEROBJECT_12_NAME) && MODBUS_NUMB_OF_USEROBJECTS>12
MB_ObjectInit(&MB_DEVID.User[12], MODBUS_USEROBJECT_12_NAME); MB_ObjectInit(&MB_DEVID.User[12], MODBUS_USEROBJECT_12_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_13_NAME #if defined(MODBUS_USEROBJECT_13_NAME) && MODBUS_NUMB_OF_USEROBJECTS>13
MB_ObjectInit(&MB_DEVID.User[13], MODBUS_USEROBJECT_13_NAME); MB_ObjectInit(&MB_DEVID.User[13], MODBUS_USEROBJECT_13_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_14_NAME #if defined(MODBUS_USEROBJECT_14_NAME) && MODBUS_NUMB_OF_USEROBJECTS>14
MB_ObjectInit(&MB_DEVID.User[14], MODBUS_USEROBJECT_14_NAME); MB_ObjectInit(&MB_DEVID.User[14], MODBUS_USEROBJECT_14_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_15_NAME #if defined(MODBUS_USEROBJECT_15_NAME) && MODBUS_NUMB_OF_USEROBJECTS>15
MB_ObjectInit(&MB_DEVID.User[15], MODBUS_USEROBJECT_15_NAME); MB_ObjectInit(&MB_DEVID.User[15], MODBUS_USEROBJECT_15_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_16_NAME #if defined(MODBUS_USEROBJECT_16_NAME) && MODBUS_NUMB_OF_USEROBJECTS>16
MB_ObjectInit(&MB_DEVID.User[16], MODBUS_USEROBJECT_16_NAME); MB_ObjectInit(&MB_DEVID.User[16], MODBUS_USEROBJECT_16_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_17_NAME #if defined(MODBUS_USEROBJECT_17_NAME) && MODBUS_NUMB_OF_USEROBJECTS>17
MB_ObjectInit(&MB_DEVID.User[17], MODBUS_USEROBJECT_17_NAME); MB_ObjectInit(&MB_DEVID.User[17], MODBUS_USEROBJECT_17_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_18_NAME #if defined(MODBUS_USEROBJECT_18_NAME) && MODBUS_NUMB_OF_USEROBJECTS>18
MB_ObjectInit(&MB_DEVID.User[18], MODBUS_USEROBJECT_18_NAME); MB_ObjectInit(&MB_DEVID.User[18], MODBUS_USEROBJECT_18_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_19_NAME #if defined(MODBUS_USEROBJECT_19_NAME) && MODBUS_NUMB_OF_USEROBJECTS>19
MB_ObjectInit(&MB_DEVID.User[19], MODBUS_USEROBJECT_19_NAME); MB_ObjectInit(&MB_DEVID.User[19], MODBUS_USEROBJECT_19_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_20_NAME #if defined(MODBUS_USEROBJECT_20_NAME) && MODBUS_NUMB_OF_USEROBJECTS>20
MB_ObjectInit(&MB_DEVID.User[20], MODBUS_USEROBJECT_20_NAME); MB_ObjectInit(&MB_DEVID.User[20], MODBUS_USEROBJECT_20_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_21_NAME #if defined(MODBUS_USEROBJECT_21_NAME) && MODBUS_NUMB_OF_USEROBJECTS>21
MB_ObjectInit(&MB_DEVID.User[21], MODBUS_USEROBJECT_21_NAME); MB_ObjectInit(&MB_DEVID.User[21], MODBUS_USEROBJECT_21_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_22_NAME #if defined(MODBUS_USEROBJECT_22_NAME) && MODBUS_NUMB_OF_USEROBJECTS>22
MB_ObjectInit(&MB_DEVID.User[22], MODBUS_USEROBJECT_22_NAME); MB_ObjectInit(&MB_DEVID.User[22], MODBUS_USEROBJECT_22_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_23_NAME #if defined(MODBUS_USEROBJECT_23_NAME) && MODBUS_NUMB_OF_USEROBJECTS>23
MB_ObjectInit(&MB_DEVID.User[23], MODBUS_USEROBJECT_23_NAME); MB_ObjectInit(&MB_DEVID.User[23], MODBUS_USEROBJECT_23_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_24_NAME #if defined(MODBUS_USEROBJECT_24_NAME) && MODBUS_NUMB_OF_USEROBJECTS>24
MB_ObjectInit(&MB_DEVID.User[24], MODBUS_USEROBJECT_24_NAME); MB_ObjectInit(&MB_DEVID.User[24], MODBUS_USEROBJECT_24_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_25_NAME #if defined(MODBUS_USEROBJECT_25_NAME) && MODBUS_NUMB_OF_USEROBJECTS>25
MB_ObjectInit(&MB_DEVID.User[25], MODBUS_USEROBJECT_25_NAME); MB_ObjectInit(&MB_DEVID.User[25], MODBUS_USEROBJECT_25_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_26_NAME #if defined(MODBUS_USEROBJECT_26_NAME) && MODBUS_NUMB_OF_USEROBJECTS>26
MB_ObjectInit(&MB_DEVID.User[26], MODBUS_USEROBJECT_26_NAME); MB_ObjectInit(&MB_DEVID.User[26], MODBUS_USEROBJECT_26_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_27_NAME #if defined(MODBUS_USEROBJECT_27_NAME) && MODBUS_NUMB_OF_USEROBJECTS>27
MB_ObjectInit(&MB_DEVID.User[27], MODBUS_USEROBJECT_27_NAME); MB_ObjectInit(&MB_DEVID.User[27], MODBUS_USEROBJECT_27_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_28_NAME #if defined(MODBUS_USEROBJECT_28_NAME) && MODBUS_NUMB_OF_USEROBJECTS>28
MB_ObjectInit(&MB_DEVID.User[28], MODBUS_USEROBJECT_28_NAME); MB_ObjectInit(&MB_DEVID.User[28], MODBUS_USEROBJECT_28_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_29_NAME #if defined(MODBUS_USEROBJECT_29_NAME) && MODBUS_NUMB_OF_USEROBJECTS>29
MB_ObjectInit(&MB_DEVID.User[29], MODBUS_USEROBJECT_29_NAME); MB_ObjectInit(&MB_DEVID.User[29], MODBUS_USEROBJECT_29_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_30_NAME #if defined(MODBUS_USEROBJECT_30_NAME) && MODBUS_NUMB_OF_USEROBJECTS>30
MB_ObjectInit(&MB_DEVID.User[30], MODBUS_USEROBJECT_30_NAME); MB_ObjectInit(&MB_DEVID.User[30], MODBUS_USEROBJECT_30_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_31_NAME #if defined(MODBUS_USEROBJECT_31_NAME) && MODBUS_NUMB_OF_USEROBJECTS>31
MB_ObjectInit(&MB_DEVID.User[31], MODBUS_USEROBJECT_31_NAME); MB_ObjectInit(&MB_DEVID.User[31], MODBUS_USEROBJECT_31_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_32_NAME #if defined(MODBUS_USEROBJECT_32_NAME) && MODBUS_NUMB_OF_USEROBJECTS>32
MB_ObjectInit(&MB_DEVID.User[32], MODBUS_USEROBJECT_32_NAME); MB_ObjectInit(&MB_DEVID.User[32], MODBUS_USEROBJECT_32_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_33_NAME #if defined(MODBUS_USEROBJECT_33_NAME) && MODBUS_NUMB_OF_USEROBJECTS>33
MB_ObjectInit(&MB_DEVID.User[33], MODBUS_USEROBJECT_33_NAME); MB_ObjectInit(&MB_DEVID.User[33], MODBUS_USEROBJECT_33_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_34_NAME #if defined(MODBUS_USEROBJECT_34_NAME) && MODBUS_NUMB_OF_USEROBJECTS>34
MB_ObjectInit(&MB_DEVID.User[34], MODBUS_USEROBJECT_34_NAME); MB_ObjectInit(&MB_DEVID.User[34], MODBUS_USEROBJECT_34_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_35_NAME #if defined(MODBUS_USEROBJECT_35_NAME) && MODBUS_NUMB_OF_USEROBJECTS>35
MB_ObjectInit(&MB_DEVID.User[35], MODBUS_USEROBJECT_35_NAME); MB_ObjectInit(&MB_DEVID.User[35], MODBUS_USEROBJECT_35_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_36_NAME #if defined(MODBUS_USEROBJECT_36_NAME) && MODBUS_NUMB_OF_USEROBJECTS>36
MB_ObjectInit(&MB_DEVID.User[36], MODBUS_USEROBJECT_36_NAME); MB_ObjectInit(&MB_DEVID.User[36], MODBUS_USEROBJECT_36_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_37_NAME #if defined(MODBUS_USEROBJECT_37_NAME) && MODBUS_NUMB_OF_USEROBJECTS>37
MB_ObjectInit(&MB_DEVID.User[37], MODBUS_USEROBJECT_37_NAME); MB_ObjectInit(&MB_DEVID.User[37], MODBUS_USEROBJECT_37_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_38_NAME #if defined(MODBUS_USEROBJECT_38_NAME) && MODBUS_NUMB_OF_USEROBJECTS>38
MB_ObjectInit(&MB_DEVID.User[38], MODBUS_USEROBJECT_38_NAME); MB_ObjectInit(&MB_DEVID.User[38], MODBUS_USEROBJECT_38_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_39_NAME #if defined(MODBUS_USEROBJECT_39_NAME) && MODBUS_NUMB_OF_USEROBJECTS>39
MB_ObjectInit(&MB_DEVID.User[39], MODBUS_USEROBJECT_39_NAME); MB_ObjectInit(&MB_DEVID.User[39], MODBUS_USEROBJECT_39_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_40_NAME #if defined(MODBUS_USEROBJECT_40_NAME) && MODBUS_NUMB_OF_USEROBJECTS>40
MB_ObjectInit(&MB_DEVID.User[40], MODBUS_USEROBJECT_40_NAME); MB_ObjectInit(&MB_DEVID.User[40], MODBUS_USEROBJECT_40_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_41_NAME #if defined(MODBUS_USEROBJECT_41_NAME) && MODBUS_NUMB_OF_USEROBJECTS>41
MB_ObjectInit(&MB_DEVID.User[41], MODBUS_USEROBJECT_41_NAME); MB_ObjectInit(&MB_DEVID.User[41], MODBUS_USEROBJECT_41_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_42_NAME #if defined(MODBUS_USEROBJECT_42_NAME) && MODBUS_NUMB_OF_USEROBJECTS>42
MB_ObjectInit(&MB_DEVID.User[42], MODBUS_USEROBJECT_42_NAME); MB_ObjectInit(&MB_DEVID.User[42], MODBUS_USEROBJECT_42_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_43_NAME #if defined(MODBUS_USEROBJECT_43_NAME) && MODBUS_NUMB_OF_USEROBJECTS>43
MB_ObjectInit(&MB_DEVID.User[43], MODBUS_USEROBJECT_43_NAME); MB_ObjectInit(&MB_DEVID.User[43], MODBUS_USEROBJECT_43_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_44_NAME #if defined(MODBUS_USEROBJECT_44_NAME) && MODBUS_NUMB_OF_USEROBJECTS>44
MB_ObjectInit(&MB_DEVID.User[44], MODBUS_USEROBJECT_44_NAME); MB_ObjectInit(&MB_DEVID.User[44], MODBUS_USEROBJECT_44_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_45_NAME #if defined(MODBUS_USEROBJECT_45_NAME) && MODBUS_NUMB_OF_USEROBJECTS>45
MB_ObjectInit(&MB_DEVID.User[45], MODBUS_USEROBJECT_45_NAME); MB_ObjectInit(&MB_DEVID.User[45], MODBUS_USEROBJECT_45_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_46_NAME #if defined(MODBUS_USEROBJECT_46_NAME) && MODBUS_NUMB_OF_USEROBJECTS>46
MB_ObjectInit(&MB_DEVID.User[46], MODBUS_USEROBJECT_46_NAME); MB_ObjectInit(&MB_DEVID.User[46], MODBUS_USEROBJECT_46_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_47_NAME #if defined(MODBUS_USEROBJECT_47_NAME) && MODBUS_NUMB_OF_USEROBJECTS>47
MB_ObjectInit(&MB_DEVID.User[47], MODBUS_USEROBJECT_47_NAME); MB_ObjectInit(&MB_DEVID.User[47], MODBUS_USEROBJECT_47_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_48_NAME #if defined(MODBUS_USEROBJECT_48_NAME) && MODBUS_NUMB_OF_USEROBJECTS>48
MB_ObjectInit(&MB_DEVID.User[48], MODBUS_USEROBJECT_48_NAME); MB_ObjectInit(&MB_DEVID.User[48], MODBUS_USEROBJECT_48_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_49_NAME #if defined(MODBUS_USEROBJECT_49_NAME) && MODBUS_NUMB_OF_USEROBJECTS>49
MB_ObjectInit(&MB_DEVID.User[49], MODBUS_USEROBJECT_49_NAME); MB_ObjectInit(&MB_DEVID.User[49], MODBUS_USEROBJECT_49_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_50_NAME #if defined(MODBUS_USEROBJECT_50_NAME) && MODBUS_NUMB_OF_USEROBJECTS>50
MB_ObjectInit(&MB_DEVID.User[50], MODBUS_USEROBJECT_50_NAME); MB_ObjectInit(&MB_DEVID.User[50], MODBUS_USEROBJECT_50_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_51_NAME #if defined(MODBUS_USEROBJECT_51_NAME) && MODBUS_NUMB_OF_USEROBJECTS>51
MB_ObjectInit(&MB_DEVID.User[51], MODBUS_USEROBJECT_51_NAME); MB_ObjectInit(&MB_DEVID.User[51], MODBUS_USEROBJECT_51_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_52_NAME #if defined(MODBUS_USEROBJECT_52_NAME) && MODBUS_NUMB_OF_USEROBJECTS>52
MB_ObjectInit(&MB_DEVID.User[52], MODBUS_USEROBJECT_52_NAME); MB_ObjectInit(&MB_DEVID.User[52], MODBUS_USEROBJECT_52_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_53_NAME #if defined(MODBUS_USEROBJECT_53_NAME) && MODBUS_NUMB_OF_USEROBJECTS>53
MB_ObjectInit(&MB_DEVID.User[53], MODBUS_USEROBJECT_53_NAME); MB_ObjectInit(&MB_DEVID.User[53], MODBUS_USEROBJECT_53_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_54_NAME #if defined(MODBUS_USEROBJECT_54_NAME) && MODBUS_NUMB_OF_USEROBJECTS>54
MB_ObjectInit(&MB_DEVID.User[54], MODBUS_USEROBJECT_54_NAME); MB_ObjectInit(&MB_DEVID.User[54], MODBUS_USEROBJECT_54_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_55_NAME #if defined(MODBUS_USEROBJECT_55_NAME) && MODBUS_NUMB_OF_USEROBJECTS>55
MB_ObjectInit(&MB_DEVID.User[55], MODBUS_USEROBJECT_55_NAME); MB_ObjectInit(&MB_DEVID.User[55], MODBUS_USEROBJECT_55_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_56_NAME #if defined(MODBUS_USEROBJECT_56_NAME) && MODBUS_NUMB_OF_USEROBJECTS>56
MB_ObjectInit(&MB_DEVID.User[56], MODBUS_USEROBJECT_56_NAME); MB_ObjectInit(&MB_DEVID.User[56], MODBUS_USEROBJECT_56_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_57_NAME #if defined(MODBUS_USEROBJECT_57_NAME) && MODBUS_NUMB_OF_USEROBJECTS>57
MB_ObjectInit(&MB_DEVID.User[57], MODBUS_USEROBJECT_57_NAME); MB_ObjectInit(&MB_DEVID.User[57], MODBUS_USEROBJECT_57_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_58_NAME #if defined(MODBUS_USEROBJECT_58_NAME) && MODBUS_NUMB_OF_USEROBJECTS>58
MB_ObjectInit(&MB_DEVID.User[58], MODBUS_USEROBJECT_58_NAME); MB_ObjectInit(&MB_DEVID.User[58], MODBUS_USEROBJECT_58_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_59_NAME #if defined(MODBUS_USEROBJECT_59_NAME) && MODBUS_NUMB_OF_USEROBJECTS>59
MB_ObjectInit(&MB_DEVID.User[59], MODBUS_USEROBJECT_59_NAME); MB_ObjectInit(&MB_DEVID.User[59], MODBUS_USEROBJECT_59_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_60_NAME #if defined(MODBUS_USEROBJECT_60_NAME) && MODBUS_NUMB_OF_USEROBJECTS>60
MB_ObjectInit(&MB_DEVID.User[60], MODBUS_USEROBJECT_60_NAME); MB_ObjectInit(&MB_DEVID.User[60], MODBUS_USEROBJECT_60_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_61_NAME #if defined(MODBUS_USEROBJECT_61_NAME) && MODBUS_NUMB_OF_USEROBJECTS>61
MB_ObjectInit(&MB_DEVID.User[61], MODBUS_USEROBJECT_61_NAME); MB_ObjectInit(&MB_DEVID.User[61], MODBUS_USEROBJECT_61_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_62_NAME #if defined(MODBUS_USEROBJECT_62_NAME) && MODBUS_NUMB_OF_USEROBJECTS>62
MB_ObjectInit(&MB_DEVID.User[62], MODBUS_USEROBJECT_62_NAME); MB_ObjectInit(&MB_DEVID.User[62], MODBUS_USEROBJECT_62_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_63_NAME #if defined(MODBUS_USEROBJECT_63_NAME) && MODBUS_NUMB_OF_USEROBJECTS>63
MB_ObjectInit(&MB_DEVID.User[63], MODBUS_USEROBJECT_63_NAME); MB_ObjectInit(&MB_DEVID.User[63], MODBUS_USEROBJECT_63_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_64_NAME #if defined(MODBUS_USEROBJECT_64_NAME) && MODBUS_NUMB_OF_USEROBJECTS>64
MB_ObjectInit(&MB_DEVID.User[64], MODBUS_USEROBJECT_64_NAME); MB_ObjectInit(&MB_DEVID.User[64], MODBUS_USEROBJECT_64_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_65_NAME #if defined(MODBUS_USEROBJECT_65_NAME) && MODBUS_NUMB_OF_USEROBJECTS>65
MB_ObjectInit(&MB_DEVID.User[65], MODBUS_USEROBJECT_65_NAME); MB_ObjectInit(&MB_DEVID.User[65], MODBUS_USEROBJECT_65_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_66_NAME #if defined(MODBUS_USEROBJECT_66_NAME) && MODBUS_NUMB_OF_USEROBJECTS>66
MB_ObjectInit(&MB_DEVID.User[66], MODBUS_USEROBJECT_66_NAME); MB_ObjectInit(&MB_DEVID.User[66], MODBUS_USEROBJECT_66_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_67_NAME #if defined(MODBUS_USEROBJECT_67_NAME) && MODBUS_NUMB_OF_USEROBJECTS>67
MB_ObjectInit(&MB_DEVID.User[67], MODBUS_USEROBJECT_67_NAME); MB_ObjectInit(&MB_DEVID.User[67], MODBUS_USEROBJECT_67_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_68_NAME #if defined(MODBUS_USEROBJECT_68_NAME) && MODBUS_NUMB_OF_USEROBJECTS>68
MB_ObjectInit(&MB_DEVID.User[68], MODBUS_USEROBJECT_68_NAME); MB_ObjectInit(&MB_DEVID.User[68], MODBUS_USEROBJECT_68_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_69_NAME #if defined(MODBUS_USEROBJECT_69_NAME) && MODBUS_NUMB_OF_USEROBJECTS>69
MB_ObjectInit(&MB_DEVID.User[69], MODBUS_USEROBJECT_69_NAME); MB_ObjectInit(&MB_DEVID.User[69], MODBUS_USEROBJECT_69_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_70_NAME #if defined(MODBUS_USEROBJECT_70_NAME) && MODBUS_NUMB_OF_USEROBJECTS>70
MB_ObjectInit(&MB_DEVID.User[70], MODBUS_USEROBJECT_70_NAME); MB_ObjectInit(&MB_DEVID.User[70], MODBUS_USEROBJECT_70_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_71_NAME #if defined(MODBUS_USEROBJECT_71_NAME) && MODBUS_NUMB_OF_USEROBJECTS>71
MB_ObjectInit(&MB_DEVID.User[71], MODBUS_USEROBJECT_71_NAME); MB_ObjectInit(&MB_DEVID.User[71], MODBUS_USEROBJECT_71_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_72_NAME #if defined(MODBUS_USEROBJECT_72_NAME) && MODBUS_NUMB_OF_USEROBJECTS>72
MB_ObjectInit(&MB_DEVID.User[72], MODBUS_USEROBJECT_72_NAME); MB_ObjectInit(&MB_DEVID.User[72], MODBUS_USEROBJECT_72_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_73_NAME #if defined(MODBUS_USEROBJECT_73_NAME) && MODBUS_NUMB_OF_USEROBJECTS>73
MB_ObjectInit(&MB_DEVID.User[73], MODBUS_USEROBJECT_73_NAME); MB_ObjectInit(&MB_DEVID.User[73], MODBUS_USEROBJECT_73_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_74_NAME #if defined(MODBUS_USEROBJECT_74_NAME) && MODBUS_NUMB_OF_USEROBJECTS>74
MB_ObjectInit(&MB_DEVID.User[74], MODBUS_USEROBJECT_74_NAME); MB_ObjectInit(&MB_DEVID.User[74], MODBUS_USEROBJECT_74_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_75_NAME #if defined(MODBUS_USEROBJECT_75_NAME) && MODBUS_NUMB_OF_USEROBJECTS>75
MB_ObjectInit(&MB_DEVID.User[75], MODBUS_USEROBJECT_75_NAME); MB_ObjectInit(&MB_DEVID.User[75], MODBUS_USEROBJECT_75_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_76_NAME #if defined(MODBUS_USEROBJECT_76_NAME) && MODBUS_NUMB_OF_USEROBJECTS>76
MB_ObjectInit(&MB_DEVID.User[76], MODBUS_USEROBJECT_76_NAME); MB_ObjectInit(&MB_DEVID.User[76], MODBUS_USEROBJECT_76_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_77_NAME #if defined(MODBUS_USEROBJECT_77_NAME) && MODBUS_NUMB_OF_USEROBJECTS>77
MB_ObjectInit(&MB_DEVID.User[77], MODBUS_USEROBJECT_77_NAME); MB_ObjectInit(&MB_DEVID.User[77], MODBUS_USEROBJECT_77_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_78_NAME #if defined(MODBUS_USEROBJECT_78_NAME) && MODBUS_NUMB_OF_USEROBJECTS>78
MB_ObjectInit(&MB_DEVID.User[78], MODBUS_USEROBJECT_78_NAME); MB_ObjectInit(&MB_DEVID.User[78], MODBUS_USEROBJECT_78_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_79_NAME #if defined(MODBUS_USEROBJECT_79_NAME) && MODBUS_NUMB_OF_USEROBJECTS>79
MB_ObjectInit(&MB_DEVID.User[79], MODBUS_USEROBJECT_79_NAME); MB_ObjectInit(&MB_DEVID.User[79], MODBUS_USEROBJECT_79_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_80_NAME #if defined(MODBUS_USEROBJECT_80_NAME) && MODBUS_NUMB_OF_USEROBJECTS>80
MB_ObjectInit(&MB_DEVID.User[80], MODBUS_USEROBJECT_80_NAME); MB_ObjectInit(&MB_DEVID.User[80], MODBUS_USEROBJECT_80_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_81_NAME #if defined(MODBUS_USEROBJECT_81_NAME) && MODBUS_NUMB_OF_USEROBJECTS>81
MB_ObjectInit(&MB_DEVID.User[81], MODBUS_USEROBJECT_81_NAME); MB_ObjectInit(&MB_DEVID.User[81], MODBUS_USEROBJECT_81_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_82_NAME #if defined(MODBUS_USEROBJECT_82_NAME) && MODBUS_NUMB_OF_USEROBJECTS>82
MB_ObjectInit(&MB_DEVID.User[82], MODBUS_USEROBJECT_82_NAME); MB_ObjectInit(&MB_DEVID.User[82], MODBUS_USEROBJECT_82_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_83_NAME #if defined(MODBUS_USEROBJECT_83_NAME) && MODBUS_NUMB_OF_USEROBJECTS>83
MB_ObjectInit(&MB_DEVID.User[83], MODBUS_USEROBJECT_83_NAME); MB_ObjectInit(&MB_DEVID.User[83], MODBUS_USEROBJECT_83_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_84_NAME #if defined(MODBUS_USEROBJECT_84_NAME) && MODBUS_NUMB_OF_USEROBJECTS>84
MB_ObjectInit(&MB_DEVID.User[84], MODBUS_USEROBJECT_84_NAME); MB_ObjectInit(&MB_DEVID.User[84], MODBUS_USEROBJECT_84_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_85_NAME #if defined(MODBUS_USEROBJECT_85_NAME) && MODBUS_NUMB_OF_USEROBJECTS>85
MB_ObjectInit(&MB_DEVID.User[85], MODBUS_USEROBJECT_85_NAME); MB_ObjectInit(&MB_DEVID.User[85], MODBUS_USEROBJECT_85_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_86_NAME #if defined(MODBUS_USEROBJECT_86_NAME) && MODBUS_NUMB_OF_USEROBJECTS>86
MB_ObjectInit(&MB_DEVID.User[86], MODBUS_USEROBJECT_86_NAME); MB_ObjectInit(&MB_DEVID.User[86], MODBUS_USEROBJECT_86_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_87_NAME #if defined(MODBUS_USEROBJECT_87_NAME) && MODBUS_NUMB_OF_USEROBJECTS>87
MB_ObjectInit(&MB_DEVID.User[87], MODBUS_USEROBJECT_87_NAME); MB_ObjectInit(&MB_DEVID.User[87], MODBUS_USEROBJECT_87_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_88_NAME #if defined(MODBUS_USEROBJECT_88_NAME) && MODBUS_NUMB_OF_USEROBJECTS>88
MB_ObjectInit(&MB_DEVID.User[88], MODBUS_USEROBJECT_88_NAME); MB_ObjectInit(&MB_DEVID.User[88], MODBUS_USEROBJECT_88_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_89_NAME #if defined(MODBUS_USEROBJECT_89_NAME) && MODBUS_NUMB_OF_USEROBJECTS>89
MB_ObjectInit(&MB_DEVID.User[89], MODBUS_USEROBJECT_89_NAME); MB_ObjectInit(&MB_DEVID.User[89], MODBUS_USEROBJECT_89_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_90_NAME #if defined(MODBUS_USEROBJECT_90_NAME) && MODBUS_NUMB_OF_USEROBJECTS>90
MB_ObjectInit(&MB_DEVID.User[90], MODBUS_USEROBJECT_90_NAME); MB_ObjectInit(&MB_DEVID.User[90], MODBUS_USEROBJECT_90_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_91_NAME #if defined(MODBUS_USEROBJECT_91_NAME) && MODBUS_NUMB_OF_USEROBJECTS>91
MB_ObjectInit(&MB_DEVID.User[91], MODBUS_USEROBJECT_91_NAME); MB_ObjectInit(&MB_DEVID.User[91], MODBUS_USEROBJECT_91_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_92_NAME #if defined(MODBUS_USEROBJECT_92_NAME) && MODBUS_NUMB_OF_USEROBJECTS>92
MB_ObjectInit(&MB_DEVID.User[92], MODBUS_USEROBJECT_92_NAME); MB_ObjectInit(&MB_DEVID.User[92], MODBUS_USEROBJECT_92_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_93_NAME #if defined(MODBUS_USEROBJECT_93_NAME) && MODBUS_NUMB_OF_USEROBJECTS>93
MB_ObjectInit(&MB_DEVID.User[93], MODBUS_USEROBJECT_93_NAME); MB_ObjectInit(&MB_DEVID.User[93], MODBUS_USEROBJECT_93_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_94_NAME #if defined(MODBUS_USEROBJECT_94_NAME) && MODBUS_NUMB_OF_USEROBJECTS>94
MB_ObjectInit(&MB_DEVID.User[94], MODBUS_USEROBJECT_94_NAME); MB_ObjectInit(&MB_DEVID.User[94], MODBUS_USEROBJECT_94_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_95_NAME #if defined(MODBUS_USEROBJECT_95_NAME) && MODBUS_NUMB_OF_USEROBJECTS>95
MB_ObjectInit(&MB_DEVID.User[95], MODBUS_USEROBJECT_95_NAME); MB_ObjectInit(&MB_DEVID.User[95], MODBUS_USEROBJECT_95_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_96_NAME #if defined(MODBUS_USEROBJECT_96_NAME) && MODBUS_NUMB_OF_USEROBJECTS>96
MB_ObjectInit(&MB_DEVID.User[96], MODBUS_USEROBJECT_96_NAME); MB_ObjectInit(&MB_DEVID.User[96], MODBUS_USEROBJECT_96_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_97_NAME #if defined(MODBUS_USEROBJECT_97_NAME) && MODBUS_NUMB_OF_USEROBJECTS>97
MB_ObjectInit(&MB_DEVID.User[97], MODBUS_USEROBJECT_97_NAME); MB_ObjectInit(&MB_DEVID.User[97], MODBUS_USEROBJECT_97_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_98_NAME #if defined(MODBUS_USEROBJECT_98_NAME) && MODBUS_NUMB_OF_USEROBJECTS>98
MB_ObjectInit(&MB_DEVID.User[98], MODBUS_USEROBJECT_98_NAME); MB_ObjectInit(&MB_DEVID.User[98], MODBUS_USEROBJECT_98_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_99_NAME #if defined(MODBUS_USEROBJECT_99_NAME) && MODBUS_NUMB_OF_USEROBJECTS>99
MB_ObjectInit(&MB_DEVID.User[99], MODBUS_USEROBJECT_99_NAME); MB_ObjectInit(&MB_DEVID.User[99], MODBUS_USEROBJECT_99_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_100_NAME #if defined(MODBUS_USEROBJECT_100_NAME) && MODBUS_NUMB_OF_USEROBJECTS>100
MB_ObjectInit(&MB_DEVID.User[100], MODBUS_USEROBJECT_100_NAME); MB_ObjectInit(&MB_DEVID.User[100], MODBUS_USEROBJECT_100_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_101_NAME #if defined(MODBUS_USEROBJECT_101_NAME) && MODBUS_NUMB_OF_USEROBJECTS>101
MB_ObjectInit(&MB_DEVID.User[101], MODBUS_USEROBJECT_101_NAME); MB_ObjectInit(&MB_DEVID.User[101], MODBUS_USEROBJECT_101_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_102_NAME #if defined(MODBUS_USEROBJECT_102_NAME) && MODBUS_NUMB_OF_USEROBJECTS>102
MB_ObjectInit(&MB_DEVID.User[102], MODBUS_USEROBJECT_102_NAME); MB_ObjectInit(&MB_DEVID.User[102], MODBUS_USEROBJECT_102_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_103_NAME #if defined(MODBUS_USEROBJECT_103_NAME) && MODBUS_NUMB_OF_USEROBJECTS>103
MB_ObjectInit(&MB_DEVID.User[103], MODBUS_USEROBJECT_103_NAME); MB_ObjectInit(&MB_DEVID.User[103], MODBUS_USEROBJECT_103_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_104_NAME #if defined(MODBUS_USEROBJECT_104_NAME) && MODBUS_NUMB_OF_USEROBJECTS>104
MB_ObjectInit(&MB_DEVID.User[104], MODBUS_USEROBJECT_104_NAME); MB_ObjectInit(&MB_DEVID.User[104], MODBUS_USEROBJECT_104_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_105_NAME #if defined(MODBUS_USEROBJECT_105_NAME) && MODBUS_NUMB_OF_USEROBJECTS>105
MB_ObjectInit(&MB_DEVID.User[105], MODBUS_USEROBJECT_105_NAME); MB_ObjectInit(&MB_DEVID.User[105], MODBUS_USEROBJECT_105_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_106_NAME #if defined(MODBUS_USEROBJECT_106_NAME) && MODBUS_NUMB_OF_USEROBJECTS>106
MB_ObjectInit(&MB_DEVID.User[106], MODBUS_USEROBJECT_106_NAME); MB_ObjectInit(&MB_DEVID.User[106], MODBUS_USEROBJECT_106_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_107_NAME #if defined(MODBUS_USEROBJECT_107_NAME) && MODBUS_NUMB_OF_USEROBJECTS>107
MB_ObjectInit(&MB_DEVID.User[107], MODBUS_USEROBJECT_107_NAME); MB_ObjectInit(&MB_DEVID.User[107], MODBUS_USEROBJECT_107_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_108_NAME #if defined(MODBUS_USEROBJECT_108_NAME) && MODBUS_NUMB_OF_USEROBJECTS>108
MB_ObjectInit(&MB_DEVID.User[108], MODBUS_USEROBJECT_108_NAME); MB_ObjectInit(&MB_DEVID.User[108], MODBUS_USEROBJECT_108_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_109_NAME #if defined(MODBUS_USEROBJECT_109_NAME) && MODBUS_NUMB_OF_USEROBJECTS>109
MB_ObjectInit(&MB_DEVID.User[109], MODBUS_USEROBJECT_109_NAME); MB_ObjectInit(&MB_DEVID.User[109], MODBUS_USEROBJECT_109_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_110_NAME #if defined(MODBUS_USEROBJECT_110_NAME) && MODBUS_NUMB_OF_USEROBJECTS>110
MB_ObjectInit(&MB_DEVID.User[110], MODBUS_USEROBJECT_110_NAME); MB_ObjectInit(&MB_DEVID.User[110], MODBUS_USEROBJECT_110_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_111_NAME #if defined(MODBUS_USEROBJECT_111_NAME) && MODBUS_NUMB_OF_USEROBJECTS>111
MB_ObjectInit(&MB_DEVID.User[111], MODBUS_USEROBJECT_111_NAME); MB_ObjectInit(&MB_DEVID.User[111], MODBUS_USEROBJECT_111_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_112_NAME #if defined(MODBUS_USEROBJECT_112_NAME) && MODBUS_NUMB_OF_USEROBJECTS>112
MB_ObjectInit(&MB_DEVID.User[112], MODBUS_USEROBJECT_112_NAME); MB_ObjectInit(&MB_DEVID.User[112], MODBUS_USEROBJECT_112_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_113_NAME #if defined(MODBUS_USEROBJECT_113_NAME) && MODBUS_NUMB_OF_USEROBJECTS>113
MB_ObjectInit(&MB_DEVID.User[113], MODBUS_USEROBJECT_113_NAME); MB_ObjectInit(&MB_DEVID.User[113], MODBUS_USEROBJECT_113_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_114_NAME #if defined(MODBUS_USEROBJECT_114_NAME) && MODBUS_NUMB_OF_USEROBJECTS>114
MB_ObjectInit(&MB_DEVID.User[114], MODBUS_USEROBJECT_114_NAME); MB_ObjectInit(&MB_DEVID.User[114], MODBUS_USEROBJECT_114_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_115_NAME #if defined(MODBUS_USEROBJECT_115_NAME) && MODBUS_NUMB_OF_USEROBJECTS>115
MB_ObjectInit(&MB_DEVID.User[115], MODBUS_USEROBJECT_115_NAME); MB_ObjectInit(&MB_DEVID.User[115], MODBUS_USEROBJECT_115_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_116_NAME #if defined(MODBUS_USEROBJECT_116_NAME) && MODBUS_NUMB_OF_USEROBJECTS>116
MB_ObjectInit(&MB_DEVID.User[116], MODBUS_USEROBJECT_116_NAME); MB_ObjectInit(&MB_DEVID.User[116], MODBUS_USEROBJECT_116_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_117_NAME #if defined(MODBUS_USEROBJECT_117_NAME) && MODBUS_NUMB_OF_USEROBJECTS>117
MB_ObjectInit(&MB_DEVID.User[117], MODBUS_USEROBJECT_117_NAME); MB_ObjectInit(&MB_DEVID.User[117], MODBUS_USEROBJECT_117_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_118_NAME #if defined(MODBUS_USEROBJECT_118_NAME) && MODBUS_NUMB_OF_USEROBJECTS>118
MB_ObjectInit(&MB_DEVID.User[118], MODBUS_USEROBJECT_118_NAME); MB_ObjectInit(&MB_DEVID.User[118], MODBUS_USEROBJECT_118_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_119_NAME #if defined(MODBUS_USEROBJECT_119_NAME) && MODBUS_NUMB_OF_USEROBJECTS>119
MB_ObjectInit(&MB_DEVID.User[119], MODBUS_USEROBJECT_119_NAME); MB_ObjectInit(&MB_DEVID.User[119], MODBUS_USEROBJECT_119_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_120_NAME #if defined(MODBUS_USEROBJECT_120_NAME) && MODBUS_NUMB_OF_USEROBJECTS>120
MB_ObjectInit(&MB_DEVID.User[120], MODBUS_USEROBJECT_120_NAME); MB_ObjectInit(&MB_DEVID.User[120], MODBUS_USEROBJECT_120_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_121_NAME #if defined(MODBUS_USEROBJECT_121_NAME) && MODBUS_NUMB_OF_USEROBJECTS>121
MB_ObjectInit(&MB_DEVID.User[121], MODBUS_USEROBJECT_121_NAME); MB_ObjectInit(&MB_DEVID.User[121], MODBUS_USEROBJECT_121_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_122_NAME #if defined(MODBUS_USEROBJECT_122_NAME) && MODBUS_NUMB_OF_USEROBJECTS>122
MB_ObjectInit(&MB_DEVID.User[122], MODBUS_USEROBJECT_122_NAME); MB_ObjectInit(&MB_DEVID.User[122], MODBUS_USEROBJECT_122_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_123_NAME #if defined(MODBUS_USEROBJECT_123_NAME) && MODBUS_NUMB_OF_USEROBJECTS>123
MB_ObjectInit(&MB_DEVID.User[123], MODBUS_USEROBJECT_123_NAME); MB_ObjectInit(&MB_DEVID.User[123], MODBUS_USEROBJECT_123_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_124_NAME #if defined(MODBUS_USEROBJECT_124_NAME) && MODBUS_NUMB_OF_USEROBJECTS>124
MB_ObjectInit(&MB_DEVID.User[124], MODBUS_USEROBJECT_124_NAME); MB_ObjectInit(&MB_DEVID.User[124], MODBUS_USEROBJECT_124_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_125_NAME #if defined(MODBUS_USEROBJECT_125_NAME) && MODBUS_NUMB_OF_USEROBJECTS>125
MB_ObjectInit(&MB_DEVID.User[125], MODBUS_USEROBJECT_125_NAME); MB_ObjectInit(&MB_DEVID.User[125], MODBUS_USEROBJECT_125_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_126_NAME #if defined(MODBUS_USEROBJECT_126_NAME) && MODBUS_NUMB_OF_USEROBJECTS>126
MB_ObjectInit(&MB_DEVID.User[126], MODBUS_USEROBJECT_126_NAME); MB_ObjectInit(&MB_DEVID.User[126], MODBUS_USEROBJECT_126_NAME);
#endif #endif
#ifdef MODBUS_USEROBJECT_127_NAME #if defined(MODBUS_USEROBJECT_127_NAME) && MODBUS_NUMB_OF_USEROBJECTS>127
MB_ObjectInit(&MB_DEVID.User[127], MODBUS_USEROBJECT_127_NAME); MB_ObjectInit(&MB_DEVID.User[127], MODBUS_USEROBJECT_127_NAME);
#endif #endif
} }
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#else //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
/* Получить количество объектов в сообщении */
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
void MB_WriteSingleObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj) {}
void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj) {}
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) {return 0;}
void MB_DeviceInentificationInit(void) {}
#endif

View File

@@ -36,29 +36,6 @@ void MB_DiagnosticsInit(void)
} }
/**
* @brief Получить данные диагностики из сообщения (DATA[1])
* @param modbus_msg Указатель на структуру сообщения
* @param data Указатель куда положить данные
* @return 1 - успех, 0 - ошибка
*/
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
{
if(modbus_msg == NULL || data == NULL)
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
{
return 0;
}
*data = modbus_msg->DATA[1];
return 1;
}
/** /**
* @brief Выставить бит в регистре диагностике * @brief Выставить бит в регистре диагностике
* @param bit_num Номер бита для выставления (1-15, 0 бит нельзя выставить) * @param bit_num Номер бита для выставления (1-15, 0 бит нельзя выставить)
@@ -97,8 +74,8 @@ int MB_Diagnostics_GetBit(int bit_num)
*/ */
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
{ {
uint16_t sub_function = modbus_msg->DATA[0]; uint16_t sub_function = modbus_msg->MbData[0];
uint16_t request_data = modbus_msg->DATA[1]; uint16_t request_data = modbus_msg->MbData[1];
// Если устройство в режиме Listen Only, отвечаем только на sub-function 0x01 // Если устройство в режиме Listen Only, отвечаем только на sub-function 0x01
if (MB_DIAG.DeviceMode == MODBUS_LISTEN_ONLY_MODE && sub_function != 0x0001) if (MB_DIAG.DeviceMode == MODBUS_LISTEN_ONLY_MODE && sub_function != 0x0001)
@@ -110,8 +87,8 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
{ {
case 0x0000: // Return Query Data case 0x0000: // Return Query Data
// Эхо-ответ с теми же данными // Эхо-ответ с теми же данными
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = request_data; modbus_msg->MbData[1] = request_data;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
@@ -137,21 +114,21 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
MB_DIAG.Counters.BusCharacterOverrun = 0; MB_DIAG.Counters.BusCharacterOverrun = 0;
} }
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = request_data; modbus_msg->MbData[1] = request_data;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x0002: // Return Diagnostic Register case 0x0002: // Return Diagnostic Register
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.DiagnosticRegister; modbus_msg->MbData[1] = MB_DIAG.DiagnosticRegister;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x0003: // Change ASCII Input Delimiter case 0x0003: // Change ASCII Input Delimiter
// В RTU режиме не поддерживается // В RTU режиме не поддерживается
modbus_msg->Func_Code |= ERR_VALUES_START; modbus_msg->FuncCode |= FC_ERR_VALUES_START;
modbus_msg->Except_Code = ILLEGAL_FUNCTION; modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
return 0; return 0;
case 0x0004: // Force Listen Only Mode case 0x0004: // Force Listen Only Mode
@@ -161,56 +138,56 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
case 0x000A: // Clear Counters and Diagnostic Register case 0x000A: // Clear Counters and Diagnostic Register
MB_DiagnosticsInit(); // Полный сброс MB_DiagnosticsInit(); // Полный сброс
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = 0; modbus_msg->MbData[1] = 0;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x000B: // Return Bus Message Count case 0x000B: // Return Bus Message Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.BusMessage; modbus_msg->MbData[1] = MB_DIAG.Counters.BusMessage;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x000C: // Return Bus Communication Error Count case 0x000C: // Return Bus Communication Error Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCommunicationErr; modbus_msg->MbData[1] = MB_DIAG.Counters.BusCommunicationErr;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x000D: // Return Bus Exception Error Count case 0x000D: // Return Bus Exception Error Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.BusExceptionErr; modbus_msg->MbData[1] = MB_DIAG.Counters.BusExceptionErr;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x000E: // Return Server Message Count case 0x000E: // Return Server Message Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveMessage; modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveMessage;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x000F: // Return Slave No Response Count case 0x000F: // Return Slave No Response Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNoResponse; modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNoResponse;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x0010: // Return Slave NAK Count case 0x0010: // Return Slave NAK Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNAK; modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNAK;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x0011: // Return Slave Busy Count case 0x0011: // Return Slave Busy Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveBusy; modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveBusy;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
case 0x0012: // Return Bus Character Overrun Count case 0x0012: // Return Bus Character Overrun Count
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCharacterOverrun; modbus_msg->MbData[1] = MB_DIAG.Counters.BusCharacterOverrun;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
@@ -218,14 +195,14 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
MB_DIAG.Counters.BusCharacterOverrun = 0; MB_DIAG.Counters.BusCharacterOverrun = 0;
// Сбрасываем флаг переполнения в DiagnosticRegister // Сбрасываем флаг переполнения в DiagnosticRegister
MB_DIAG.DiagnosticRegister &= ~(1<<0); MB_DIAG.DiagnosticRegister &= ~(1<<0);
modbus_msg->DATA[0] = sub_function; modbus_msg->MbData[0] = sub_function;
modbus_msg->DATA[1] = 0; modbus_msg->MbData[1] = 0;
modbus_msg->ByteCnt = 4; modbus_msg->ByteCnt = 4;
break; break;
default: default:
modbus_msg->Func_Code |= ERR_VALUES_START; modbus_msg->FuncCode |= FC_ERR_VALUES_START;
modbus_msg->Except_Code = ILLEGAL_FUNCTION; modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
return 0; return 0;
} }
@@ -316,21 +293,4 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
return MB_DIAG.DeviceMode; return MB_DIAG.DeviceMode;
} }
#else //MODBUS_ENABLE_DIAGNOSTICS #endif //MODBUS_ENABLE_DIAGNOSTICS
void MB_DiagnosticsInit(void) {}
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;}
int MB_Diagnostics_WriteBit(int bit_num, int bit_state) {return 0;}
int MB_Diagnostics_GetBit(int bit_num) {return 0;}
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) {return 0;}
void MB_Diagnostics_BusMessageCnt(void) {}
void MB_Diagnostics_CommunicationErrorCnt(void) {}
void MB_Diagnostics_ExceptionErrorCnt(void) {}
void MB_Diagnostics_CharacterOverrunCnt(void) {}
void MB_Diagnostics_SlaveMessageCnt(void) {}
void MB_Diagnostics_SlaveNoResponseCnt(void) {}
void MB_Diagnostics_SlaveNAKCnt(void) {}
void MB_Diagnostics_SlaveBusyCnt(void) {}
MB_DeviceModeTypeDef MB_GetDeviceMode(void) {return MODBUS_NORMAL_MODE;}
#endif

View File

@@ -24,6 +24,66 @@
#ifdef MODBUS_ENABLE_HOLDINGS #ifdef MODBUS_ENABLE_HOLDINGS
/**
* @brief Записать регистр хранения по глобальному адресу.
* @param Addr Адрес регистра.
* @param WriteVal Число для записи.
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
uint16_t *pHoldRegs;
//------------WRITE COIL-------------
Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
if(Exception == ET_NO_ERRORS)
{
*(pHoldRegs) = WriteVal;
}
return Exception;
}
/**
* @brief Считать регистр хранения по глобальному адресу.
* @param Addr Адрес регистра.
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
* @return uint16_t Возвращает значение регистра.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp = 0;
uint16_t *pHoldRegs;
//------------READ COIL--------------
Exception_tmp = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
if(Exception) // if exception is not given to func fill it
*Exception = Exception_tmp;
if(Exception_tmp == ET_NO_ERRORS)
{
return *(pHoldRegs);
}
else
{
return 0;
}
}
/** /**
* @brief Обработать функцию Read Holding Registers (03 - 0x03). * @brief Обработать функцию Read Holding Registers (03 - 0x03).
* @param modbus_msg Указатель на структуру собщения modbus. * @param modbus_msg Указатель на структуру собщения modbus.
@@ -36,7 +96,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
// get origin address for data // get origin address for data
uint16_t *pHoldRegs; uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров 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; return 0;
@@ -47,7 +107,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
int i; int i;
for (i = 0; i<modbus_msg->Qnt; i++) for (i = 0; i<modbus_msg->Qnt; i++)
{ {
modbus_msg->DATA[i] = *(pHoldRegs++); modbus_msg->MbData[i] = *(pHoldRegs++);
} }
return 1; return 1;
} }
@@ -63,7 +123,7 @@ uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
// get origin address for data // get origin address for data
uint16_t *pHoldRegs; uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров 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; return 0;
//-----------WRITTING REG------------ //-----------WRITTING REG------------
@@ -88,22 +148,15 @@ uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
// get origin address for data // get origin address for data
uint16_t *pHoldRegs; uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров 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; return 0;
//-----------WRITTING REGS----------- //-----------WRITTING REGS-----------
for (int i = 0; i<modbus_msg->Qnt; i++) for (int i = 0; i<modbus_msg->Qnt; i++)
{ {
*(pHoldRegs++) = modbus_msg->DATA[i]; *(pHoldRegs++) = modbus_msg->MbData[i];
} }
return 1; return 1;
} }
#endif //MODBUS_ENABLE_HOLDINGS
#else //MODBUS_ENABLE_HOLDINGS
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
#endif

View File

@@ -14,6 +14,65 @@
#ifdef MODBUS_ENABLE_INPUTS #ifdef MODBUS_ENABLE_INPUTS
/**
* @brief Записать входной регистр по глобальному адресу.
* @param Addr Адрес регистра.
* @param WriteVal Число для записи.
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
uint16_t *pInRegs;
//------------WRITE COIL-------------
Exception = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input);
if(Exception == ET_NO_ERRORS)
{
*(pInRegs) = WriteVal;
}
return Exception;
}
/**
* @brief Считать входной регистр по глобальному адресу.
* @param Addr Адрес регистра.
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
* @return uint16_t Возвращает значение регистра.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp = 0;
uint16_t *pInRegs;
//------------READ COIL--------------
Exception_tmp = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input);
if(Exception) // if exception is not given to func fill it
*Exception = Exception_tmp;
if(Exception_tmp == ET_NO_ERRORS)
{
return *(pInRegs);
}
else
{
return 0;
}
}
/** /**
* @brief Обработать функцию Read Input Registers (04 - 0x04). * @brief Обработать функцию Read Input Registers (04 - 0x04).
* @param modbus_msg Указатель на структуру собщения modbus. * @param modbus_msg Указатель на структуру собщения modbus.
@@ -26,7 +85,7 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
// get origin address for data // get origin address for data
uint16_t *pInRegs; uint16_t *pInRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров 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; return 0;
@@ -38,15 +97,11 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
for (i = 0; i<modbus_msg->Qnt; i++) for (i = 0; i<modbus_msg->Qnt; i++)
{ {
if(*((int16_t *)pInRegs) > 0) if(*((int16_t *)pInRegs) > 0)
modbus_msg->DATA[i] = (*pInRegs++); modbus_msg->MbData[i] = (*pInRegs++);
else else
modbus_msg->DATA[i] = (*pInRegs++); modbus_msg->MbData[i] = (*pInRegs++);
} }
return 1; return 1;
} }
#else //MODBUS_ENABLE_INPUTS #endif //MODBUS_ENABLE_INPUTS
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
#endif

View File

@@ -29,9 +29,9 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
return 0; return 0;
// Проверяем что ответ связан с регистрами // Проверяем что ответ связан с регистрами
if((modbus_msg->Func_Code != MB_R_DISC_IN) && if((modbus_msg->FuncCode != FC_R_DISC_IN) &&
(modbus_msg->Func_Code != MB_R_HOLD_REGS) && (modbus_msg->FuncCode != FC_R_HOLD_REGS) &&
(modbus_msg->Func_Code != MB_R_IN_REGS)) (modbus_msg->FuncCode != FC_R_IN_REGS))
{ {
return 0; return 0;
} }
@@ -48,11 +48,208 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
return 0; return 0;
// Получаем значение регистра // Получаем значение регистра
*reg_value = modbus_msg->DATA[reg_index]; *reg_value = modbus_msg->MbData[reg_index];
return 1; return 1;
} }
/**
* @brief Получить состояние coil в ответе по его адресу
* @param modbus_msg Указатель на структуру сообщения
* @param coil_addr Адрес coil, состояние которого нужно получить
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
*/
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
{
if(modbus_msg == NULL || coil_state == NULL)
return 0;
// Проверяем что ответ связан с коилами
if(modbus_msg->FuncCode != FC_R_COILS)
{
return 0;
}
// Проверяем что coil_addr в пределах запрошенного диапазона
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0;
// Вычисляем индекс coil в полученных данных
uint16_t coil_index = coil_addr - modbus_msg->Addr;
// Вычисляем байт и бит
uint8_t byte_index = coil_index / 8;
uint8_t data_index = coil_index / 16;
uint8_t bit_index = coil_index % 16;
// Проверяем что байт существует в данных
if(byte_index >= modbus_msg->ByteCnt)
return 0;
// Получаем байт и проверяем бит
if(bit_index < 8)
*coil_state = (modbus_msg->MbData[data_index] >> (bit_index+8)) & 0x01;
else
*coil_state = ((modbus_msg->MbData[data_index]&0xFF) >> bit_index-8) & 0x01;
return 1;
}
/**
* @brief Получить количество объектов в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @return int Количество объектов
*/
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
{
if(modbus_msg == NULL)
{
return 0;
}
// Проверяем что ответ связан с диагностикой
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
{
return 0;
}
return modbus_msg->DevId.NumbOfObj;
}
/**
* @brief Найти объект по ID в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @param obj_id ID искомого объекта
* @param obj_data Буфер для данных объекта (может быть NULL)
* @param obj_length Указатель для длины объекта
* @return int Найден ли объект (1 - да, 0 - нет)
*/
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
{
return 0;
}
uint8_t *data = (uint8_t*)modbus_msg->MbData;
unsigned ind = 0;
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
{
uint8_t current_id = data[ind++];
uint8_t current_length = data[ind++];
if(current_id == obj_id)
{
if(obj_length)
*obj_length = current_length;
for(int j = 0; j < current_length; j++)
{
obj_data[j] = data[ind++];
}
obj_data[current_length] = '\0'; // добавляем \0
return 1;
}
else
{
// Пропускаем данные этого объекта
ind += current_length;
}
}
return 0;
}
/**
* @brief Получить объект по индексу в сообщении
* @param modbus_msg Указатель на структуру сообщения
* @param index Индекс объекта (0..N-1)
* @param obj_id Указатель для ID объекта
* @param obj_data Буфер для данных объекта
* @param obj_length Указатель для длины объекта
* @return int Успешность получения (1 - получен, 0 - не найден)
*/
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
{
return 0;
}
if(index >= modbus_msg->DevId.NumbOfObj)
return 0;
uint8_t *data = (uint8_t*)modbus_msg->MbData;
unsigned ind = 0;
for(int i = 0; i <= index; i++)
{
uint8_t current_id = data[ind++];
uint8_t current_length = data[ind++];
if(obj_id)
*obj_id = current_id;
if(obj_length)
*obj_length = current_length;
if(i == index)
{
for(int j = 0; j < current_length; j++)
{
obj_data[j] = data[ind++];
}
obj_data[current_length] = '\0'; // добавляем \0
return 1;
}
else
{
// Пропускаем данные этого объекта
ind += current_length;
}
}
return 0;
}
/**
* @brief Получить данные диагностики из сообщения (MbData[1])
* @param modbus_msg Указатель на структуру сообщения
* @param data Указатель куда положить данные
* @return 1 - успех, 0 - ошибка
*/
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
{
if(modbus_msg == NULL || data == NULL)
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->FuncCode != FC_R_DIAGNOSTICS)
{
return 0;
}
*data = modbus_msg->MbData[1];
return 1;
}
/** /**
* @brief Определить размер модбас запроса (МАСТЕР версия). * @brief Определить размер модбас запроса (МАСТЕР версия).
* @param hRS Указатель на хендлер RS. * @param hRS Указатель на хендлер RS.
@@ -67,24 +264,24 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
// Master mode - calculating response size from slave // 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] // Error response: [Addr][Func|0x80][ExceptCode][CRC]
mb_func_size = -1; // Only Exception Code 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] // Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
mb_func_size = 1; 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 // Device identifications: variable size, need to read first to determine
mb_func_size = 0; // Will be determined after reading header mb_func_size = 0; // Will be determined after reading header
} }
else else
{ {
switch (modbus_msg->Func_Code & ~ERR_VALUES_START) switch (modbus_msg->FuncCode & ~FC_ERR_VALUES_START)
{ {
case 0x01: // Read Coils case 0x01: // Read Coils
case 0x02: // Read Discrete Inputs case 0x02: // Read Discrete Inputs
@@ -132,25 +329,30 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
modbus_uart_buff[ind++] = modbus_msg->MbAddr; modbus_uart_buff[ind++] = modbus_msg->MbAddr;
// set function code // 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 // 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.MEI_Type;
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId; modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId; 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] // 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->MbData[0] >> 8; // Sub-function HI
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
} }
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // classic modbus request else // classic modbus request
{ {
// set address // set address
@@ -162,12 +364,12 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF; modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF;
// for write multiple functions // 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; modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
// write data bytes // 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++) for(int i = 0; i < modbus_msg->ByteCnt; i++)
{ {
modbus_uart_buff[ind++] = tmp_data_addr[i]; modbus_uart_buff[ind++] = tmp_data_addr[i];
@@ -182,7 +384,7 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
//---------------CRC---------------- //---------------CRC----------------
//---------[last 2 bytes]---------- //---------[last 2 bytes]----------
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind); 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 & 0xFF;
modbus_uart_buff[ind++] = CRC_VALUE >> 8; modbus_uart_buff[ind++] = CRC_VALUE >> 8;
@@ -207,15 +409,17 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
modbus_msg->MbAddr = modbus_uart_buff[ind++]; modbus_msg->MbAddr = modbus_uart_buff[ind++];
// get function code (check if error response) // 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++]; 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.MEI_Type = modbus_uart_buff[ind++];
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++]; modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
@@ -227,7 +431,7 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
modbus_msg->ByteCnt = 0; 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; int data_index = 0;
for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++) for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++)
@@ -249,24 +453,27 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
modbus_msg->ByteCnt += (2 + object_length); // ID + длина + данные 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] // Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8; modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[0] |= modbus_uart_buff[ind++]; modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8; modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[1] |= modbus_uart_buff[ind++]; modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
} }
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // classic modbus response else // classic modbus response
{ {
// get byte count for read functions // get byte count for read functions
if((modbus_msg->Func_Code == 0x01) || (modbus_msg->Func_Code == 0x02) || if((modbus_msg->FuncCode == 0x01) || (modbus_msg->FuncCode == 0x02) ||
(modbus_msg->Func_Code == 0x03) || (modbus_msg->Func_Code == 0x04)) (modbus_msg->FuncCode == 0x03) || (modbus_msg->FuncCode == 0x04))
{ {
modbus_msg->ByteCnt = modbus_uart_buff[ind++]; modbus_msg->ByteCnt = modbus_uart_buff[ind++];
// read data bytes // 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++) for(int i = 0; i < modbus_msg->ByteCnt; i++)
{ {
if(i % 2 == 0) // HI byte if(i % 2 == 0) // HI byte
@@ -276,8 +483,8 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
} }
} }
// for write functions - echo address and quantity // for write functions - echo address and quantity
else if((modbus_msg->Func_Code == 0x05) || (modbus_msg->Func_Code == 0x06) || else if((modbus_msg->FuncCode == 0x05) || (modbus_msg->FuncCode == 0x06) ||
(modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10)) (modbus_msg->FuncCode == 0x0F) || (modbus_msg->FuncCode == 0x10))
{ {
modbus_msg->Addr = modbus_uart_buff[ind++] << 8; modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
modbus_msg->Addr |= modbus_uart_buff[ind++]; modbus_msg->Addr |= modbus_uart_buff[ind++];
@@ -291,10 +498,10 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
//---------------CRC---------------- //---------------CRC----------------
//----------[last 2 bytes]---------- //----------[last 2 bytes]----------
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind); uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
modbus_msg->MB_CRC = modbus_uart_buff[ind++]; modbus_msg->MbCRC = modbus_uart_buff[ind++];
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8; 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); TrackerCnt_Err(hmodbus->rs_err);
return RS_PARSE_MSG_ERR; return RS_PARSE_MSG_ERR;
@@ -310,58 +517,58 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
/** @brief Сформировать запрос на чтение коилов */ /** @brief Сформировать запрос на чтение коилов */
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) 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; return msg;
} }
/** @brief Сформировать запрос на чтение дискретных регистров */ /** @brief Сформировать запрос на чтение дискретных регистров */
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) 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; return msg;
} }
/** @brief Сформировать запрос на чтение холдинг регистров */ /** @brief Сформировать запрос на чтение холдинг регистров */
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) 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; return msg;
} }
/** @brief Сформировать запрос на чтение инпут регистров */ /** @brief Сформировать запрос на чтение инпут регистров */
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) 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; return msg;
} }
/** @brief Сформировать запрос на запись одного коила */ /** @brief Сформировать запрос на запись одного коила */
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value) 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; return msg;
} }
/** @brief Сформировать запрос на запись одного регистра */ /** @brief Сформировать запрос на запись одного регистра */
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value) 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; return msg;
} }
/** @brief Сформировать запрос на запись нескольких регистров */ /** @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 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 // Calculate byte count and prepare data
uint8_t byte_count = (quantity + 7) / 8; uint8_t byte_count = (quantity + 7) / 8;
msg.ByteCnt = byte_count; 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++) { for(int i = 0; i < byte_count; i++) {
if(i < DATA_SIZE) { if(i < DATA_SIZE) {
msg.DATA[i] = coils_data[i]; msg.MbData[i] = coils_data[i];
} }
} }
@@ -371,13 +578,13 @@ RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start
/** @brief Сформировать запрос на запись нескольких коилов */ /** @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 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 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++) { for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
msg.DATA[i] = regs_data[i]; msg.MbData[i] = regs_data[i];
} }
return msg; return msg;
@@ -386,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 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; return msg;
} }
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
@@ -457,71 +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 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; return msg;
} }
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr) 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; return msg;
} }
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr) 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; return msg;
} }
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id) 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; return msg;
} }
#endif //MODBUS_ENABLE_MASTER
#else
RS_MsgTypeDef msg_dummy = {0};
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data) {return msg_dummy;}
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr) {return msg_dummy;}
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id) {return msg_dummy;}
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
#endif

View File

@@ -37,26 +37,26 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
} }
MB_Diagnostics_SlaveMessageCnt(); 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 // Read Coils
case MB_R_COILS: case FC_R_COILS:
hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr);
break; break;
// Read Hodling Registers // Read Hodling Registers
case MB_R_HOLD_REGS: case FC_R_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr);
break; break;
case MB_R_IN_REGS: case FC_R_IN_REGS:
hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr);
break; break;
// Write Single Coils // Write Single Coils
case MB_W_COIL: case FC_W_COIL:
hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled) if(hmodbus->f.MessageHandled)
{ {
@@ -66,7 +66,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
} }
break; break;
case MB_W_HOLD_REG: case FC_W_HOLD_REG:
hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled) if(hmodbus->f.MessageHandled)
{ {
@@ -77,7 +77,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
break; break;
// Write Multiple Coils // Write Multiple Coils
case MB_W_COILS: case FC_W_COILS:
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled) if(hmodbus->f.MessageHandled)
{ {
@@ -88,7 +88,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
break; break;
// Write Multiple Registers // Write Multiple Registers
case MB_W_HOLD_REGS: case FC_W_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled) if(hmodbus->f.MessageHandled)
{ {
@@ -98,12 +98,12 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
} }
break; break;
case MB_R_DEVICE_INFO: case FC_R_DEVICE_ID:
hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr);
break; break;
// Добавить в switch-case после других case: // Добавить в switch-case после других case:
case MB_R_DIAGNOSTIC: case FC_R_DIAGNOSTICS:
hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr);
break; break;
@@ -126,7 +126,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
{ {
MB_Diagnostics_ExceptionErrorCnt(); MB_Diagnostics_ExceptionErrorCnt();
TrackerCnt_Warn(hmodbus->rs_err); TrackerCnt_Warn(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START; modbus_msg->FuncCode |= FC_ERR_VALUES_START;
} }
else else
{ {
@@ -173,17 +173,29 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
else else
{ {
//------INFO ABOUT DATA/MESSAGE------ //------INFO ABOUT DATA/MESSAGE------
#ifdef MODBUS_PROTOCOL_TCP
modbus_uart_buff[ind++] = modbus_msg->TransactionID >> 8;
modbus_uart_buff[ind++] = modbus_msg->TransactionID& 0xFF;
modbus_uart_buff[ind++] = modbus_msg->ProtocolID >> 8;
modbus_uart_buff[ind++] = modbus_msg->ProtocolID& 0xFF;
modbus_uart_buff[ind++] = modbus_msg->PDULength >> 8;
modbus_uart_buff[ind++] = modbus_msg->PDULength& 0xFF;
#endif
//-----------[first bytes]----------- //-----------[first bytes]-----------
// set ID of message/user // set ID of message/user
modbus_uart_buff[ind++] = modbus_msg->MbAddr; modbus_uart_buff[ind++] = modbus_msg->MbAddr;
// set dat or err response // 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 // 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.MEI_Type;
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId; modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
@@ -201,7 +213,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------DATA---------------- //---------------DATA----------------
//-----------[data bytes]------------ //-----------[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 for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
{ // set data { // set data
modbus_uart_buff[ind++] = *tmp_data_addr; modbus_uart_buff[ind++] = *tmp_data_addr;
@@ -209,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] // 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->MbData[0] >> 8; // Sub-function HI
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
} }
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // modbus data header else // modbus data header
{ {
// set size of received data // set size of received data
@@ -230,7 +245,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------DATA---------------- //---------------DATA----------------
//-----------[data bytes]------------ //-----------[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 for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
{ // set data { // set data
if (i%2 == 0) // HI byte if (i%2 == 0) // HI byte
@@ -255,12 +270,14 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------CRC---------------- //---------------CRC----------------
//---------[last 16 bytes]---------- //---------[last 16 bytes]----------
#ifndef MODBUS_PROTOCOL_TCP
// calc crc of received data // calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind); uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// write crc to message structure and modbus-uart buffer // 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;
modbus_uart_buff[ind++] = CRC_VALUE >> 8; modbus_uart_buff[ind++] = CRC_VALUE >> 8;
#endif
hmodbus->RS_Message_Size = ind; hmodbus->RS_Message_Size = ind;
@@ -279,15 +296,15 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
RS_StatusTypeDef MB_RES = 0; RS_StatusTypeDef MB_RES = 0;
int mb_func_size = 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; 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; 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; mb_func_size = 1;
} }
@@ -317,6 +334,16 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
hmodbus->f.RX_Continue = 0; hmodbus->f.RX_Continue = 0;
int expected_size = 0; int expected_size = 0;
//-----INFO ABOUT DATA/MESSAGE------- //-----INFO ABOUT DATA/MESSAGE-------
#ifdef MODBUS_PROTOCOL_TCP
modbus_msg->TransactionID =modbus_uart_buff[ind++]<<8;
modbus_msg->TransactionID |=modbus_uart_buff[ind++];
modbus_msg->ProtocolID =modbus_uart_buff[ind++]<<8;
modbus_msg->ProtocolID |=modbus_uart_buff[ind++];
modbus_msg->PDULength =modbus_uart_buff[ind++]<<8;
modbus_msg->PDULength |=modbus_uart_buff[ind++];
#endif
//-----------[first bits]------------ //-----------[first bits]------------
// get ID of message/user // get ID of message/user
if(modbus_uart_buff[ind] != hmodbus->ID) if(modbus_uart_buff[ind] != hmodbus->ID)
@@ -330,33 +357,38 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
} }
// get func code // get func code
modbus_msg->Func_Code = modbus_uart_buff[ind++]; modbus_msg->FuncCode = modbus_uart_buff[ind++];
if(modbus_msg->Func_Code & ERR_VALUES_START) // явная херня if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // явная херня
{ {
MB_Diagnostics_SlaveNAKCnt(); MB_Diagnostics_SlaveNAKCnt();
modbus_msg->MbAddr = 0; modbus_msg->MbAddr = 0;
return RS_SKIP; 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.MEI_Type = modbus_uart_buff[ind++];
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++]; modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++]; modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
modbus_msg->ByteCnt = 0; 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 // Sub-function
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8; modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[0] |= modbus_uart_buff[ind++]; modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
// Data // Data
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8; modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[1] |= modbus_uart_buff[ind++]; modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
modbus_msg->Addr = 0; // не использует Addr modbus_msg->Addr = 0; // не использует Addr
modbus_msg->Qnt = 0; // не использует Qnt modbus_msg->Qnt = 0; // не использует Qnt
} }
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // if its classic modbus request else // if its classic modbus request
{ {
// get address from CMD // get address from CMD
@@ -368,7 +400,7 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
modbus_msg->Qnt |= modbus_uart_buff[ind++]; 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++]; hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
else else
hmodbus->pMessagePtr->ByteCnt = 0; hmodbus->pMessagePtr->ByteCnt = 0;
@@ -395,11 +427,11 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
if (modbus_msg->ByteCnt > DATA_SIZE*2) if (modbus_msg->ByteCnt > DATA_SIZE*2)
{ {
TrackerCnt_Err(hmodbus->rs_err); TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START; modbus_msg->FuncCode |= FC_ERR_VALUES_START;
MB_Diagnostics_CommunicationErrorCnt(); MB_Diagnostics_CommunicationErrorCnt();
return RS_PARSE_MSG_ERR; 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++) for(int i = 0; i < modbus_msg->ByteCnt; i++)
{ // set data { // set data
if (i%2 == 0) if (i%2 == 0)
@@ -414,24 +446,22 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
//---------------CRC---------------- //---------------CRC----------------
//----------[last 16 bits]---------- //----------[last 16 bits]----------
#ifndef MODBUS_PROTOCOL_TCP
// calc crc of received data // calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind); uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// get crc of received data // get crc of received data
modbus_msg->MB_CRC = modbus_uart_buff[ind++]; modbus_msg->MbCRC = modbus_uart_buff[ind++];
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8; modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
// compare crc // compare crc
if (modbus_msg->MB_CRC != CRC_VALUE) if (modbus_msg->MbCRC != CRC_VALUE)
{ {
MB_Diagnostics_CommunicationErrorCnt(); MB_Diagnostics_CommunicationErrorCnt();
TrackerCnt_Err(hmodbus->rs_err); TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START; modbus_msg->FuncCode |= FC_ERR_VALUES_START;
} }
#endif
return RS_OK; return RS_OK;
} }
#else // MODBUS_ENABLE_SLAVE #endif //MODBUS_ENABLE_SLAVE
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) {return RS_ERR;}
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
#endif

View File

@@ -323,6 +323,7 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
{ {
return; return;
} }
RS_UART_Handler_ENTER();
//-------------CHECK IDLE FLAG FIRST------------- //-------------CHECK IDLE FLAG FIRST-------------
/* Проверяем флаг IDLE в первую очередь - это гарантирует обработку только после idle */ /* Проверяем флаг IDLE в первую очередь - это гарантирует обработку только после idle */
if(__HAL_UART_GET_FLAG(hRS->huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(hRS->huart, UART_IT_IDLE)) if(__HAL_UART_GET_FLAG(hRS->huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(hRS->huart, UART_IT_IDLE))
@@ -348,22 +349,24 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
RS_Set_RX_End(hRS); RS_Set_RX_End(hRS);
// Парсим наше сообщение // Парсим наше сообщение
RS_StatusTypeDef parse_res = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); hRS->RS_STATUS = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr);
// Если сообещине принято корректно // Если сообещине принято корректно
if(parse_res == RS_OK) if(hRS->RS_STATUS == RS_OK)
{ {
RS_Timeout_Stop(hRS); RS_Timeout_Stop(hRS);
hRS->lastPacketTick = uwTick; hRS->lastPacketTick = local_time();
if(hRS->sRS_Mode < RS_MASTER_MODE_START) if(hRS->sRS_Mode < RS_MASTER_MODE_START)
{
RS_Response(hRS, hRS->pMessagePtr); // отвечаем на запрос RS_Response(hRS, hRS->pMessagePtr); // отвечаем на запрос
}
else else
{ {
RS_Set_Free(hRS); // освобожднаем RS
if(hRS->pCallback) if(hRS->pCallback)
{ {
hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ
RS_Set_Free(hRS); // освобожднаем RS
} }
} }
} }
@@ -417,6 +420,7 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
// later, maybe, will be added specific handlers for err // later, maybe, will be added specific handlers for err
} }
RS_UART_Handler_EXIT();
} }
@@ -432,20 +436,30 @@ void RS_TIM_Handler(RS_HandleTypeDef *hRS)
{ {
return; return;
} }
RS_TIM_Handler_ENTER();
HAL_TIM_IRQHandler(hRS->htim); HAL_TIM_IRQHandler(hRS->htim);
RS_Abort(hRS, ABORT_RS); RS_Abort(hRS, ABORT_RS);
hRS->RS_STATUS = RS_TIMEOUT;
if(hRS->sRS_Mode < RS_MASTER_MODE_START)
if(hRS->pMessagePtr->MbAddr == hRS->ID) // ошибка если таймаут по нашему сообщению if(hRS->pMessagePtr->MbAddr == hRS->ID) // ошибка если таймаут по нашему сообщению
TrackerCnt_Err(hRS->rs_err); TrackerCnt_Err(hRS->rs_err);
if(hRS->sRS_Mode == RS_MASTER_REQUEST) { if(hRS->sRS_Mode >= RS_MASTER_MODE_START)
// Мастер: таймаут ответа -> освобождаем для нового запроса { // Мастер: коллбек и освобождение для нового запроса
RS_Set_Free(hRS); RS_Set_Free(hRS);
if(hRS->pCallback)
{
hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ
}
} else { } else {
// Слейв: перезапускаем прием // Слейв: перезапускаем прием
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr); RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
} }
RS_TIM_Handler_EXIT();
} }
/** /**

View File

@@ -9,9 +9,11 @@
****************************************************************************** ******************************************************************************
* @details * @details
Файл содержит настройки для работы Modbus: Файл содержит настройки для работы Modbus:
- Идентификатор устройства и таймауты - Подключение библиотек контроллера
- ID устройства и таймауты
- Строковые идентификаторы (Vendor, Product, Revision) - Строковые идентификаторы (Vendor, Product, Revision)
- Настройки периферии (UART, TIMER) - Настройки периферии (UART, TIMER)
- Подключение модулей Modbus
- Опциональные функции (переключение команд 0x03/0x04) - Опциональные функции (переключение команд 0x03/0x04)
******************************************************************************/ ******************************************************************************/
#ifndef _MODBUS_CONFIG_H_ #ifndef _MODBUS_CONFIG_H_
@@ -30,7 +32,9 @@
#define MODBUS_PRODUCT_NAME "" #define MODBUS_PRODUCT_NAME ""
#define MODBUS_MODEL_NAME "" #define MODBUS_MODEL_NAME ""
#define MODBUS_USER_APPLICATION_NAME "" #define MODBUS_USER_APPLICATION_NAME ""
#define MODBUS_NUMB_OF_USEROBJECTS 0
#define MODBUS_NUMB_OF_USEROBJECTS 0 ///< Количество пользовательских объектов
#define MODBUS_USEROBJECT_0_NAME "" ///< Строка пользовательского идентификатора 0. По аналогии можно определить строки до <=128 USEROBJECT
// Периферия (опционально) // Периферия (опционально)
#define mb_huart huart1 ///< Удобный дефайн для модбасовского uart #define mb_huart huart1 ///< Удобный дефайн для модбасовского uart
@@ -49,6 +53,7 @@
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства #define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас #define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
//#define MODBUS_PROTOCOL_TCP ///< Включить TCP-протокол, иначе - RTU
/** /**
* @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей) * @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей)

View File

@@ -29,11 +29,11 @@
* @param Qnt Количество запрашиваемых элементов. * @param Qnt Количество запрашиваемых элементов.
* @param R_ARR_ADDR Начальный адресс массива R_ARR. * @param R_ARR_ADDR Начальный адресс массива R_ARR.
* @param R_ARR_NUMB Количество элементов в массиве 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: * @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR. * Если адресс 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) 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 quantity too big return error
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB) 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 // if all ok - return no errors
return NO_ERRORS; return ET_NO_ERRORS;
} }
// if address isnt from this array return error // if address isnt from this array return error
else else
return ILLEGAL_DATA_ADDRESS; // return exception code return ET_ILLEGAL_DATA_ADDRESS; // return exception code
} }
/** /**
* @brief Define Address Origin for Input/Holding Registers * @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 Addr Адрес начального регистра.
* @param Qnt Количество запрашиваемых регистров. * @param Qnt Количество запрашиваемых регистров.
* @param WriteFlag Флаг регистр нужны для чтения или записи. * @param WriteFlag Флаг регистр нужны для чтения или записи.
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет. * @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
* *
* @details Определение адреса начального регистра. * @details Определение адреса начального регистра.
* @note WriteFlag пока не используется. * @note WriteFlag пока не используется.
@@ -68,41 +68,41 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
/* check quantity error */ /* check quantity error */
if (Qnt > DATA_SIZE) if (Qnt > DATA_SIZE)
{ {
return ILLEGAL_DATA_VALUE; // return exception code return ET_ILLEGAL_DATA_VALUE; // return exception code
} }
if(RegisterType == RegisterType_Holding) if(RegisterType == RegisterType_Holding)
{ {
// Default holding registers // 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 регистр *pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
} }
// if address doesnt match any array - return illegal data address response // if address doesnt match any array - return illegal data address response
else else
{ {
return ILLEGAL_DATA_ADDRESS; return ET_ILLEGAL_DATA_ADDRESS;
} }
} }
else if(RegisterType == RegisterType_Input) else if(RegisterType == RegisterType_Input)
{ {
// Default input registers // 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 регистр *pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
} }
// if address doesnt match any array - return illegal data address response // if address doesnt match any array - return illegal data address response
else else
{ {
return ILLEGAL_DATA_ADDRESS; return ET_ILLEGAL_DATA_ADDRESS;
} }
} }
else else
{ {
return ILLEGAL_FUNCTION; return ET_ILLEGAL_FUNCTION;
} }
// if found requeried array return no err // 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 * @brief Define Address Origin for coils
@@ -111,7 +111,7 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
* @param Qnt Количество запрашиваемых коилов. * @param Qnt Количество запрашиваемых коилов.
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила. * @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
* @param WriteFlag Флаг коилы нужны для чтения или записи. * @param WriteFlag Флаг коилы нужны для чтения или записи.
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет. * @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
* *
* @details Определение адреса начального регистра запрашиваемых коилов. * @details Определение адреса начального регистра запрашиваемых коилов.
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR. * @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
@@ -121,21 +121,21 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
/* check quantity error */ /* check quantity error */
if (Qnt > 2000) if (Qnt > 2000)
{ {
return ILLEGAL_DATA_VALUE; // return exception code return ET_ILLEGAL_DATA_VALUE; // return exception code
} }
// Default coils // 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 массив коилов *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 // if address doesnt match any array - return illegal data address response
else else
{ {
return ILLEGAL_DATA_ADDRESS; return ET_ILLEGAL_DATA_ADDRESS;
} }
*start_shift = Addr % 16; // set shift to requested coil *start_shift = Addr % 16; // set shift to requested coil
// if found requeried array return no err // if found requeried array return no err
return NO_ERRORS; // return no errors return ET_NO_ERRORS; // return no errors
} }

View File

@@ -36,14 +36,14 @@
uint16_t user_regs[16]; 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); // ВАЖНО! *pRegs = MB_Set_Register_Ptr(&user_regs, Addr-R_USER_ADDR); // ВАЖНО!
// -R_USER_ADDR нужен чтобы взять адрес относительно начала массива // -R_USER_ADDR нужен чтобы взять адрес относительно начала массива
} }
else else
{ {
return ILLEGAL_DATA_ADDRESS; return ET_ILLEGAL_DATA_ADDRESS;
} }
@endcode @endcode
******************************************************************************/ ******************************************************************************/