API для реквестов MB_RespGet.. перенесено в modbus_master
This commit is contained in:
@@ -82,6 +82,13 @@
|
|||||||
#include "modbus_diag.h"
|
#include "modbus_diag.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MODBUS_ENABLE_MASTER
|
||||||
|
#define MODBUS_MODE_MASTER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODBUS_ENABLE_SLAVE
|
||||||
|
#define MODBUS_MODE_SLAVE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|||||||
@@ -84,40 +84,6 @@ Coils упакованы в 16-битные слова для эффективн
|
|||||||
/////////////////////////---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
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,52 +86,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
|
||||||
* @{
|
* @{
|
||||||
|
|||||||
@@ -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
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
* @{
|
* @{
|
||||||
|
|||||||
@@ -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
|
||||||
* @{
|
* @{
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -284,7 +239,6 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
#else //MODBUS_ENABLE_COILS
|
#else //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;}
|
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;}
|
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_Read_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file modbus_core.c
|
* @file modbus_core.c
|
||||||
* @brief Базовая реализация ядра Modbus (заглушка)
|
* @brief Базовая реализация ядра Modbus
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
В текущей реализации этот файл служит заглушкой для будущего расширения
|
В текущей реализации этот файл служит заглушкой для будущего расширения
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -674,9 +548,7 @@ void MB_DeviceInentificationInit(void)
|
|||||||
#else //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_WriteSingleObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj) {}
|
||||||
void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj) {}
|
void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj) {}
|
||||||
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) {return 0;}
|
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|||||||
@@ -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 бит нельзя выставить)
|
||||||
@@ -319,7 +296,6 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
|
|||||||
#else //MODBUS_ENABLE_DIAGNOSTICS
|
#else //MODBUS_ENABLE_DIAGNOSTICS
|
||||||
|
|
||||||
void MB_DiagnosticsInit(void) {}
|
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_WriteBit(int bit_num, int bit_state) {return 0;}
|
||||||
int MB_Diagnostics_GetBit(int bit_num) {return 0;}
|
int MB_Diagnostics_GetBit(int bit_num) {return 0;}
|
||||||
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) {return 0;}
|
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|||||||
@@ -53,6 +53,203 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
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->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 Получить количество объектов в сообщении
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 hRS Указатель на хендлер RS.
|
* @param hRS Указатель на хендлер RS.
|
||||||
@@ -487,6 +684,11 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
|
|||||||
RS_MsgTypeDef msg_dummy = {0};
|
RS_MsgTypeDef msg_dummy = {0};
|
||||||
|
|
||||||
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
|
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
|
||||||
|
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
|
||||||
|
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;}
|
||||||
|
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data) {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_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_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||||
|
|||||||
@@ -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_
|
||||||
|
|||||||
Reference in New Issue
Block a user