release 0.3.1

doxygen + refactoring
This commit is contained in:
2025-11-05 00:08:41 +03:00
parent 106deb0fcc
commit ecda27792c
21 changed files with 310 additions and 189 deletions

View File

@@ -14,7 +14,7 @@
Подключает все необходимые модули: Подключает все необходимые модули:
@section Инструкция по подключению @section init Инструкция по подключению
Для корректной работы надо: Для корректной работы надо:
- Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие - Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие
низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика
@@ -48,7 +48,7 @@
@endverbatim @endverbatim
@section Подключаемые модули: @section Подключаемые модули:
- rs_message.h - работа с uart - rs_message.h - работа с uart
- modbus_core.h - базовые определения - modbus_core.h - базовые определения
- modbus_coils.h - работа с дискретными выходами - modbus_coils.h - работа с дискретными выходами
@@ -58,7 +58,7 @@
- modbus_diag.h - диагностика modbus - modbus_diag.h - диагностика modbus
@section Структура данных Modbus @section Структура данных Modbus
#### Holding/Input Registers: #### Holding/Input Registers:
- Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель. - Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_COILS Coils Tools @addtogroup MODBUS_COILS Coils Tools
@ingroup MODBUS_INTERNAL @ingroup MODBUS_INTERNAL
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль предоставляет функции и макросы для работы с битовыми данными: Модуль предоставляет функции и макросы для работы с битовыми данными:
@@ -14,11 +13,11 @@
- Запись множественных coils (0x0F) - распаковка байтов в биты - Запись множественных coils (0x0F) - распаковка байтов в биты
- Макросы для локального доступа к coils - Макросы для локального доступа к coils
@section Организация битовых данных: @section Организация битовых данных:
Coils упакованы в 16-битные слова для эффективного использования памяти. Coils упакованы в 16-битные слова для эффективного использования памяти.
Биты нумеруются от младшего к старшему внутри каждого слова. Биты нумеруются от младшего к старшему внутри каждого слова.
@section Адресация: @section Адресация:
- Глобальная - абсолютный адрес в пространстве Modbus - Глобальная - абсолютный адрес в пространстве Modbus
- Локальная - относительный адрес внутри массива coils - Локальная - относительный адрес внутри массива coils
- Макросы автоматически вычисляют смещения и маски - Макросы автоматически вычисляют смещения и маски
@@ -31,16 +30,15 @@ Coils упакованы в 16-битные слова для эффективн
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
////////////////////---MODBUS FUNCTION DEFINES---//////////////////// ////////////////////---MODBUS FUNCTION DEFINES---////////////////////
/** @brief Structure for coils operation */
typedef enum
{
SET_COIL,
RESET_COIL,
TOOGLE_COIL,
}MB_CoilsOpTypeDef;
//-------------------------------------------------- //--------------------------------------------------
/**
* @addtogroup MODBUS_COILS
* @{
*/
/** /**
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил * @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
* @param _parr_ - массив коилов. * @param _parr_ - массив коилов.
@@ -77,17 +75,14 @@ typedef enum
*/ */
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) )) #define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
/** MODBUS_COILS
* @}
*/
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
* @ingroup MODBUS_FUNCTIONS
* @brief Функции для доступа к данным модбас
@{
*/
/** /**
* @addtogroup MODBUS_REQ_COILS_API API for Coils * @addtogroup MODBUS_REQ_COILS_API API for Coils
@@ -98,7 +93,7 @@ typedef enum
* @code * @code
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25 * // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
* int coil_state; * int coil_state;
* if(MB_GetCoilState(&MODBUS_MSG, 25, &coil_state)) * if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
* { * {
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF"); * printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
* } * }
@@ -107,15 +102,16 @@ typedef enum
* 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++)
* { * {
* int state; * int state;
* if(MB_GetCoilState(&MODBUS_MSG, addr, &state)) * if(MB_RespGet_CoilState(&MODBUS_MSG, addr, &state))
* { * {
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF"); * printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
* } * }
* } * }
* @endcode * @endcode
* @{
*/ */
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state); int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
/** MODBUS_REQ_COILS_API /** MODBUS_REQ_COILS_API
* @} * @}
@@ -123,6 +119,22 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
/**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
* @ingroup MODBUS_FUNCTIONS
* @brief Функции для доступа к данным модбас
* @{
*/
/** @brief Structure for coils operation */
typedef enum
{
SET_COIL,
RESET_COIL,
TOOGLE_COIL,
}MB_CoilsOpTypeDef;
/** /**
* @brief Считать коил по локальному адресу. * @brief Считать коил по локальному адресу.
* @param _parr_ - массив коилов. * @param _parr_ - массив коилов.
@@ -131,7 +143,7 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
* *
* @details Позволяет обратиться к коилу по адресу относительно _arr_. * @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/ */
#define MB_Read_Coil_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_)) #define MB_Coil_Read_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_))
/** /**
* @brief Выставить коил по локальному адресу. * @brief Выставить коил по локальному адресу.
* @param _parr_ Указатель на массив коилов. * @param _parr_ Указатель на массив коилов.
@@ -139,7 +151,7 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
* *
* @details Позволяет обратиться к коилу по адресу относительно _arr_. * @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/ */
#define MB_Set_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_) #define MB_Coil_Set_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_)
/** /**
* @brief Сбросить коил по локальному адресу. * @brief Сбросить коил по локальному адресу.
* @param _parr_ Указатель на массив коилов. * @param _parr_ Указатель на массив коилов.
@@ -147,7 +159,7 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
* *
* @details Позволяет обратиться к коилу по адресу относительно _arr_. * @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/ */
#define MB_Reset_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_)) #define MB_Coil_Reset_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_))
/** /**
* @brief Переключить состояние коила по локальному адресу. * @brief Переключить состояние коила по локальному адресу.
* @param _parr_ Указатель на массив коилов. * @param _parr_ Указатель на массив коилов.
@@ -155,12 +167,12 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
* *
* @details Позволяет обратиться к коилу по адресу относительно _arr_. * @details Позволяет обратиться к коилу по адресу относительно _arr_.
*/ */
#define MB_Toogle_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_) #define MB_Coil_Toogle_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_)
/* Выставить/сбросить коил по глобальному адресу */ /* Выставить/сбросить коил по глобальному адресу */
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal); MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal);
/* Считать коил по глобальному адресу */ /* Считать коил по глобальному адресу */
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception); uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
/** MODBUS_DATA_ACCESS_FUNCTIONS /** MODBUS_DATA_ACCESS_FUNCTIONS
* @} * @}
@@ -176,7 +188,7 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Single Coils (05 - 0x05) */ /* Обработать функцию Write Single Coils (05 - 0x05) */
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg); uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Multiple Coils (15 - 0x0F) */ /* Обработать функцию Write Multiple Coils (15 - 0x0F) */
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg); uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
/** MODBUS_CMD_PROCESS_FUNCTIONS /** MODBUS_CMD_PROCESS_FUNCTIONS
* @} * @}

View File

@@ -14,7 +14,7 @@
Константы размеров полей Константы размеров полей
Вспомогательные макросы Вспомогательные макросы
@section Структура сообщения: @section Структура сообщения:
[ADDR][FUNC][DATA...][CRC] [ADDR][FUNC][DATA...][CRC]
- Адрес: 1 байт - Адрес: 1 байт
- Функция: 1 байт - Функция: 1 байт

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_DEVID Device Identifications Tools @addtogroup MODBUS_DEVID Device Identifications Tools
@ingroup MODBUS_INTERNAL @ingroup MODBUS_INTERNAL
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль реализации функции Read Device Identifications (0x2B): Модуль реализации функции Read Device Identifications (0x2B):
@@ -13,7 +12,7 @@
- Расширенная идентификация (URL, Model, User fields) - Расширенная идентификация (URL, Model, User fields)
- Поддержка потоковой передачи больших объектов - Поддержка потоковой передачи больших объектов
@section Объекты идентификации: @section Объекты идентификации:
- VendorName, ProductCode, Revision - обязательные - VendorName, ProductCode, Revision - обязательные
- VendorUrl, ProductName, ModelName - опциональные - VendorUrl, ProductName, ModelName - опциональные
- User objects - пользовательские поля - User objects - пользовательские поля
@@ -27,6 +26,11 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
///////////////---DEVICE IDENTIVICATIONS DEFINES---////////////////// ///////////////---DEVICE IDENTIVICATIONS DEFINES---//////////////////
/**
* @addtogroup MODBUS_DEVID
* @{
*/
/** @brief Структура для объекта (идентификатора устройства модбас) */ /** @brief Структура для объекта (идентификатора устройства модбас) */
typedef struct typedef struct
{ {
@@ -61,15 +65,20 @@ void MB_DeviceInentificationInit(void);
* @brief Инициализация объектов * @brief Инициализация объектов
* @details С помозью этого дефайна инициализируются объекты в @ref MB_DeviceInentificationInit * @details С помозью этого дефайна инициализируются объекты в @ref MB_DeviceInentificationInit
*/ */
#define MB_ObjectInit(_p_obj_, _userstring_) (_p_obj_)->length = sizeof(_userstring_);\ #define MB_ObjectInit(_p_obj_, _userstring_) \
(_p_obj_)->name = _userstring_; (_p_obj_)->length = sizeof(_userstring_);\
/** (_p_obj_)->name = _userstring_;
/**
* @brief Инициализация пользовательских объектов * @brief Инициализация пользовательских объектов
* @details С помозью этого дефайна инициализируются пользовательские объекты в MB_DeviceInentificationInit * @details С помозью этого дефайна инициализируются пользовательские объекты в MB_DeviceInentificationInit
*/ */
#define MB_UserObjectInit(_pinfostruct_, _user_numb_) MB_ObjectInit(&(_pinfostruct_)->User[_user_numb_], MODBUS_USEROBJECT##_user_numb_##_NAME) #define MB_UserObjectInit(_pinfostruct_, _user_numb_) MB_ObjectInit(&(_pinfostruct_)->User[_user_numb_], MODBUS_USEROBJECT##_user_numb_##_NAME)
/** MODBUS_DEVID
* @}
*/
////////////////////---MODBUS MESSAGE DEFINES---///////////////////// ////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
@@ -80,14 +89,14 @@ void MB_DeviceInentificationInit(void);
/** /**
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications * @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
* @ingroup MODBUS_REQUEST_MSG * @ingroup MODBUS_REQUEST_MSG
* @brief Макросы для чтения идентификторов из ответа в режиме мастер * @brief API для чтения идентификторов из ответа в режиме мастер
* @details Примеры использования: * @details Примеры использования:
* *
* @code * @code
* // Пример 1: Получить VendorName (ID = 0x00) * // Пример 1: Получить VendorName (ID = 0x00)
* uint8_t length; * uint8_t length;
* char vendor_name[64]; * char vendor_name[64];
* if(MB_FindObjectById(&MODBUS_MSG, 0x00, vendor_name, &length)) * if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
* { * {
* // получено * // получено
* } * }
@@ -96,25 +105,26 @@ void MB_DeviceInentificationInit(void);
* uint8_t obj_id, obj_length; * uint8_t obj_id, obj_length;
* char obj_data[256]; * char obj_data[256];
* *
* int obj_count = MB_GetNumberOfObjects(&MODBUS_MSG); * int obj_count = MB_RespGet_NumberOfObjects(&MODBUS_MSG);
* printf("Total objects: %d\n", obj_count); * printf("Total objects: %d\n", obj_count);
* *
* for(int i = 0; i < obj_count; i++) * for(int i = 0; i < obj_count; i++)
* { * {
* if(MB_GetObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length)) * if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
* { * {
* // получено * // получено
* } * }
* } * }
* @endcode * @endcode
* @{
*/ */
/* Получить количество объектов в сообщении */ /* Получить количество объектов в сообщении */
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg); int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg);
/* Найти объект по ID в сообщении */ /* Найти объект по ID в сообщении */
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length); int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
/* Получить объект по индексу в сообщении */ /* Получить объект по индексу в сообщении */
int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, 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 /** MODBUS_REQ_DEFID_API
@@ -122,12 +132,19 @@ int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, c
*/ */
/**
* @addtogroup MODBUS_DEVID
* @{
*/
/* Записать Один Объект Идентификатора в массив данных */ /* Записать Один Объект Идентификатора в массив данных */
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);
/** MODBUS_DEVID
* @}
*/
//---------PROCESS MODBUS COMMAND FUNCTIONS--------- //---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
@@ -142,7 +159,3 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_DEVID_H_ #endif //__MODBUS_DEVID_H_
/** MODBUS_DEVID
* @}
*/

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_DIAG Diagnostics Tools @addtogroup MODBUS_DIAG Diagnostics Tools
@ingroup MODBUS_INTERNAL @ingroup MODBUS_INTERNAL
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль реализации Diagnostics (Serial Line only) (0x08): Модуль реализации Diagnostics (Serial Line only) (0x08):
@@ -13,7 +12,7 @@
- Возможность выставить/сбросить любой бит в диагностическом регистре - Возможность выставить/сбросить любой бит в диагностическом регистре
- Сбор статистики работы устройства - Сбор статистики работы устройства
- Управление режимами работы - Управление режимами работы
******************************************************************************/ ****************************************** ************************************/
#ifndef __MODBUS_DIAG_H_ #ifndef __MODBUS_DIAG_H_
#define __MODBUS_DIAG_H_ #define __MODBUS_DIAG_H_
#include "modbus_core.h" #include "modbus_core.h"
@@ -21,6 +20,11 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////////////////---DEVICE DIAGNOSTICS DEFINES---//////////////////// /////////////////---DEVICE DIAGNOSTICS DEFINES---////////////////////
/**
* @addtogroup MODBUS_DIAG
* @{
*/
/** @brief Режимы работы устройства */ /** @brief Режимы работы устройства */
typedef enum typedef enum
{ {
@@ -57,6 +61,10 @@ extern MB_DiagnosticsInfoTypeDef MB_DIAG;
/* Инициализация диагностических счетчиков */ /* Инициализация диагностических счетчиков */
void MB_DiagnosticsInit(void); void MB_DiagnosticsInit(void);
/** MODBUS_DIAG
* @}
*/
/** /**
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics * @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
* @ingroup MODBUS_REQUEST_MSG * @ingroup MODBUS_REQUEST_MSG
@@ -64,15 +72,18 @@ void MB_DiagnosticsInit(void);
* @details Примеры использования: * @details Примеры использования:
* *
* @code * @code
* Получить данные диагностики (значение счетчика) * // Получить данные диагностики (значение счетчика)
* uint16_t counter_value; * uint16_t counter_value;
* if(MB_GetDiagnosticResponse(&MODBUS_MSG, &counter_value)) * if(MB_RespGet_Diagnostic(&MODBUS_MSG, &counter_value))
* { * {
* printf("Counter value: %d\n", counter_value); * printf("Counter value: %d\n", counter_value);
* } * }
* @endcode * @endcode
* @{
*/ */
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data);
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data);
/** MODBUS_REQ_DIAG_API /** MODBUS_REQ_DIAG_API
* @} * @}
*/ */
@@ -95,6 +106,17 @@ int MB_Diagnostics_WriteBit(int bit_num, int bit_state);
int MB_Diagnostics_GetBit(int bit_num); int MB_Diagnostics_GetBit(int bit_num);
/* Получение текущего режима устройства */ /* Получение текущего режима устройства */
MB_DeviceModeTypeDef MB_GetDeviceMode(void); MB_DeviceModeTypeDef MB_GetDeviceMode(void);
/* Функции для обновления счетчиков диагностики */
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);
/** MODBUS_CMD_PROCESS_FUNCTIONS /** MODBUS_CMD_PROCESS_FUNCTIONS
* @} * @}
*/ */
@@ -113,15 +135,6 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
*/ */
/* Функции для обновления счетчиков диагностики */
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);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_INS Input Register Tools @addtogroup MODBUS_INS Input Register Tools
@ingroup MODBUS_INTERNAL @ingroup MODBUS_INTERNAL
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль обработки команд для регистров хранения (Holding Registers): Модуль обработки команд для регистров хранения (Holding Registers):
@@ -13,7 +12,7 @@
- Запись одиночного регистра (0x06) - Запись одиночного регистра (0x06)
- Запись множества регистров (0x10) - Запись множества регистров (0x10)
@section Регистры хранения: @section Регистры хранения:
- Read/Write доступ - Read/Write доступ
- 16-битные значения (uint16_t) - 16-битные значения (uint16_t)
******************************************************************************/ ******************************************************************************/
@@ -42,7 +41,3 @@ uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_HOLDREGS_H_ #endif //__MODBUS_HOLDREGS_H_
/** MODBUS_INS
* @}
*/

