Коррекции по синтаксису и doxygen
This commit is contained in:
@@ -1,15 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @file __modbus_compat.h
|
* @file __modbus_compat.h
|
||||||
* @brief Модуль для совместимости библиотеки MODBUS.
|
* @brief Модуль для совместимости библиотеки MODBUS.
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
||||||
*************************************************************************/
|
******************************************************************************/
|
||||||
#include "modbus.h"
|
#include "modbus_core.h"
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup MODBUS_LEGACY_API Legacy API
|
/** @addtogroup MODBUS_LEGACY_API Legacy API
|
||||||
* @ingroup MODBUS_FUNCTIONS
|
* @ingroup MODBUS_FUNCTIONS
|
||||||
|
* @brief Старые API функций, сохранённые для обратной совместимости.
|
||||||
|
* @note Не используйте эти функции в новом коде. Они могут быть удалены в будущих версиях.
|
||||||
|
* Вместо них используйте функции из основных групп MODBUS API.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
30
Inc/modbus.h
30
Inc/modbus.h
@@ -1,20 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus.h
|
* @file modbus.h
|
||||||
* @brief Главный заголовочный файл Modbus библиотеки
|
* @brief Главный заголовочный файл Modbus библиотеки
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS Modbus tools
|
@addtogroup MODBUS Modbus tools
|
||||||
******************************************************************************
|
@brief Библиотека реализующая протокол Modbus
|
||||||
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_FUNCTIONS Main API for Modbus Library
|
@addtogroup MODBUS_FUNCTIONS Main API for Modbus Library
|
||||||
@ingroup MODBUS
|
@ingroup MODBUS
|
||||||
|
@brief Публичные функции библиотеки
|
||||||
@{
|
@{
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Объединяющий файл для подключения всей функциональности Modbus.
|
Объединяющий файл для подключения всей функциональности Modbus.
|
||||||
Подключает все необходимые модули:
|
Подключает все необходимые модули:
|
||||||
|
|
||||||
|
|
||||||
@section init Инструкция по подключению
|
@section Start Инструкция по подключению
|
||||||
Для корректной работы надо:
|
Для корректной работы надо:
|
||||||
- Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие
|
- Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие
|
||||||
низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика
|
низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика
|
||||||
@@ -23,20 +25,20 @@
|
|||||||
|
|
||||||
- Инициализировать хендл мобдас. По умолчанию глобально создается hmodbus1
|
- Инициализировать хендл мобдас. По умолчанию глобально создается hmodbus1
|
||||||
- После для запуска Modbus:
|
- После для запуска Modbus:
|
||||||
@verbatim
|
@code
|
||||||
//----------------Слейв модбас----------------//
|
//----------------Слейв модбас----------------//
|
||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|
||||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||||
@endverbatim
|
@endcode
|
||||||
@verbatim
|
@code
|
||||||
//----------------Мастер модбас----------------//
|
//----------------Мастер модбас----------------//
|
||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|
||||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||||
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER);
|
MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
|
||||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||||
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
||||||
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
||||||
@@ -56,10 +58,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@endverbatim
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@section Подключаемые модули:
|
@section modules Подключаемые модули:
|
||||||
- rs_message.h - работа с uart
|
- rs_message.h - работа с uart
|
||||||
- modbus_core.h - базовые определения
|
- modbus_core.h - базовые определения
|
||||||
- modbus_coils.h - работа с дискретными выходами
|
- modbus_coils.h - работа с дискретными выходами
|
||||||
@@ -69,7 +71,7 @@
|
|||||||
- modbus_diag.h - диагностика modbus
|
- modbus_diag.h - диагностика modbus
|
||||||
|
|
||||||
|
|
||||||
@section Структура данных Modbus
|
@section data Структура данных Modbus
|
||||||
|
|
||||||
#### Holding/Input Registers:
|
#### Holding/Input Registers:
|
||||||
- Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.
|
- Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.
|
||||||
@@ -108,11 +110,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef MODBUS_ENABLE_MASTER
|
#ifdef MODBUS_ENABLE_MASTER
|
||||||
#define MODBUS_MODE_MASTER 1
|
#define MODBUS_MODE_MASTER 1 ///< Псевдо-enum: Режим мастер
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODBUS_ENABLE_SLAVE
|
#ifdef MODBUS_ENABLE_SLAVE
|
||||||
#define MODBUS_MODE_SLAVE 0
|
#define MODBUS_MODE_SLAVE 0 ///< Псевдо-enum: Режим слейв
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -1,23 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_coils.h
|
* @file modbus_coils.h
|
||||||
* @brief Работа с коилами Modbus
|
* @brief Работа с коилами Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_COILS Coils Tools
|
@addtogroup MODBUS_COILS Coils Tools
|
||||||
@ingroup MODBUS_INTERNAL
|
@ingroup MODBUS_INTERNAL
|
||||||
******************************************************************************
|
@brief Функции для работы с коилами
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к coils внутри программы:
|
||||||
|
- Функции для доступа к coils по глобальным адресам
|
||||||
|
- Макросы для доступа к coils по локальным адресам
|
||||||
|
|
||||||
Модуль предоставляет функции и макросы для работы с битовыми данными:
|
Модуль предоставляет функции и макросы для работы с битовыми данными:
|
||||||
- Чтение coils (0x01) Упаковка битов в байты
|
- Чтение coils (0x01) Упаковка битов в байты
|
||||||
- Запись одиночного coil (0x05) Установка/сброс бита
|
- Запись одиночного coil (0x05) Установка/сброс бита
|
||||||
- Запись множественных coils (0x0F) - распаковка байтов в биты
|
- Запись множественных coils (0x0F) - распаковка байтов в биты
|
||||||
- Макросы для локального доступа к coils
|
|
||||||
|
|
||||||
@section Организация битовых данных:
|
@section cbits Организация битовых данных:
|
||||||
Coils упакованы в 16-битные слова для эффективного использования памяти.
|
Coils упакованы в 16-битные слова для эффективного использования памяти.
|
||||||
Биты нумеруются от младшего к старшему внутри каждого слова.
|
Биты нумеруются от младшего к старшему внутри каждого слова.
|
||||||
|
|
||||||
@section Адресация:
|
@section caddr Адресация:
|
||||||
- Глобальная - абсолютный адрес в пространстве Modbus
|
- Глобальная - абсолютный адрес в пространстве Modbus
|
||||||
- Локальная - относительный адрес внутри массива coils
|
- Локальная - относительный адрес внутри массива coils
|
||||||
- Макросы автоматически вычисляют смещения и маски
|
- Макросы автоматически вычисляют смещения и маски
|
||||||
@@ -44,7 +48,7 @@ Coils упакованы в 16-битные слова для эффективн
|
|||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
|
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
|
||||||
* @ingroup MODBUS_FUNCTIONS
|
* @ingroup MODBUS_FUNCTIONS
|
||||||
* @brief Функции для доступа к данным модбас
|
* @brief API для доступа к данным модбас внутри программы
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -101,7 +105,7 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Обработать функцию Read Coils (01 - 0x01) */
|
/* Обработать функцию Read Coils (01 - 0x01) */
|
||||||
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg);
|
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg);
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_core.h
|
* @file modbus_core.h
|
||||||
* @brief Ядро Modbus протокола - определения и структуры
|
* @brief Ядро Modbus протокола - определения и структуры
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_INTERNAL Modbus Internal Tools
|
@addtogroup MODBUS_INTERNAL Modbus Internal Tools
|
||||||
@ingroup MODBUS
|
@ingroup MODBUS
|
||||||
|
@brief Внутренние штуки библиотеки
|
||||||
@{
|
@{
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Базовые определения для реализации Modbus RTU устройства:
|
Базовые определения для реализации Modbus RTU устройства:
|
||||||
- Структуры сообщений Modbus
|
- Структуры сообщений Modbus
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
Константы размеров полей
|
Константы размеров полей
|
||||||
Вспомогательные макросы
|
Вспомогательные макросы
|
||||||
|
|
||||||
@section Структура сообщения:
|
@section msg Структура сообщения:
|
||||||
[ADDR][FUNC][DATA...][CRC]
|
[ADDR][FUNC][DATA...][CRC]
|
||||||
- Адрес: 1 байт
|
- Адрес: 1 байт
|
||||||
- Функция: 1 байт
|
- Функция: 1 байт
|
||||||
@@ -28,12 +29,13 @@
|
|||||||
#include "modbus_config.h"
|
#include "modbus_config.h"
|
||||||
#include "modbus_data.h"
|
#include "modbus_data.h"
|
||||||
#include "__crc_algs.h"
|
#include "__crc_algs.h"
|
||||||
|
#include "__modbus_compat.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_MESSAGE_DEFINES Modbus Message Tools
|
* @addtogroup MODBUS_MESSAGE_DEFINES Modbus Message Tools
|
||||||
* @ingroup MODBUS
|
* @ingroup MODBUS
|
||||||
* @brief Определения протокола модбас
|
* @brief Определения протокола модбас
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -93,7 +95,7 @@ typedef enum //MB_FunctonTypeDef
|
|||||||
/* COMMANDS */
|
/* COMMANDS */
|
||||||
// reading
|
// reading
|
||||||
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
|
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||||
//FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||||
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||||
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||||
@@ -114,7 +116,7 @@ typedef enum //MB_FunctonTypeDef
|
|||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
// error reading
|
// error reading
|
||||||
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||||
//FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||||
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||||
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||||
|
|
||||||
@@ -124,8 +126,8 @@ typedef enum //MB_FunctonTypeDef
|
|||||||
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||||
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||||
|
|
||||||
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||||
MB_FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||||
}MB_FunctonTypeDef;
|
}MB_FunctonTypeDef;
|
||||||
|
|
||||||
/** @brief Enum for MEI func codes */
|
/** @brief Enum for MEI func codes */
|
||||||
@@ -217,7 +219,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
* @param _parr_ - массив коилов.
|
* @param _parr_ - массив коилов.
|
||||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||||
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
||||||
@verbatim Пояснение выражений
|
@code Пояснение выражений
|
||||||
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
|
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
|
||||||
|
|
||||||
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
|
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
|
||||||
@@ -225,14 +227,14 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
|register[0]----| |register[1]----|
|
|register[0]----| |register[1]----|
|
||||||
|skip this------| |get this-------|
|
|skip this------| |get this-------|
|
||||||
|shift to 14 bit|
|
|shift to 14 bit|
|
||||||
@endverbatim
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
||||||
/**
|
/**
|
||||||
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
|
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
|
||||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||||
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
||||||
@verbatim Пояснение выражений
|
@code Пояснение выражений
|
||||||
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
|
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
|
||||||
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
|
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
|
||||||
|
|
||||||
@@ -244,7 +246,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
|register[0]----| |register[1]----|
|
|register[0]----| |register[1]----|
|
||||||
|skip this------| |get this-------|
|
|skip this------| |get this-------|
|
||||||
|shift to 14 bit|
|
|shift to 14 bit|
|
||||||
@endverbatim
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
||||||
|
|
||||||
@@ -289,7 +291,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Реализация этих функций лежит в modbus_data.c */
|
/* Реализация этих функций лежит в modbus_data.c */
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_devid.h
|
* @file modbus_devid.h
|
||||||
* @brief Идентификаторы устройства Modbus
|
* @brief Идентификаторы устройства Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_DEVID Device Identifications Tools
|
@addtogroup MODBUS_DEVID Device Identifications Tools
|
||||||
@ingroup MODBUS_INTERNAL
|
@ingroup MODBUS_INTERNAL
|
||||||
******************************************************************************
|
@brief Функции для работы с идентификаторами устройства
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль реализации функции Read Device Identifications (0x2B):
|
Модуль реализации функции Read Device Identifications (0x2B):
|
||||||
- Базовая идентификация (Vendor, Product, Revision)
|
- Базовая идентификация (Vendor, Product, Revision)
|
||||||
- Расширенная идентификация (URL, Model, User fields)
|
- Расширенная идентификация (URL, Model, User fields)
|
||||||
- Поддержка потоковой передачи больших объектов
|
- Поддержка потоковой передачи больших объектов
|
||||||
|
|
||||||
@section Объекты идентификации:
|
@section devobj Объекты идентификации:
|
||||||
- VendorName, ProductCode, Revision - обязательные
|
- VendorName, ProductCode, Revision - обязательные
|
||||||
- VendorUrl, ProductName, ModelName - опциональные
|
- VendorUrl, ProductName, ModelName - опциональные
|
||||||
- User objects - пользовательские поля
|
- User objects - пользовательские поля
|
||||||
@@ -108,7 +109,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Обработать функцию Read Device Identifications (43/14 - 0x2B/0E) */
|
/* Обработать функцию Read Device Identifications (43/14 - 0x2B/0E) */
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_diag.h
|
* @file modbus_diag.h
|
||||||
* @brief Диагностика устройства Modbus
|
* @brief Диагностика устройства Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_DIAG Diagnostics Tools
|
@addtogroup MODBUS_DIAG Diagnostics Tools
|
||||||
@ingroup MODBUS_INTERNAL
|
@ingroup MODBUS_INTERNAL
|
||||||
******************************************************************************
|
@brief Функции для работы с диагностикой
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль реализации Diagnostics (Serial Line only) (0x08):
|
Модуль реализации Diagnostics (Serial Line only) (0x08):
|
||||||
- Полная поддержка всех подфункций диагностики
|
- Полная поддержка всех подфункций диагностики
|
||||||
- Возможность выставить/сбросить любой бит в диагностическом регистре
|
- Возможность выставить/сбросить любой бит в диагностическом регистре
|
||||||
- Сбор статистики работы устройства
|
- Сбор статистики работы устройства
|
||||||
- Управление режимами работы
|
- Управление режимами работы
|
||||||
****************************************** ************************************/
|
******************************************************************************/
|
||||||
#ifndef __MODBUS_DIAG_H_
|
#ifndef __MODBUS_DIAG_H_
|
||||||
#define __MODBUS_DIAG_H_
|
#define __MODBUS_DIAG_H_
|
||||||
#include "modbus_core.h"
|
#include "modbus_core.h"
|
||||||
@@ -100,7 +101,7 @@ void MB_Diagnostics_SlaveBusyCnt(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Обработка команды диагностики (0x08) */
|
/* Обработка команды диагностики (0x08) */
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_holdregs.h
|
* @file modbus_holdregs.h
|
||||||
* @brief Работа с регистрами хранения Modbus
|
* @brief Работа с регистрами хранения Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_INS Input Register Tools
|
@addtogroup MODBUS_INS Input Register Tools
|
||||||
@ingroup MODBUS_INTERNAL
|
@ingroup MODBUS_INTERNAL
|
||||||
******************************************************************************
|
@brief Функции для работы с входными регистрами
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к регистрам внутри программы:
|
||||||
|
- Функции для доступа к регистрам хранения по глобальным адресам
|
||||||
|
|
||||||
Модуль обработки команд для регистров хранения (Holding Registers):
|
Модуль обработки команд для регистров хранения (Holding Registers):
|
||||||
- Чтение множества регистров (0x03)
|
- Чтение множества регистров (0x03)
|
||||||
- Запись одиночного регистра (0x06)
|
- Запись одиночного регистра (0x06)
|
||||||
- Запись множества регистров (0x10)
|
- Запись множества регистров (0x10)
|
||||||
|
|
||||||
@section Регистры хранения:
|
@section hold Регистры хранения:
|
||||||
- Read/Write доступ
|
- Read/Write доступ
|
||||||
- 16-битные значения (uint16_t)
|
- 16-битные значения (uint16_t)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -41,7 +45,7 @@ uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Обработать функцию Read Holding Registers (03 - 0x03) */
|
/* Обработать функцию Read Holding Registers (03 - 0x03) */
|
||||||
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
|
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_inputregs.h
|
* @file modbus_inputregs.h
|
||||||
* @brief Работа с входными регистрами Modbus
|
* @brief Работа с входными регистрами Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_HOLD Holding Registers Tools
|
@addtogroup MODBUS_HOLD Holding Registers Tools
|
||||||
@ingroup MODBUS_INTERNAL
|
@ingroup MODBUS_INTERNAL
|
||||||
******************************************************************************
|
@brief Функции для работы с регистрами хранения
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к регистрам внутри программы:
|
||||||
|
- Функции для доступа к входным регистрам по глобальным адресам
|
||||||
|
|
||||||
Модуль обработки команд для входных регистров (Input Registers):
|
Модуль обработки команд для входных регистров (Input Registers):
|
||||||
- Чтение множества регистров (0x04)
|
- Чтение множества регистров (0x04)
|
||||||
|
|
||||||
@section Входные регистры:
|
@section in Входные регистры:
|
||||||
- Read-Only доступ
|
- Read-Only доступ
|
||||||
- 16-битные значения
|
- 16-битные значения
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -40,7 +44,7 @@ uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
|
||||||
* @ingroup MODBUS_INTERNAL
|
* @ingroup MODBUS_INTERNAL
|
||||||
* @brief Функции обработки запросов модбас
|
* @brief Функции обработки запросов модбас
|
||||||
@{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Обработать функцию Read Input Registers (04 - 0x04) */
|
/* Обработать функцию Read Input Registers (04 - 0x04) */
|
||||||
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
|
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_master.h
|
* @file modbus_master.h
|
||||||
* @brief Главный заголовочный файл Modbus библиотеки
|
* @brief Главный заголовочный файл Modbus библиотеки
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_MASTER Modbus master funtions
|
@addtogroup MODBUS_MASTER Modbus master funtions
|
||||||
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
******************************************************************************
|
@brief Функции для работы в режиме Master
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль реализации обработки UART сообщение в режиме мастер
|
Модуль реализации Modbus в режиме мастер
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifndef __MODBUS_MASTER_H_
|
#ifndef __MODBUS_MASTER_H_
|
||||||
#define __MODBUS_MASTER_H_
|
#define __MODBUS_MASTER_H_
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
|
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
|
||||||
* @ingroup MODBUS_FUNCTIONS
|
* @ingroup MODBUS_FUNCTIONS
|
||||||
* @brief Макросы для создания запросов в режиме мастер
|
* @brief API для формирования фрейма-запроса в режиме мастер
|
||||||
* @details Примеры использования:
|
* @details Примеры использования:
|
||||||
* @code
|
* @code
|
||||||
* // Чтение 10 holding registers начиная с адреса 0
|
* // Чтение 10 holding registers начиная с адреса 0
|
||||||
@@ -80,24 +81,20 @@ 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_RespGet_RegisterValue(&MODBUS_MSG, 105, ®_value))
|
* if(MB_RespGet_RegisterValue(modbus_msg, 105, ®_value))
|
||||||
* {
|
* {
|
||||||
* printf("Register 105 value: %d\n", reg_value);
|
* printf("Register 105 value: %d\n", reg_value);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* // Пример: Получить все запрошенные регистры
|
* // Пример: Получить все запрошенные регистры
|
||||||
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
* uint16_t reg_value[125];
|
||||||
* {
|
* MB_RespGet_RegisterAll(modbus_msg)
|
||||||
* uint16_t value;
|
|
||||||
* if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
|
|
||||||
* {
|
|
||||||
* printf("Register %d: %d\n", addr, value);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @endcode
|
* @endcode
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
/* Получить значение ВСЕХ регистров в ответе */
|
||||||
|
int MB_RespGet_RegisterAll(RS_MsgTypeDef *modbus_msg, uint16_t *reg_arr);
|
||||||
|
/* Получить значение регистра в ответе по его адресу */
|
||||||
int MB_RespGet_RegisterValue(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);
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +112,7 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
* @code
|
* @code
|
||||||
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
|
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
|
||||||
* int coil_state;
|
* int coil_state;
|
||||||
* if(MB_RespGet_CoilState(&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");
|
||||||
* }
|
* }
|
||||||
@@ -124,7 +121,7 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
* 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_RespGet_CoilState(&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");
|
||||||
* }
|
* }
|
||||||
@@ -132,7 +129,9 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
* @endcode
|
* @endcode
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
/* Получить состояние ВСЕХ coil в ответе */
|
||||||
|
int MB_RespGet_CoilAll(RS_MsgTypeDef *modbus_msg, int *coil_arr);
|
||||||
|
/* Получить состояние coil в ответе по его адресу */
|
||||||
int MB_RespGet_CoilState(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
|
||||||
@@ -150,7 +149,7 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
|
|||||||
* // Пример 1: Получить VendorName (ID = 0x00)
|
* // Пример 1: Получить VendorName (ID = 0x00)
|
||||||
* uint8_t length;
|
* uint8_t length;
|
||||||
* char vendor_name[64];
|
* char vendor_name[64];
|
||||||
* if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
|
* if(MB_RespGet_ObjectById(modbus_msg, 0x00, vendor_name, &length))
|
||||||
* {
|
* {
|
||||||
* // получено
|
* // получено
|
||||||
* }
|
* }
|
||||||
@@ -159,12 +158,12 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
|
|||||||
* uint8_t obj_id, obj_length;
|
* uint8_t obj_id, obj_length;
|
||||||
* char obj_data[256];
|
* char obj_data[256];
|
||||||
*
|
*
|
||||||
* int obj_count = MB_RespGet_NumberOfObjects(&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_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
|
* if(MB_RespGet_ObjectByIndex(modbus_msg, i, &obj_id, obj_data, &obj_length))
|
||||||
* {
|
* {
|
||||||
* // получено
|
* // получено
|
||||||
* }
|
* }
|
||||||
@@ -196,7 +195,7 @@ int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_
|
|||||||
* @code
|
* @code
|
||||||
* // Получить данные диагностики (значение счетчика)
|
* // Получить данные диагностики (значение счетчика)
|
||||||
* uint16_t counter_value;
|
* uint16_t counter_value;
|
||||||
* if(MB_RespGet_Diagnostic(&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);
|
||||||
* }
|
* }
|
||||||
@@ -204,6 +203,7 @@ int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Получить */
|
||||||
int MB_RespGet_Diagnostic(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
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_slave.h
|
* @file modbus_slave.h
|
||||||
* @brief Главный заголовочный файл Modbus библиотеки
|
* @brief Главный заголовочный файл Modbus библиотеки
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@addtogroup MODBUS_SLAVE Modbus slave funtions
|
@addtogroup MODBUS_SLAVE Modbus slave funtions
|
||||||
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
******************************************************************************
|
@brief Функции для работы в режиме Slave
|
||||||
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль реализации обработки UART сообщение в режиме слейв
|
Модуль реализации Modbus в режиме слейв
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifndef __MODBUS_SLAVE_H_
|
#ifndef __MODBUS_SLAVE_H_
|
||||||
#define __MODBUS_SLAVE_H_
|
#define __MODBUS_SLAVE_H_
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file rs_message.h
|
* @file rs_message.h
|
||||||
* @brief Библиотека обмена сообщениями по RS-интерфейсу
|
* @brief Библиотека обмена сообщениями по RS-интерфейсу
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
@defgroup RS_TOOLS RS Tools
|
@defgroup RS_TOOLS RS Tools
|
||||||
@brief Всякое для работы по UART/RS
|
@brief Всякое для работы по UART/RS
|
||||||
@{
|
@{
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
|
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
|
||||||
через UART в режиме прерываний с поддержкой таймаутов.
|
через UART в режиме прерываний с поддержкой таймаутов.
|
||||||
|
|
||||||
@section Основные возможности:
|
@section posibility Основные возможности:
|
||||||
- Прием/передача в прерываниях
|
- Прием/передача в прерываниях
|
||||||
- Обработка IDLE линии для определения конца фрейма
|
- Обработка IDLE линии для определения конца фрейма
|
||||||
- Таймауты приема через TIM
|
- Таймауты приема через TIM
|
||||||
- Гибкая настройка размера сообщений
|
- Гибкая настройка размера сообщений
|
||||||
|
|
||||||
@section Использование:
|
@section usage Использование:
|
||||||
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 features Особенности:
|
||||||
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
|
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
|
||||||
- Состояния: отслеживается через флаги в RS_HandleTypeDef
|
- Состояния: отслеживается через флаги в RS_HandleTypeDef
|
||||||
- Таймауты: контролируют максимальное время ожидания фрейма
|
- Таймауты: контролируют максимальное время ожидания фрейма
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
/**
|
/**
|
||||||
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
|
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
|
||||||
* @ingroup RS_TOOLS
|
* @ingroup RS_TOOLS
|
||||||
|
* @brief Дефайны для отладки периферии
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
413
README.md
413
README.md
@@ -6,40 +6,40 @@
|
|||||||
|
|
||||||
*Note: Файлы начинающиеся с `__` и которых **нет** в этом дереве являются **внутренними/непротестированными/недокументированными***
|
*Note: Файлы начинающиеся с `__` и которых **нет** в этом дереве являются **внутренними/непротестированными/недокументированными***
|
||||||
```
|
```
|
||||||
Modbus/ Иерархия модулей:
|
Modbus/ Иерархия модулей:
|
||||||
│ inc/ modbus
|
│ inc/ modbus
|
||||||
│ ├── modbus.h # Главный заголовочный файл modbus_slave
|
│ ├── modbus.h # Главный заголовочный файл modbus_slave
|
||||||
│ ├── modbus_core.h # Базовые определения и структуры modbus_master
|
│ ├── modbus_core.h # Базовые определения и структуры modbus_master
|
||||||
│ ├── modbus_coils.h # Работа с дискретными выходами ├── modbus_coils
|
│ ├── modbus_coils.h # Работа с дискретными выходами ├── modbus_coils
|
||||||
│ ├── modbus_holdregs.h # Работа с регистрами хранения ├── modbus_inputregs
|
│ ├── modbus_holdregs.h # Работа с регистрами хранения ├── modbus_inputregs
|
||||||
│ ├── modbus_inputregs.h # Работа с входными регистрами ├── modbus_inputregs
|
│ ├── modbus_inputregs.h # Работа с входными регистрами ├── modbus_inputregs
|
||||||
│ ├── modbus_devid.h # Идентификация устройства ├── modbus_devid
|
│ ├── modbus_devid.h # Идентификация устройства ├── modbus_devid
|
||||||
│ ├── rs_message.h # Драйвер обмена по RS/UART ├── modbus_diag
|
│ ├── rs_message.h # Драйвер обмена по RS/UART ├── modbus_diag
|
||||||
├── src/ └── rs_message
|
├── src/ └── rs_message
|
||||||
│ ├── modbus.c # Основная логика Modbus │
|
│ ├── modbus.c # Основная логика Modbus │
|
||||||
│ ├── modbus_slave.c # Основная логика Slave Modbus └── modbus_core (единое ядро)
|
│ ├── modbus_slave.c # Основная логика Slave Modbus └── modbus_core (единое ядро)
|
||||||
│ ├── modbus_master.c # Основная логика Master Modbus ├── modbus_config
|
│ ├── modbus_master.c # Основная логика Master Modbus ├── modbus_config
|
||||||
│ ├── modbus_coils.c # Реализация работы с coils ├── modbus_data
|
│ ├── modbus_coils.c # Реализация работы с coils ├── modbus_data
|
||||||
│ ├── modbus_holdregs.c # Реализация регистров хранения └── __crc_algs
|
│ ├── modbus_holdregs.c # Реализация регистров хранения └── __crc_algs
|
||||||
│ ├── modbus_inputregs.c # Реализация входных регистров
|
│ ├── modbus_inputregs.c # Реализация входных регистров
|
||||||
│ ├── modbus_devid.c # Реализация идентификации устройства
|
│ ├── modbus_devid.c # Реализация идентификации устройства
|
||||||
│ ├── modbus_data.c # Функции доступа к данным
|
│ ├── modbus_data.c # Функции доступа к данным
|
||||||
│ └── rs_message.c # Реализация драйвера RS
|
│ └── rs_message.c # Реализация драйвера RS
|
||||||
├── __modbus_config.h # Конфигурация Modbus (надо заменить)
|
├── __modbus_config.h # Конфигурация Modbus (надо заменить)
|
||||||
├── __modbus_data.h # Структуры данных (надо заменить)
|
├── __modbus_data.h # Структуры данных (надо заменить)
|
||||||
└── __modbus_data.c # Функции доступа (надо заменить)
|
└── __modbus_data.c # Функции доступа (надо заменить)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Инструкция по подключению
|
## Инструкция по подключению
|
||||||
|
|
||||||
1. **Склонируйте субмодуль** в ваш проект:
|
### 1. **Склонируйте субмодуль** в ваш проект:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git submodule add https://git.arktika.cyou/set506/STM32_Modbus path/to/Modbus
|
git submodule add https://git.arktika.cyou/set506/STM32_Modbus path/to/Modbus
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Скопируйте файлы конфигурации** в отдельную папку в вашем проекте (вне субмодуля) и удалите `__` из имени файлов:
|
### 2. **Скопируйте файлы конфигурации** в отдельную папку в вашем проекте (вне субмодуля) и удалите `__` из имени файлов:
|
||||||
|
|
||||||
```
|
```
|
||||||
ProjectRoot/
|
ProjectRoot/
|
||||||
@@ -47,219 +47,210 @@ ProjectRoot/
|
|||||||
│ ├── modbus_config.h # скопировать из __modbus_config.h
|
│ ├── modbus_config.h # скопировать из __modbus_config.h
|
||||||
│ ├── modbus_data.h # скопировать из __modbus_data.h
|
│ ├── modbus_data.h # скопировать из __modbus_data.h
|
||||||
│ └── modbus_data.c # скопировать из __modbus_data.c
|
│ └── modbus_data.c # скопировать из __modbus_data.c
|
||||||
└── Modbus/ # Субмодуль
|
└── Modbus/ # Субмодуль
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Настройте конфигурацию** под ваш проект:
|
### 3. **Настройте конфигурацию** под ваш проект:
|
||||||
|
#### 3.1. Настройка периферии
|
||||||
3.1. Настройка периферии
|
|
||||||
|
|
||||||
- **UART**: Настройте в режиме Asynchronous, нужная скорость (9600, 19200, etc), 8N1
|
- **UART**: Настройте в режиме Asynchronous, нужная скорость (9600, 19200, etc), 8N1
|
||||||
- **TIM**: Настройте таймер для генерации прерываний (например, 1ms tick)
|
- **TIM**: Настройте таймер для генерации прерываний (например, 1ms tick)
|
||||||
- **Включите прерывания** для UART и TIM
|
- **Включите прерывания** для UART и TIM
|
||||||
|
|
||||||
3.2. Подключение обработчиков прерываний
|
#### 3.2. Подключение обработчиков прерываний
|
||||||
|
|
||||||
Подключите обработчики прерываний **UART** и **TIM** в свои IRQ обработчики ***вместо*** HAL-обработчиков:
|
Подключите обработчики прерываний **UART** и **TIM** в свои IRQ обработчики ***вместо*** HAL-обработчиков:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|
||||||
void USARTx_IRQHandler(void)
|
void USARTx_IRQHandler(void)
|
||||||
{
|
{
|
||||||
RS_UART_Handler(&hmodbus1);
|
RS_UART_Handler(&hmodbus1);
|
||||||
return;
|
return;
|
||||||
HAL_UART_IRQHandler(&huart);
|
HAL_UART_IRQHandler(&huart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIMx_IRQHandler(void)
|
void TIMx_IRQHandler(void)
|
||||||
{
|
{
|
||||||
RS_TIM_Handler(&hmodbus1);
|
RS_TIM_Handler(&hmodbus1);
|
||||||
return;
|
return;
|
||||||
HAL_TIM_IRQHandler(&htim);
|
HAL_TIM_IRQHandler(&htim);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
#### 3.3. В `modbus_config.h` укажите параметры устройства
|
||||||
|
|
||||||
3.3. В `modbus_config.h` укажите параметры устройства
|
#### 3.4. Инициализация в коде
|
||||||
|
|
||||||
|
Чтобы настроить Slave-режим `main()` после инициализации HAL:
|
||||||
|
|
||||||
3.4. Инициализация в коде
|
```c
|
||||||
|
#include "modbus.h"
|
||||||
Чтобы настроить Slave-режим `main()` после инициализации HAL:
|
|
||||||
|
|
||||||
```c
|
int main(void)
|
||||||
#include "modbus.h"
|
{
|
||||||
|
// Инициализация HAL
|
||||||
|
HAL_Init();
|
||||||
|
SystemClock_Config();
|
||||||
|
MX_GPIO_Init();
|
||||||
|
MX_USART1_UART_Init();
|
||||||
|
MX_TIM3_Init();
|
||||||
|
|
||||||
|
// Инициализация Modbus
|
||||||
|
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
||||||
|
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||||
|
|
||||||
|
// Запуск приема Modbus
|
||||||
|
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// Основной цикл
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Чтобы настроить Master-режим `main()` после инициализации HAL:
|
||||||
|
|
||||||
int main(void)
|
```c
|
||||||
{
|
#include "modbus.h"
|
||||||
// Инициализация HAL
|
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||||
HAL_Init();
|
RS_MsgTypeDef read_hold_cmd = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
||||||
SystemClock_Config();
|
// коллбек, вызовется при получении ответа от слейва
|
||||||
MX_GPIO_Init();
|
read_hold[10];
|
||||||
MX_USART1_UART_Init();
|
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||||
MX_TIM3_Init();
|
{
|
||||||
|
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
||||||
// Инициализация Modbus
|
if(hmodbus->RS_STATUS == RS_OK)
|
||||||
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
{
|
||||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
||||||
|
{
|
||||||
// Запуск приема Modbus
|
uint16_t value;
|
||||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
|
||||||
|
{
|
||||||
while (1)
|
read_hold[i] = value;
|
||||||
{
|
}
|
||||||
// Основной цикл
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
int main(void)
|
||||||
|
{
|
||||||
|
// Инициализация HAL
|
||||||
|
HAL_Init();
|
||||||
|
SystemClock_Config();
|
||||||
|
MX_GPIO_Init();
|
||||||
|
MX_USART1_UART_Init();
|
||||||
|
MX_TIM3_Init();
|
||||||
|
|
||||||
|
// Инициализация Modbus
|
||||||
|
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
||||||
|
MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
|
||||||
|
|
||||||
|
// Запрос по Modbus
|
||||||
|
MODBUS_MasterRequest(&hmodbus1, &read_hold_cmd, &callback_func);
|
||||||
|
|
||||||
Чтобы настроить Master-режим `main()` после инициализации HAL:
|
}
|
||||||
|
```
|
||||||
|
#### 3.5. Настройка карты данных
|
||||||
|
|
||||||
```c
|
В `modbus_data.h` настройте регистры и coils под ваше устройство:
|
||||||
#include "modbus.h"
|
|
||||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
|
||||||
RS_MsgTypeDef read_hold_cmd = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
|
||||||
// коллбек, вызовется при получении ответа от слейва
|
|
||||||
read_hold[10];
|
|
||||||
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
|
||||||
{
|
|
||||||
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
|
||||||
if(hmodbus->RS_STATUS == RS_OK)
|
|
||||||
{
|
|
||||||
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
|
||||||
{
|
|
||||||
uint16_t value;
|
|
||||||
if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
|
|
||||||
{
|
|
||||||
read_hold[i] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
// Инициализация HAL
|
|
||||||
HAL_Init();
|
|
||||||
SystemClock_Config();
|
|
||||||
MX_GPIO_Init();
|
|
||||||
MX_USART1_UART_Init();
|
|
||||||
MX_TIM3_Init();
|
|
||||||
|
|
||||||
// Инициализация Modbus
|
|
||||||
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
|
||||||
MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
|
|
||||||
|
|
||||||
// Запрос по Modbus
|
|
||||||
MODBUS_MasterRequest(&hmodbus1, &read_hold_cmd, &callback_func);
|
|
||||||
|
|
||||||
}
|
**Input Registers (только чтение)**
|
||||||
```
|
```c
|
||||||
3.5. Настройка карты данных
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t Temperature; // Адрес 0
|
||||||
|
uint16_t Humidity; // Адрес 1
|
||||||
|
uint16_t Pressure; // Адрес 2
|
||||||
|
uint16_t Voltage; // Адрес 3
|
||||||
|
} MB_DataInRegsTypeDef;
|
||||||
|
|
||||||
В `modbus_data.h` настройте регистры и coils под ваше устройство:
|
#define R_INPUT_ADDR 0 // Начальный адрес Input регистров
|
||||||
|
#define R_INPUT_QNT 4 // Количество Input регистров
|
||||||
|
```
|
||||||
|
**Holding Registers (чтение/запись)**
|
||||||
|
```c
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t SetpointTemp; // Адрес 0
|
||||||
|
uint16_t SetpointHumidity; // Адрес 1
|
||||||
|
uint16_t ControlMode; // Адрес 2
|
||||||
|
} MB_DataHoldRegsTypeDef;
|
||||||
|
|
||||||
**Input Registers (только чтение)**
|
#define R_HOLDING_ADDR 0 // Начальный адрес Holding регистров
|
||||||
```c
|
#define R_HOLDING_QNT 3 // Количество Holding регистров
|
||||||
typedef struct
|
```
|
||||||
{
|
**Coils (1-битные)**
|
||||||
uint16_t Temperature; // Адрес 0
|
```c
|
||||||
uint16_t Humidity; // Адрес 1
|
typedef struct
|
||||||
uint16_t Pressure; // Адрес 2
|
{
|
||||||
uint16_t Voltage; // Адрес 3
|
unsigned Relay1 : 1; // Адрес 0
|
||||||
} MB_DataInRegsTypeDef;
|
unsigned Relay2 : 1; // Адрес 1
|
||||||
|
unsigned Pump : 1; // Адрес 2
|
||||||
|
unsigned Heater : 1; // Адрес 3
|
||||||
|
unsigned reserved : 12; // Резерв (выравнивание до 16 бит)
|
||||||
|
} MB_DataCoilsTypeDef;
|
||||||
|
|
||||||
#define R_INPUT_ADDR 0 // Начальный адрес Input регистров
|
#define C_COILS_ADDR 0 // Начальный адрес Coils
|
||||||
#define R_INPUT_QNT 4 // Количество Input регистров
|
#define C_COILS_QNT 4 // Количество Coils
|
||||||
```
|
```
|
||||||
|
#### 3.6. Доступ к данным в коде
|
||||||
|
|
||||||
**Holding Registers (чтение/запись)**
|
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
|
||||||
```c
|
```c
|
||||||
typedef struct
|
// Чтение входных регистров
|
||||||
{
|
uint16_t temp = MB_DATA.InRegs.Temperature;
|
||||||
uint16_t SetpointTemp; // Адрес 0
|
|
||||||
uint16_t SetpointHumidity; // Адрес 1
|
|
||||||
uint16_t ControlMode; // Адрес 2
|
|
||||||
} MB_DataHoldRegsTypeDef;
|
|
||||||
|
|
||||||
#define R_HOLDING_ADDR 0 // Начальный адрес Holding регистров
|
// Запись в регистры хранения
|
||||||
#define R_HOLDING_QNT 3 // Количество Holding регистров
|
MB_DATA.HoldRegs.SetpointTemp = 2500;
|
||||||
```
|
|
||||||
|
|
||||||
**Coils (1-битные)**
|
// Управление coils
|
||||||
```c
|
MB_Coil_Set_Local(&MB_DATA.Coils, 0); // Включить Relay1
|
||||||
typedef struct
|
MB_Coil_Reset_Local(&MB_DATA.Coils, 1); // Выключить Relay2
|
||||||
{
|
|
||||||
unsigned Relay1 : 1; // Адрес 0
|
|
||||||
unsigned Relay2 : 1; // Адрес 1
|
|
||||||
unsigned Pump : 1; // Адрес 2
|
|
||||||
unsigned Heater : 1; // Адрес 3
|
|
||||||
unsigned reserved : 12; // Резерв (выравнивание до 16 бит)
|
|
||||||
} MB_DataCoilsTypeDef;
|
|
||||||
|
|
||||||
#define C_COILS_ADDR 0 // Начальный адрес Coils
|
// Чтение coil
|
||||||
#define C_COILS_QNT 4 // Количество Coils
|
if (MB_Coil_Read_Local(&MB_DATA.Coils, 2)) {
|
||||||
```
|
// Pump включен
|
||||||
|
}
|
||||||
|
```
|
||||||
|
В режиме мастера есть функции для получения информации из ответа `MB_RespGet_...()`
|
||||||
|
```c
|
||||||
|
// Чтение регистров: Получить запрошенные регистры
|
||||||
|
uint16_t value;
|
||||||
|
if(MB_RespGet_RegisterValue(&MODBUS_MSG, 105, ®_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);
|
||||||
|
}
|
||||||
|
|
||||||
3.6. Доступ к данным в коде
|
uint8_t obj_id, obj_length;
|
||||||
|
char obj_data[64];
|
||||||
|
if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, 0x00, &obj_id, obj_data, &obj_length))
|
||||||
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
|
{
|
||||||
```c
|
printf("First object - ID: 0x%02X, Data: %s\n", obj_id, obj_data);
|
||||||
// Чтение входных регистров
|
}
|
||||||
uint16_t temp = MB_DATA.InRegs.Temperature;
|
```
|
||||||
|
|
||||||
// Запись в регистры хранения
|
|
||||||
MB_DATA.HoldRegs.SetpointTemp = 2500;
|
|
||||||
|
|
||||||
// Управление coils
|
|
||||||
MB_Coil_Set_Local(&MB_DATA.Coils, 0); // Включить Relay1
|
|
||||||
MB_Coil_Reset_Local(&MB_DATA.Coils, 1); // Выключить Relay2
|
|
||||||
|
|
||||||
// Чтение coil
|
|
||||||
if (MB_Coil_Read_Local(&MB_DATA.Coils, 2)) {
|
|
||||||
// Pump включен
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
В режиме мастера есть функции для получения информации из ответа `MB_RespGet_...()`
|
|
||||||
```c
|
|
||||||
// Чтение регистров: Получить запрошенные регистры
|
|
||||||
uint16_t value;
|
|
||||||
if(MB_RespGet_RegisterValue(&MODBUS_MSG, 105, ®_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. **Обновление библиотеки**:
|
||||||
|
|
||||||
После обновления субмодуля из Git, исходные файлы библиотеки будут обновлены, и ваши конфиги вне субмодуля не перезапишутся:
|
После обновления субмодуля из Git, исходные файлы библиотеки будут обновлены, и ваши конфиги вне субмодуля не перезапишутся:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @file __modbus_compat.c
|
* @file __modbus_compat.c
|
||||||
* @brief Модуль для совместимости библиотеки MODBUS.
|
* @brief Модуль для совместимости библиотеки MODBUS.
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|||||||
20
Src/modbus.c
20
Src/modbus.c
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus.c
|
* @file modbus.c
|
||||||
* @brief Модуль для реализации MODBUS.
|
* @brief Модуль для реализации MODBUS.
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Файл содержит реализацию функций работы с Modbus.
|
Файл содержит реализацию функций работы с Modbus.
|
||||||
|
|
||||||
@section Функции и макросы
|
@section mbapi Функции и макросы
|
||||||
|
|
||||||
### Инициализация:
|
### Инициализация:
|
||||||
- MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM)
|
- MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM)
|
||||||
@@ -164,9 +164,15 @@ HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//-----------------------------INTERNAL------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Дефолтный коллбек для мастера.
|
||||||
|
* @param hmodbus Указатель на хендлер RS
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @details В этот коллбек попадут все запросы, с NULL-коллбеком
|
||||||
|
*/
|
||||||
static void MB_DefaultCallback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
static void MB_DefaultCallback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||||
{
|
{
|
||||||
__NOP();
|
__NOP();
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_coils.c
|
* @file modbus_coils.c
|
||||||
* @brief Реализация работы с коилами Modbus
|
* @brief Реализация работы с коилами Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к coils внутри программы:
|
||||||
|
- Функции для доступа к coils по глобальным адресам
|
||||||
|
- Макросы для доступа к coils по локальным адресам
|
||||||
|
|
||||||
Модуль обработки команд для coils (битовых данных):
|
Модуль обработки команд для coils (битовых данных):
|
||||||
- Чтение coils (0x01) - упаковка битов в байты для передачи
|
- Чтение coils (0x01) - упаковка битов в байты для передачи
|
||||||
- Запись одиночного coil (0x05) - установка/сброс бита
|
- Запись одиночного coil (0x05) - установка/сброс бита
|
||||||
- Запись множественных coils (0x0F) - распаковка битов из байтов
|
- Запись множественных coils (0x0F) - распаковка битов из байтов
|
||||||
|
|
||||||
|
@section cvalid Валидация данных:
|
||||||
|
- Проверка соответствия количества байт и регистров
|
||||||
|
- Валидация адресов через MB_DefineRegistersAddress()
|
||||||
|
- Обработка исключений при некорректных запросах
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "modbus_coils.h"
|
#include "modbus_coils.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_core.c
|
* @file modbus_core.c
|
||||||
* @brief Базовая реализация ядра Modbus
|
* @brief Базовая реализация ядра Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
В текущей реализации этот файл служит заглушкой для будущего расширения
|
В текущей реализации этот файл служит заглушкой для будущего расширения
|
||||||
функциональности ядра Modbus протокола.
|
функциональности ядра Modbus протокола.
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_devid.c
|
* @file modbus_devid.c
|
||||||
* @brief Реализация идентификаторов устройства Modbus
|
* @brief Реализация идентификаторов устройства Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль обработки запросов идентификации устройства через MEI-тип 0x0E:
|
Модуль обработки запросов идентификации устройства через MEI-тип 0x0E:
|
||||||
- Формирование иерархии объектов идентификации
|
- Формирование иерархии объектов идентификации
|
||||||
- Поддержка потоковой передачи при большом количестве объектов
|
- Поддержка потоковой передачи при большом количестве объектов
|
||||||
- Автоматический расчет MoreFollows флагов
|
- Автоматический расчет MoreFollows флагов
|
||||||
|
|
||||||
@section Потоковая передача:
|
@section stream Потоковая передача:
|
||||||
При большом количестве объектов идентификация разбивается на несколько
|
При большом количестве объектов идентификация разбивается на несколько
|
||||||
сообщений с установкой флага MoreFollows и указанием NextObjId для
|
сообщений с установкой флага MoreFollows и указанием NextObjId для
|
||||||
продолжения чтения в следующем запросе.
|
продолжения чтения в следующем запросе.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_diag.c
|
* @file modbus_diag.c
|
||||||
* @brief Реализация диагностики устройства Modbus
|
* @brief Реализация диагностики устройства Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль обработки запросов диагностической информации (0x08):
|
Модуль обработки запросов диагностической информации (0x08):
|
||||||
- Полная поддержка всех подфункций диагностики согласно спецификации Modbus
|
- Полная поддержка всех подфункций диагностики согласно спецификации Modbus
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_holdregs.c
|
* @file modbus_holdregs.c
|
||||||
* @brief Реализация работы с регистрами хранения Modbus
|
* @brief Реализация работы с регистрами хранения Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к регистрам внутри программы:
|
||||||
|
- Функции для доступа к регистрам хранения по глобальным адресам
|
||||||
|
|
||||||
Модуль обработки команд для holding registers (регистров хранения):
|
Модуль обработки команд для holding registers (регистров хранения):
|
||||||
- Чтение множественных регистров (0x03) - копирование данных в буфер ответа
|
- Чтение множественных регистров (0x03) - копирование данных в буфер ответа
|
||||||
- Запись одиночного регистра (0x06) - прямая запись значения
|
- Запись одиночного регистра (0x06) - прямая запись значения
|
||||||
- Запись множественных регистров (0x10) - пакетная запись из буфера
|
- Запись множественных регистров (0x10) - пакетная запись из буфера
|
||||||
|
|
||||||
@section Валидация данных:
|
@section hvalid Валидация данных:
|
||||||
- Проверка соответствия количества байт и регистров
|
- Проверка соответствия количества байт и регистров
|
||||||
Валидация адресов через MB_DefineRegistersAddress()
|
- Валидация адресов через MB_DefineRegistersAddress()
|
||||||
- Обработка исключений при некорректных запросах
|
- Обработка исключений при некорректных запросах
|
||||||
|
|
||||||
@section Echo-ответы:
|
|
||||||
При успешной записи формируется echo-ответ с теми же данными,
|
|
||||||
что были в запросе (для функций 0x05, 0x06, 0x0F, 0x10).
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "modbus_inputregs.h"
|
#include "modbus_inputregs.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_inputregs.c
|
* @file modbus_inputregs.c
|
||||||
* @brief Реализация работы с входными регистрами Modbus
|
* @brief Реализация работы с входными регистрами Modbus
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
Модуль для доступа к регистрам внутри программы:
|
||||||
|
- Функции для доступа к входным регистрам по глобальным адресам
|
||||||
|
|
||||||
Модуль обработки команды чтения input registers (0x04):
|
Модуль обработки команды чтения input registers (0x04):
|
||||||
- Чтение множественных входных регистров
|
|
||||||
Копирование данных из структур устройства в буфер ответа
|
@section ivalid Валидация данных:
|
||||||
- Поддержка знаковых и беззнаковых значений
|
- Проверка соответствия количества байт и регистров
|
||||||
|
- Валидация адресов через MB_DefineRegistersAddress()
|
||||||
|
- Обработка исключений при некорректных запросах
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "modbus_inputregs.h"
|
#include "modbus_inputregs.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_master.c
|
* @file modbus_master.c
|
||||||
* @brief Модуль для реализации мастера MODBUS.
|
* @brief Модуль для реализации мастера MODBUS.
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Файл содержит реализацию функций для работы Modbus в режиме мастера.
|
Файл содержит реализацию функций для работы Modbus в режиме мастера.
|
||||||
|
|
||||||
@section Функции и макросы
|
@section mast Функции и макросы
|
||||||
|
- MB_RespGet_RegisterAll() — Считать все регистра из ответа
|
||||||
|
- MB_RespGet_RegisterValue() — Считать один регистр из ответа
|
||||||
|
- MB_RespGet_CoilAll() — Считать все коилы из ответа
|
||||||
|
- MB_RespGet_CoilState() — Считать один коил из ответа
|
||||||
|
- MB_RespGet_NumberOfObjects() — Считать количество принятых объектов идентификатора
|
||||||
|
- MB_RespGet_ObjectById() — Считать объект идентификатора по
|
||||||
|
его ID
|
||||||
|
- MB_RespGet_ObjectByIndex() — Считать объект идентификатора по
|
||||||
|
порядковому номеру в сообщении
|
||||||
|
- MB_RespGet_Diagnostic() — Считать запрошенный диагностический счетчик
|
||||||
|
|
||||||
- MB_Master_Collect_Message() — Сбор сообщения в режиме мастера
|
- MB_Master_Collect_Message() — Сбор сообщения в режиме мастера
|
||||||
- MB_Master_Parse_Message() — Парс сообщения в режиме мастера
|
- MB_Master_Parse_Message() — Парс сообщения в режиме мастера
|
||||||
@@ -16,8 +26,35 @@
|
|||||||
#ifdef MODBUS_ENABLE_MASTER
|
#ifdef MODBUS_ENABLE_MASTER
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//-----------------------------FOR USER------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief Получить значение регистра из ответа по его адресу
|
* @brief Получить значение ВСЕХ регистров в ответе
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param reg_addr Адрес регистра, значение которого нужно получить
|
||||||
|
* @param reg_arr Указатель для массив для сохранения значений регистров
|
||||||
|
* @return количество считанных регистров, 0 - ошибка
|
||||||
|
*/
|
||||||
|
int MB_RespGet_RegisterAll(RS_MsgTypeDef *modbus_msg, uint16_t *reg_arr)
|
||||||
|
{
|
||||||
|
if(modbus_msg == NULL || reg_arr == NULL)
|
||||||
|
return 0;
|
||||||
|
int read_cnt = 0;
|
||||||
|
int i = 0;
|
||||||
|
for(int addr = modbus_msg->Addr; addr < modbus_msg->Addr + modbus_msg->Qnt; addr++)
|
||||||
|
{
|
||||||
|
if(MB_RespGet_RegisterValue(modbus_msg, addr, ®_arr[i]))
|
||||||
|
{
|
||||||
|
read_cnt++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return read_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить значение регистра в ответе по его адресу
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
* @param reg_addr Адрес регистра, значение которого нужно получить
|
* @param reg_addr Адрес регистра, значение которого нужно получить
|
||||||
* @param reg_value Указатель для значения регистра
|
* @param reg_value Указатель для значения регистра
|
||||||
@@ -55,6 +92,31 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить состояние ВСЕХ coil в ответе
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param coil_arr Указатель для массив доя сохранения состояний coil (1 - ON, 0 - OFF)
|
||||||
|
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
|
||||||
|
*/
|
||||||
|
int MB_RespGet_CoilAll(RS_MsgTypeDef *modbus_msg, int *coil_arr)
|
||||||
|
{
|
||||||
|
if(modbus_msg == NULL || coil_arr == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int read_cnt = 0;
|
||||||
|
int i = 0;
|
||||||
|
for(int addr = modbus_msg->Addr; addr < modbus_msg->Addr + modbus_msg->Qnt; addr++)
|
||||||
|
{
|
||||||
|
if(MB_RespGet_CoilState(modbus_msg, addr, &coil_arr[i]))
|
||||||
|
{
|
||||||
|
read_cnt++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Получить состояние coil в ответе по его адресу
|
* @brief Получить состояние coil в ответе по его адресу
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
@@ -93,7 +155,7 @@ int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coi
|
|||||||
if(bit_index < 8)
|
if(bit_index < 8)
|
||||||
*coil_state = (modbus_msg->MbData[data_index] >> (bit_index+8)) & 0x01;
|
*coil_state = (modbus_msg->MbData[data_index] >> (bit_index+8)) & 0x01;
|
||||||
else
|
else
|
||||||
*coil_state = ((modbus_msg->MbData[data_index]&0xFF) >> bit_index-8) & 0x01;
|
*coil_state = ((modbus_msg->MbData[data_index]&0xFF) >> (bit_index-8)) & 0x01;
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -250,6 +312,10 @@ int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//-----------------------------INTERNAL------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
||||||
* @param hRS Указатель на хендлер RS.
|
* @param hRS Указатель на хендлер RS.
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @file modbus_slave.c
|
* @file modbus_slave.c
|
||||||
* @brief Модуль для реализации слейв MODBUS.
|
* @brief Модуль для реализации слейв MODBUS.
|
||||||
**************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Файл содержит реализацию функций для работы Modbus в режиме слейва.
|
Файл содержит реализацию функций для работы Modbus в режиме слейва.
|
||||||
|
|
||||||
@section Функции и макросы
|
@section slave Функции и макросы
|
||||||
|
|
||||||
- MB_Slave_Response() — Ответ на запрос
|
- MB_Slave_Response() — Ответ на запрос
|
||||||
- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
|
- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file rs_message.c
|
* @file rs_message.c
|
||||||
* @brief Реализация протоколов обмена по RS/UART
|
* @brief Реализация протоколов обмена по RS/UART
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Модуль реализует асинхронный обмен сообщениями через UART с использованием:
|
Модуль реализует асинхронный обмен сообщениями через UART с использованием:
|
||||||
- Прерываний по приему/передаче
|
- Прерываний по приему/передаче
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
- Таймаутов через таймер
|
- Таймаутов через таймер
|
||||||
- Двухстадийного приема (заголовок + данные)
|
- Двухстадийного приема (заголовок + данные)
|
||||||
|
|
||||||
@section Архитектура:
|
@section arch Архитектура:
|
||||||
В режиме слейв:
|
В режиме слейв:
|
||||||
- Инициализация приема с сообщения с максимальным размером MSG_SIZE_MAX
|
- Инициализация приема с сообщения с максимальным размером MSG_SIZE_MAX
|
||||||
- При срабатывании прерывания IDLE - обработка полученного сообщения
|
- При срабатывании прерывания IDLE - обработка полученного сообщения
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
- Отправка запроса и переход в режим приема сообщения с максимальным размером MSG_SIZE_MAX
|
- Отправка запроса и переход в режим приема сообщения с максимальным размером MSG_SIZE_MAX
|
||||||
- При срабатывании прерывания IDLE - обработка полученного ответа
|
- При срабатывании прерывания IDLE - обработка полученного ответа
|
||||||
|
|
||||||
@section Необходимые обработчики:
|
@section ithandler Необходимые обработчики:
|
||||||
- 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()
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
@addtogroup MODBUS_CONFIGS Modbus configs
|
@addtogroup MODBUS_CONFIGS Modbus configs
|
||||||
@ingroup MODBUS
|
@ingroup MODBUS
|
||||||
|
@brief Конфигурация библиотеки
|
||||||
@{
|
@{
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @file modbus_data.h
|
* @file modbus_data.h
|
||||||
* @brief Определения структур данных Modbus устройства
|
* @brief Определения структур данных Modbus устройства
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
@defgroup MODBUS_DATA Modbus Data Tools
|
@defgroup MODBUS_DATA Modbus Registers Map
|
||||||
@ingroup MODBUS
|
@ingroup MODBUS
|
||||||
@brief Определение карты регистров и коилов
|
@brief Определение карты регистров и коилов
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
- Input Registers (R/O) - входные регистры
|
- Input Registers (R/O) - входные регистры
|
||||||
- Coils (R/W) - дискретные выходы
|
- Coils (R/W) - дискретные выходы
|
||||||
|
|
||||||
@section Базовая настройка под устройство:
|
@section datinit Базовая настройка под устройство:
|
||||||
1. Настроить диапазоны адресов
|
1. Настроить диапазоны адресов
|
||||||
- @ref R_INPUT_ADDR и @ref R_INPUT_QNT для входных регистров
|
- @ref R_INPUT_ADDR и @ref R_INPUT_QNT для входных регистров
|
||||||
- @ref R_HOLDING_ADDR и @ref R_HOLDING_QNT для регистров хранения
|
- @ref R_HOLDING_ADDR и @ref R_HOLDING_QNT для регистров хранения
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
- @ref MB_DataCoilsTypeDef
|
- @ref MB_DataCoilsTypeDef
|
||||||
|
|
||||||
|
|
||||||
@section Расширенная настройка под устройство:
|
@section datexpert Расширенная настройка под устройство:
|
||||||
1. Добавить новый массив с нужными данными.
|
1. Добавить новый массив с нужными данными.
|
||||||
2. Добавить дефайны для определения его начального адреса и количества элементов
|
2. Добавить дефайны для определения его начального адреса и количества элементов
|
||||||
3. Добавить проверку адресов в MB_DefineRegistersAddress/MB_DefineCoilsAddress.
|
3. Добавить проверку адресов в MB_DefineRegistersAddress/MB_DefineCoilsAddress.
|
||||||
@@ -75,11 +75,11 @@
|
|||||||
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES Registers structures
|
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES Registers structures
|
||||||
* @ingroup MODBUS_DATA
|
* @ingroup MODBUS_DATA
|
||||||
* @brief Стуруктура регистров (входных и хранения)
|
* @brief Стуруктура регистров (входных и хранения)
|
||||||
@verbatim
|
@code
|
||||||
Для массивов регистров:
|
Для массивов регистров:
|
||||||
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
|
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
|
||||||
R_<NAME_ARRAY>_QNT - количество регистров в массиве
|
R_<NAME_ARRAY>_QNT - количество регистров в массиве
|
||||||
@endverbatim
|
@endcode
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -111,12 +111,12 @@ typedef struct //MB_DataInRegsTypeDef
|
|||||||
* @addtogroup MODBUS_DATA_COILS_DEFINES Coils Structure
|
* @addtogroup MODBUS_DATA_COILS_DEFINES Coils Structure
|
||||||
* @ingroup MODBUS_DATA
|
* @ingroup MODBUS_DATA
|
||||||
* @brief Структура коилов
|
* @brief Структура коилов
|
||||||
@verbatim
|
@code
|
||||||
Структура дефайна
|
Структура дефайна
|
||||||
Для массивов коилов:
|
Для массивов коилов:
|
||||||
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
|
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
|
||||||
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
|
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
|
||||||
@endverbatim
|
@endcode
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user