View File

@@ -5,13 +5,12 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_HOLD Holding Registers Tools @addtogroup MODBUS_HOLD Holding Registers Tools
@ingroup MODBUS_INTERNAL @ingroup MODBUS_INTERNAL
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль обработки команд для входных регистров (Input Registers): Модуль обработки команд для входных регистров (Input Registers):
- Чтение множества регистров (0x04) - Чтение множества регистров (0x04)
@section Входные регистры: @section Входные регистры:
- Read-Only доступ - Read-Only доступ
- 16-битные значения - 16-битные значения
******************************************************************************/ ******************************************************************************/
@@ -25,7 +24,7 @@
//---------PROCESS MODBUS COMMAND FUNCTIONS--------- //---------PROCESS MODBUS COMMAND FUNCTIONS---------
/** /**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
* @ingroup MODBUS_FUNCTIONS * @ingroup MODBUS_INTERNAL
* @brief Функции обработки запросов модбас * @brief Функции обработки запросов модбас
@{ @{
*/ */
@@ -38,6 +37,3 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
/////////////////////////---FUNCTIONS---///////////////////////////// /////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_INPUTREGS_H_ #endif //__MODBUS_INPUTREGS_H_
/** MODBUS_HOLD
* @}
*/

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_MASTER Modbus master funtions @addtogroup MODBUS_MASTER Modbus master funtions
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS @ingroup MODBUS_CMD_PROCESS_FUNCTIONS
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль реализации обработки UART сообщение в режиме мастер Модуль реализации обработки UART сообщение в режиме мастер
@@ -24,7 +23,7 @@
* @ingroup MODBUS_FUNCTIONS * @ingroup MODBUS_FUNCTIONS
* @brief Макросы для создания запросов в режиме мастер * @brief Макросы для создания запросов в режиме мастер
* @details Примеры использования: * @details Примеры использования:
* * @code
* // Чтение 10 holding registers начиная с адреса 0 * // Чтение 10 holding registers начиная с адреса 0
* RS_MsgTypeDef read_msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10); * RS_MsgTypeDef read_msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
* *
@@ -36,6 +35,8 @@
* *
* // Идентификация устройства * // Идентификация устройства
* RS_MsgTypeDef dev_id_msg = MB_REQUEST_READ_DEVICE_ID_BASIC(1); * RS_MsgTypeDef dev_id_msg = MB_REQUEST_READ_DEVICE_ID_BASIC(1);
* @endcode
* @{
*/ */
//---------КЛАССИЧЕСКИЕ ДАННЫЕ----------- //---------КЛАССИЧЕСКИЕ ДАННЫЕ-----------
@@ -83,7 +84,7 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
* @code * @code
* // Пример: Запросили 10 регистров с адреса 100, хотим получить значение регистра 105 * // Пример: Запросили 10 регистров с адреса 100, хотим получить значение регистра 105
* uint16_t reg_value; * uint16_t reg_value;
* if(MB_GetRegisterValue(&MODBUS_MSG, 105, &reg_value)) * if(MB_RespGet_RegisterValue(&MODBUS_MSG, 105, &reg_value))
* { * {
* printf("Register 105 value: %d\n", reg_value); * printf("Register 105 value: %d\n", reg_value);
* } * }
@@ -92,30 +93,34 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
* 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;
* if(MB_GetRegisterValue(&MODBUS_MSG, addr, &value)) * if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
* { * {
* printf("Register %d: %d\n", addr, value); * printf("Register %d: %d\n", addr, value);
* } * }
* } * }
* @endcode * @endcode
* @{
*/ */
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value); int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value);
/** MODBUS_REQ_REGS_API /** MODBUS_REQ_REGS_API
* @} * @}
*/ */
/**
* @addtogroup MODBUS_MASTER
* @{
*/
/* Сбор сообщения в буфер UART в режиме мастер (фрейм мастера из msg -> uart) */ /* Сбор сообщения в буфер UART в режиме мастер (фрейм мастера из msg -> uart) */
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff); RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
/* Парс сообщения в режиме мастер (фрейм слейва из uart -> msg) */ /* Парс сообщения в режиме мастер (фрейм слейва из uart -> msg) */
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff); RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
#endif //__MODBUS_MASTER_H_
/** MODBUS_MASTER /** MODBUS_MASTER
* @} * @}
*/ */
#endif //__MODBUS_MASTER_H_

View File

@@ -5,7 +5,6 @@
****************************************************************************** ******************************************************************************
@addtogroup MODBUS_SLAVE Modbus slave funtions @addtogroup MODBUS_SLAVE Modbus slave funtions
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS @ingroup MODBUS_CMD_PROCESS_FUNCTIONS
@{
****************************************************************************** ******************************************************************************
* @details * @details
Модуль реализации обработки UART сообщение в режиме слейв Модуль реализации обработки UART сообщение в режиме слейв
@@ -19,6 +18,10 @@
#ifdef MODBUS_ENABLE_SLAVE #ifdef MODBUS_ENABLE_SLAVE
#define MODBUS_MODE_SLAVE 0 #define MODBUS_MODE_SLAVE 0
#endif #endif
/**
* @addtogroup MODBUS_SLAVE
* @{
*/
/* Ответ на сообщение в режиме слейва */ /* Ответ на сообщение в режиме слейва */
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg); RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg);
@@ -27,8 +30,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
/* Парс сообщения в режиме слейв (фрейм мастера из uart -> msg) */ /* Парс сообщения в режиме слейв (фрейм мастера из uart -> msg) */
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff); RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
#endif //__MODBUS_SLAVE_H_ /** MODBUS_SLAVE
/** MODBUS_MASTER
* @} * @}
*/ */
#endif //__MODBUS_SLAVE_H_

View File

@@ -11,19 +11,19 @@
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom) Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
через UART в режиме прерываний с поддержкой таймаутов. через UART в режиме прерываний с поддержкой таймаутов.
@section Основные возможности: @section Основные возможности:
- Прием/передача в прерываниях - Прием/передача в прерываниях
- Обработка IDLE линии для определения конца фрейма - Обработка IDLE линии для определения конца фрейма
- Таймауты приема через TIM - Таймауты приема через TIM
- Гибкая настройка размера сообщений - Гибкая настройка размера сообщений
@section Использование: @section Использование:
1. Определить структуру сообщения и размеры буфера 1. Определить структуру сообщения и размеры буфера
2. Реализовать weak-функции обработки сообщений 2. Реализовать weak-функции обработки сообщений
3. Добавить вызовы RS_UART_Handler/RS_TIM_Handler в прерывания 3. Добавить вызовы RS_UART_Handler/RS_TIM_Handler в прерывания
4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT() 4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT()
@section Особенности: @section Особенности:
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи - Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
- Состояния: отслеживается через флаги в RS_HandleTypeDef - Состояния: отслеживается через флаги в RS_HandleTypeDef
- Таймауты: контролируют максимальное время ожидания фрейма - Таймауты: контролируют максимальное время ожидания фрейма

View File

@@ -1,6 +1,6 @@
# Инструкция по подключению релиза библиотеки `STM Modbus` # Инструкция по подключению релиза библиотеки `STM Modbus`
Данная библиотека подключается напрямую из Git, как субмодуль. Позволяя при желании обновлять её напрямую через pull. Данная библиотека подключается напрямую из Git, как субмодуль. Позволяя при желании обновлять её напрямую через git.
## Структура библиотеки ## Структура библиотеки
@@ -136,7 +136,7 @@ ProjectRoot/
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_... Чтобы достать нужные данные из ответа
} }
} }
``` ```
@@ -188,6 +188,8 @@ ProjectRoot/
3.6. Доступ к данным в коде 3.6. Доступ к данным в коде
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
```c ```c
// Чтение входных регистров // Чтение входных регистров
uint16_t temp = MB_DATA.InRegs.Temperature; uint16_t temp = MB_DATA.InRegs.Temperature;
@@ -205,6 +207,42 @@ ProjectRoot/
} }
``` ```
В режиме мастера есть функции для получения информации из ответа `MB_RespGet_...()`
```c
// Чтение регистров: Получить запрошенные регистры
uint16_t value;
if(MB_RespGet_RegisterValue(&MODBUS_MSG, 105, &reg_value))
{
printf("Register 105 value: %d\n", reg_value);
}
// Чтение коилов: Получить запрошенные коилы
int state;
if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
{
printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
}
// Чтение диагностики: Получить запрошенныую диагностику
uint16_t counter_value;
if(MB_RespGet_DiagnosticResponse(&MODBUS_MSG, &counter_value))
{
printf("Counter value: %d\n", counter_value);
}
// Чтение идентификаторов: Получить запрошенные идентификаторы
uint8_t length;
char vendor_name[64];
if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
{
printf("Vendor Name: %s (length: %d)\n", vendor_name, length);
}
uint8_t obj_id, obj_length;
char obj_data[64];
if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, 0x00, &obj_id, obj_data, &obj_length))
{
printf("First object - ID: 0x%02X, Data: %s\n", obj_id, obj_data);
}
```
5. **Обновление библиотеки**: 5. **Обновление библиотеки**:

View File

@@ -6,7 +6,7 @@
* @details * @details
Файл содержит реализацию функций работы с Modbus. Файл содержит реализацию функций работы с Modbus.
@section Функции и макросы @section Функции и макросы
### Инициализация: ### Инициализация:
- MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM) - MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM)

View File

@@ -23,7 +23,7 @@
* @details Позволяет обратиться к любому коилу по его глобальному адрессу. * @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти. Вне зависимости от того как коилы размещены в памяти.
*/ */
MB_ExceptionTypeDef MB_Write_Coil_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 = NO_ERRORS;
@@ -63,7 +63,7 @@ MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteV
* @details Позволяет обратиться к любому коилу по его глобальному адрессу. * @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти. Вне зависимости от того как коилы размещены в памяти.
*/ */
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{ {
//---------CHECK FOR ERRORS---------- //---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp; MB_ExceptionTypeDef Exception_tmp;
@@ -94,11 +94,17 @@ uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF) * @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса * @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
*/ */
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
{ {
if(modbus_msg == NULL || coil_state == NULL) if(modbus_msg == NULL || coil_state == NULL)
return 0; return 0;
// Проверяем что ответ связан с коилами
if(modbus_msg->Func_Code != MB_R_COILS)
{
return 0;
}
// Проверяем что coil_addr в пределах запрошенного диапазона // Проверяем что coil_addr в пределах запрошенного диапазона
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt) if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0; return 0;
@@ -108,15 +114,19 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
// Вычисляем байт и бит // Вычисляем байт и бит
uint8_t byte_index = coil_index / 8; uint8_t byte_index = coil_index / 8;
uint8_t bit_index = coil_index % 8; uint8_t data_index = coil_index / 16;
uint8_t bit_index = coil_index % 16;
// Проверяем что байт существует в данных // Проверяем что байт существует в данных
if(byte_index >= modbus_msg->ByteCnt) if(byte_index >= modbus_msg->ByteCnt)
return 0; return 0;
// Получаем байт и проверяем бит // Получаем байт и проверяем бит
uint8_t coil_byte = modbus_msg->DATA[byte_index] & 0xFF; if(bit_index < 8)
*coil_state = (coil_byte >> bit_index) & 0x01; *coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
else
*coil_state = (modbus_msg->DATA[data_index] >> bit_index) & 0x01;
return 1; return 1;
} }
@@ -211,7 +221,7 @@ uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
* @return fMessageHandled Статус о результате обработки комманды. * @return fMessageHandled Статус о результате обработки комманды.
* @details Обработка команды Write Multiple Coils. * @details Обработка команды Write Multiple Coils.
*/ */
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) 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))
@@ -274,11 +284,11 @@ uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
#else //MODBUS_ENABLE_COILS #else //MODBUS_ENABLE_COILS
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;} int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
MB_ExceptionTypeDef MB_Write_Coil_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_Read_Coil_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;}
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg) {return 0;} uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;} uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
#endif #endif

View File

@@ -9,7 +9,7 @@
- Поддержка потоковой передачи при большом количестве объектов - Поддержка потоковой передачи при большом количестве объектов
- Автоматический расчет MoreFollows флагов - Автоматический расчет MoreFollows флагов
@section Потоковая передача: @section Потоковая передача:
При большом количестве объектов идентификация разбивается на несколько При большом количестве объектов идентификация разбивается на несколько
сообщений с установкой флага MoreFollows и указанием NextObjId для сообщений с установкой флага MoreFollows и указанием NextObjId для
продолжения чтения в следующем запросе. продолжения чтения в следующем запросе.
@@ -26,8 +26,18 @@ MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная струк
* @param modbus_msg Указатель на структуру сообщения * @param modbus_msg Указатель на структуру сообщения
* @return int Количество объектов * @return int Количество объектов
*/ */
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg) 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; return modbus_msg->DevId.NumbOfObj;
} }
@@ -39,11 +49,17 @@ int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg)
* @param obj_length Указатель для длины объекта * @param obj_length Указатель для длины объекта
* @return int Найден ли объект (1 - да, 0 - нет) * @return int Найден ли объект (1 - да, 0 - нет)
*/ */
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) 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)) if((modbus_msg == NULL) || (obj_data == NULL))
return 0; return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
uint8_t *data = (uint8_t*)modbus_msg->DATA; uint8_t *data = (uint8_t*)modbus_msg->DATA;
unsigned ind = 0; unsigned ind = 0;
@@ -84,11 +100,17 @@ int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data,
* @param obj_length Указатель для длины объекта * @param obj_length Указатель для длины объекта
* @return int Успешность получения (1 - получен, 0 - не найден) * @return int Успешность получения (1 - получен, 0 - не найден)
*/ */
int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, 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)
{ {
if((modbus_msg == NULL) || (obj_data == NULL)) if((modbus_msg == NULL) || (obj_data == NULL))
return 0; return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
if(index >= modbus_msg->DevId.NumbOfObj) if(index >= modbus_msg->DevId.NumbOfObj)
return 0; return 0;
@@ -652,9 +674,9 @@ void MB_DeviceInentificationInit(void)
#else //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS #else //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
/* Получить количество объектов в сообщении */ /* Получить количество объектов в сообщении */
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;} int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {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_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, 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;}

View File

@@ -42,11 +42,19 @@ void MB_DiagnosticsInit(void)
* @param data Указатель куда положить данные * @param data Указатель куда положить данные
* @return 1 - успех, 0 - ошибка * @return 1 - успех, 0 - ошибка
*/ */
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data) int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
{ {
if(modbus_msg == NULL || data == NULL) if(modbus_msg == NULL || data == NULL)
return 0; return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
{
return 0;
}
*data = modbus_msg->DATA[1]; *data = modbus_msg->DATA[1];
return 1; return 1;
} }
@@ -311,7 +319,7 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
#else //MODBUS_ENABLE_DIAGNOSTICS #else //MODBUS_ENABLE_DIAGNOSTICS
void MB_DiagnosticsInit(void) {} void MB_DiagnosticsInit(void) {}
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;} 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;}

View File

@@ -9,12 +9,12 @@
- Запись одиночного регистра (0x06) - прямая запись значения - Запись одиночного регистра (0x06) - прямая запись значения
- Запись множественных регистров (0x10) - пакетная запись из буфера - Запись множественных регистров (0x10) - пакетная запись из буфера
@section Валидация данных: @section Валидация данных:
- Проверка соответствия количества байт и регистров - Проверка соответствия количества байт и регистров
Валидация адресов через MB_DefineRegistersAddress() Валидация адресов через MB_DefineRegistersAddress()
- Обработка исключений при некорректных запросах - Обработка исключений при некорректных запросах
@section Echo-ответы: @section Echo-ответы:
При успешной записи формируется echo-ответ с теми же данными, При успешной записи формируется echo-ответ с теми же данными,
что были в запросе (для функций 0x05, 0x06, 0x0F, 0x10). что были в запросе (для функций 0x05, 0x06, 0x0F, 0x10).
******************************************************************************/ ******************************************************************************/

View File

@@ -6,7 +6,7 @@
* @details * @details
Файл содержит реализацию функций для работы Modbus в режиме мастера. Файл содержит реализацию функций для работы Modbus в режиме мастера.
@section Функции и макросы @section Функции и макросы
- MB_Master_Collect_Message() — Сбор сообщения в режиме мастера - MB_Master_Collect_Message() — Сбор сообщения в режиме мастера
- MB_Master_Parse_Message() — Парс сообщения в режиме мастера - MB_Master_Parse_Message() — Парс сообщения в режиме мастера
@@ -23,11 +23,19 @@
* @param reg_value Указатель для значения регистра * @param reg_value Указатель для значения регистра
* @return 1 - успех, 0 - ошибка или reg_addr вне диапазона запроса * @return 1 - успех, 0 - ошибка или reg_addr вне диапазона запроса
*/ */
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value)
{ {
if(modbus_msg == NULL || reg_value == NULL) if(modbus_msg == NULL || reg_value == NULL)
return 0; return 0;
// Проверяем что ответ связан с регистрами
if((modbus_msg->Func_Code != MB_R_DISC_IN) &&
(modbus_msg->Func_Code != MB_R_HOLD_REGS) &&
(modbus_msg->Func_Code != MB_R_IN_REGS))
{
return 0;
}
// Проверяем что reg_addr в пределах запрошенного диапазона // Проверяем что reg_addr в пределах запрошенного диапазона
if(reg_addr < modbus_msg->Addr || reg_addr >= modbus_msg->Addr + modbus_msg->Qnt) if(reg_addr < modbus_msg->Addr || reg_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0; return 0;
@@ -302,173 +310,173 @@ 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, MB_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, MB_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, MB_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, MB_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, MB_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, MB_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, MB_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 DATA 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.DATA[i] = coils_data[i];
}
} }
}
return msg; return msg;
} }
/** @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, MB_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 DATA 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.DATA[i] = regs_data[i];
} }
return msg; return msg;
} }
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ----------- //---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
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, MB_R_DIAGNOSTIC, {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)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0000, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0000, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data) RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0001, data); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0001, data);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0002, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0002, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0004, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0004, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000A, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000A, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000B, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000B, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000C, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000C, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000D, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000D, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000E, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000E, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000F, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000F, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0010, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0010, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0011, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0011, 0x0000);
} }
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr) RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr)
{ {
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0012, 0x0000); return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0012, 0x0000);
} }
//---------ИДЕНТИФИКАТОРЫ МОДБАС----------- //---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
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, MB_R_DEVICE_INFO, {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, MB_R_DEVICE_INFO, {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, MB_R_DEVICE_INFO, {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, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg; return msg;
} }
@@ -478,7 +486,7 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
#else #else
RS_MsgTypeDef msg_dummy = {0}; RS_MsgTypeDef msg_dummy = {0};
int MB_GetRegisterValue(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;}
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;}

View File

@@ -6,7 +6,7 @@
* @details * @details
Файл содержит реализацию функций для работы Modbus в режиме слейва. Файл содержит реализацию функций для работы Modbus в режиме слейва.
@section Функции и макросы @section Функции и макросы
- MB_Slave_Response() — Ответ на запрос - MB_Slave_Response() — Ответ на запрос
- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва. - MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
@@ -78,7 +78,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
// Write Multiple Coils // Write Multiple Coils
case MB_W_COILS: case MB_W_COILS:
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr); hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled) if(hmodbus->f.MessageHandled)
{ {
hmodbus->f.DataUpdated = 1; hmodbus->f.DataUpdated = 1;

View File

@@ -10,7 +10,7 @@
- Таймаутов через таймер - Таймаутов через таймер
- Двухстадийного приема (заголовок + данные) - Двухстадийного приема (заголовок + данные)
@section Архитектура: @section Архитектура:
В режиме слейв: В режиме слейв:
- Инициализация приема с сообщения с максимальным размером MSG_SIZE_MAX - Инициализация приема с сообщения с максимальным размером MSG_SIZE_MAX
- При срабатывании прерывания IDLE - обработка полученного сообщения - При срабатывании прерывания IDLE - обработка полученного сообщения
@@ -18,7 +18,7 @@
- Отправка запроса и переход в режим приема сообщения с максимальным размером MSG_SIZE_MAX - Отправка запроса и переход в режим приема сообщения с максимальным размером MSG_SIZE_MAX
- При срабатывании прерывания IDLE - обработка полученного ответа - При срабатывании прерывания IDLE - обработка полученного ответа
@section Необходимые обработчики: @section Необходимые обработчики:
- RS_UART_Handler() в UARTx_IRQHandler вместо HAL_UART_IRQHandler() - RS_UART_Handler() в UARTx_IRQHandler вместо HAL_UART_IRQHandler()
- RS_TIM_Handler() в TIMx_IRQHandler вместо HAL_TIM_IRQHandler() - RS_TIM_Handler() в TIMx_IRQHandler вместо HAL_TIM_IRQHandler()
******************************************************************************/ ******************************************************************************/

View File

@@ -19,8 +19,8 @@
#include "stm32f1xx_hal.h" #include "stm32f1xx_hal.h"
// Общие параметры // Общие параметры
#define MODBUS_DEVICE_ID 1 ///< девайс текущего устройства #define MODBUS_DEVICE_ID 1 ///< Адрес устройства в сети Modbus
#define MODBUS_TIMEOUT 5000 ///< максимальнйы тайтаут MB в тиках таймера #define MODBUS_TIMEOUT 5000 ///< Таймаут в тиках таймера
// Строковые идентификаторы устройства // Строковые идентификаторы устройства
#define MODBUS_VENDOR_NAME "NIO-12" #define MODBUS_VENDOR_NAME "NIO-12"
@@ -34,19 +34,19 @@
// Периферия (опционально) // Периферия (опционально)
#define mb_huart huart1 ///< Удобный дефайн для модбасовского uart #define mb_huart huart1 ///< Удобный дефайн для модбасовского uart
#define mb_htim htim2 ///< Удобный дефайн для модбасовского таймера #define mb_htim htim3 ///< Удобный дефайн для модбасовского таймера
//#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485 //#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
//#define RS_EnableTransmit() ///< Функция изменения направления передачи на ПЕРЕДАЧУ для RS-485 //#define RS_EnableTransmit() ///< Функция изменения направления передачи на ПЕРЕДАЧУ для RS-485
// Модули modbus // Модули modbus
#define MODBUS_ENABLE_SLAVE ///< Включить обработку МАСТЕР режима #define MODBUS_ENABLE_SLAVE ///< Включить обработку СЛЕЙВ режима
//#define MODBUS_ENABLE_MASTER ///< Включить обработку СЛЕЙВ режима #define MODBUS_ENABLE_MASTER ///< Включить обработку МАСТЕР режима
#define MODBUS_ENABLE_COILS ///< Включить обработку коилов #define MODBUS_ENABLE_COILS ///< Включить обработку коилов
#define MODBUS_ENABLE_HOLDINGS ///< Включить обработку регистров хранения #define MODBUS_ENABLE_HOLDINGS ///< Включить обработку регистров хранения
#define MODBUS_ENABLE_INPUTS ///< Включить обработку входных регистров #define MODBUS_ENABLE_INPUTS ///< Включить обработку входных регистров
#define MODBUS_ENABLE_DEVICE_IDENTIFICATORS ///< Включить обработку идентификаторы устройства #define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас #define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас

View File

@@ -23,7 +23,6 @@
#include "modbus_devid.h" #include "modbus_devid.h"
/** /**
* @brief Check is address valid for certain array. * @brief Check is address valid for certain array.
* @param Addr Начальный адресс. * @param Addr Начальный адресс.