release 0.4 (*API CHANGED)
*Не совсем апи, но поменялись enum в modbus_core.h: - MB_ExceptionTypeDef - MB_FunctonTypeDef Необходимо обновить modbus_data.c: NO_ERRORS -> NO_ERRORS ILLEGAL_FUNCTION -> ET_ILLEGAL_FUNCTION ILLEGAL_DATA_ADDRESS -> ET_ILLEGAL_DATA_ADDRESS ILLEGAL_DATA_ADDRESS -> ET_ILLEGAL_DATA_ADDRESS - множественные правки докумнтации - множественный рефакторинг
This commit is contained in:
118
Inc/__modbus_compat.h
Normal file
118
Inc/__modbus_compat.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file __modbus_compat.h
|
||||
* @brief Модуль для совместимости библиотеки MODBUS.
|
||||
*******************************************************************************
|
||||
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
||||
******************************************************************************/
|
||||
#include "modbus_core.h"
|
||||
|
||||
|
||||
/** @addtogroup MODBUS_LEGACY_API Legacy API
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Старые API функций, сохранённые для обратной совместимости.
|
||||
* @note Не используйте эти функции в новом коде. Они могут быть удалены в будущих версиях.
|
||||
* Вместо них используйте функции из основных групп MODBUS API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** MODBUS_LEGACY_API
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @cond Заглушки отключенных модулей */
|
||||
|
||||
#ifndef MODBUS_ENABLE_COILS
|
||||
#define MB_Coil_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Coil_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Coils(modbus_msg) 0
|
||||
#define MB_Process_Write_Single_Coil(modbus_msg) 0
|
||||
#define MB_Process_Write_Miltuple_Coils(modbus_msg) 0
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_HOLDINGS
|
||||
#define MB_Holding_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Holding_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Hold_Regs(modbus_msg) 0
|
||||
#define MB_Process_Write_Single_Reg(modbus_msg) 0
|
||||
#define MB_Process_Write_Miltuple_Regs(modbus_msg) 0
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_INPUTS
|
||||
#define MB_Input_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
||||
#define MB_Input_Read_Global(Addr, Exception) 0
|
||||
#define MB_Process_Read_Input_Regs(modbus_msg) 0
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#define MB_WriteSingleObjectToMessage(mbdata, ind, obj)
|
||||
#define MB_WriteObjectsToMessage(modbus_msg, maxidofobj)
|
||||
#define MB_Process_Read_Device_Identifications(modbus_msg) 0
|
||||
#define MB_DeviceInentificationInit()
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MODBUS_ENABLE_DIAGNOSTICS
|
||||
#define MB_DiagnosticsInit()
|
||||
#define MB_Diagnostics_WriteBit(bit_num, bit_state) 0
|
||||
#define MB_Diagnostics_GetBit(bit_num) 0
|
||||
#define MB_Process_Diagnostics(modbus_msg) 0
|
||||
#define MB_Diagnostics_BusMessageCnt()
|
||||
#define MB_Diagnostics_CommunicationErrorCnt()
|
||||
#define MB_Diagnostics_ExceptionErrorCnt()
|
||||
#define MB_Diagnostics_CharacterOverrunCnt()
|
||||
#define MB_Diagnostics_SlaveMessageCnt()
|
||||
#define MB_Diagnostics_SlaveNoResponseCnt()
|
||||
#define MB_Diagnostics_SlaveNAKCnt()
|
||||
#define MB_Diagnostics_SlaveBusyCnt()
|
||||
#define MB_GetDeviceMode() MODBUS_NORMAL_MODE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef MODBUS_ENABLE_MASTER
|
||||
#define MB_RespGet_RegisterValue(modbus_msg, reg_addr, reg_value) 0
|
||||
#define MB_RespGet_CoilState(modbus_msg, coil_addr, coil_state) 0
|
||||
#define MB_RespGet_NumberOfObjects(modbus_msg) 0
|
||||
#define MB_RespGet_ObjectById(modbus_msg, obj_id, obj_data, obj_length) 0
|
||||
#define MB_RespGet_ObjectByIndex(modbus_msg, index, obj_id, obj_data, obj_length) 0
|
||||
#define MB_RespGet_Diagnostic(modbus_msg, data) 0
|
||||
#define MB_REQUEST_READ_COILS(slave_addr, start_addr, quantity) {0}
|
||||
#define MB_REQUEST_READ_DISCRETE_INPUTS(slave_addr, start_addr, quantity) {0}
|
||||
#define MB_REQUEST_READ_HOLDING_REGS(slave_addr, start_addr, quantity) {0}
|
||||
#define MB_REQUEST_READ_INPUT_REGS(slave_addr, start_addr, quantity) {0}
|
||||
#define MB_REQUEST_WRITE_SINGLE_COIL(slave_addr, coil_addr, value) {0}
|
||||
#define MB_REQUEST_WRITE_SINGLE_REG(slave_addr, reg_addr, value) {0}
|
||||
#define MB_REQUEST_WRITE_MULTIPLE_COILS(slave_addr, start_addr, quantity, coils_data) {0}
|
||||
#define MB_REQUEST_WRITE_MULTIPLE_REGS(slave_addr, start_addr, quantity, regs_data) {0}
|
||||
#define MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, sub_function, data) {0}
|
||||
#define MB_REQUEST_RETURN_QUERY_DATA(slave_addr) {0}
|
||||
#define MB_REQUEST_RESTART_COMMUNICATIONS(slave_addr, data) {0}
|
||||
#define MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(slave_addr) {0}
|
||||
#define MB_REQUEST_FORCE_LISTEN_ONLY_MODE(slave_addr) {0}
|
||||
#define MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_SLAVE_NAK_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(slave_addr) {0}
|
||||
#define MB_REQUEST_READ_DEVICE_ID_BASIC(slave_addr) {0}
|
||||
#define MB_REQUEST_READ_DEVICE_ID_REGULAR(slave_addr) {0}
|
||||
#define MB_REQUEST_READ_DEVICE_ID_EXTENDED(slave_addr) {0}
|
||||
#define MB_REQUEST_READ_DEVICE_ID_SPECIFIC(slave_addr, object_id) {0}
|
||||
#define MB_Master_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
||||
#define MB_Master_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_ENABLE_SLAVE
|
||||
#define MB_Slave_Response(hmodbus, modbus_msg) RS_ERR
|
||||
#define MB_Slave_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
||||
#define MB_Slave_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
79
Inc/modbus.h
79
Inc/modbus.h
@@ -1,20 +1,22 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus.h
|
||||
* @brief Главный заголовочный файл Modbus библиотеки
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS Modbus tools
|
||||
******************************************************************************
|
||||
@brief Библиотека реализующая протокол Modbus
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_FUNCTIONS Main API for Modbus Library
|
||||
@ingroup MODBUS
|
||||
@brief Публичные функции библиотеки
|
||||
@{
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Объединяющий файл для подключения всей функциональности Modbus.
|
||||
Подключает все необходимые модули:
|
||||
|
||||
|
||||
@section init Инструкция по подключению
|
||||
@section Start Инструкция по подключению
|
||||
Для корректной работы надо:
|
||||
- Подключить обработчики RS_UART_Handler(), RS_TIM_Handler(), в соответствубщие
|
||||
низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler вместо HAL'овского обработчика
|
||||
@@ -23,43 +25,43 @@
|
||||
|
||||
- Инициализировать хендл мобдас. По умолчанию глобально создается hmodbus1
|
||||
- После для запуска Modbus:
|
||||
@verbatim
|
||||
@code
|
||||
//----------------Слейв модбас----------------//
|
||||
#include "modbus.h"
|
||||
|
||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||
MODBUS_Config(&hmodbus1, 1, 1000, MODBUS_MODE_SLAVE);
|
||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||
@endverbatim
|
||||
@verbatim
|
||||
@endcode
|
||||
@code
|
||||
//----------------Мастер модбас----------------//
|
||||
#include "modbus.h"
|
||||
|
||||
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 штук
|
||||
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
||||
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endverbatim
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@section Подключаемые модули:
|
||||
@section modules Подключаемые модули:
|
||||
- rs_message.h - работа с uart
|
||||
- modbus_core.h - базовые определения
|
||||
- modbus_coils.h - работа с дискретными выходами
|
||||
@@ -69,7 +71,7 @@
|
||||
- modbus_diag.h - диагностика modbus
|
||||
|
||||
|
||||
@section Структура данных Modbus
|
||||
@section data Структура данных Modbus
|
||||
|
||||
#### Holding/Input Registers:
|
||||
- Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.
|
||||
@@ -84,21 +86,35 @@
|
||||
#define __MODBUS_H_
|
||||
|
||||
#include "rs_message.h"
|
||||
#ifdef MODBUS_ENABLE_MASTER
|
||||
#include "modbus_master.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_SLAVE
|
||||
#include "modbus_slave.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_COILS
|
||||
#include "modbus_coils.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_HOLDINGS
|
||||
#include "modbus_holdregs.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_INPUTS
|
||||
#include "modbus_inputregs.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||
#include "modbus_devid.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
#include "modbus_diag.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MODBUS_ENABLE_MASTER
|
||||
#define MODBUS_MODE_MASTER 1
|
||||
#define MODBUS_MODE_MASTER 1 ///< Псевдо-enum: Режим мастер
|
||||
#endif
|
||||
|
||||
#ifdef MODBUS_ENABLE_SLAVE
|
||||
#define MODBUS_MODE_SLAVE 0
|
||||
#define MODBUS_MODE_SLAVE 0 ///< Псевдо-enum: Режим слейв
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@ -124,4 +140,5 @@ HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
||||
|
||||
/** MODBUS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_coils.h
|
||||
* @brief Работа с коилами Modbus
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_COILS Coils Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
******************************************************************************
|
||||
@brief Функции для работы с коилами
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль для доступа к coils внутри программы:
|
||||
- Функции для доступа к coils по глобальным адресам
|
||||
- Макросы для доступа к coils по локальным адресам
|
||||
|
||||
Модуль предоставляет функции и макросы для работы с битовыми данными:
|
||||
- Чтение coils (0x01) Упаковка битов в байты
|
||||
- Запись одиночного coil (0x05) Установка/сброс бита
|
||||
- Запись множественных coils (0x0F) - распаковка байтов в биты
|
||||
- Макросы для локального доступа к coils
|
||||
|
||||
@section Организация битовых данных:
|
||||
@section cbits Организация битовых данных:
|
||||
Coils упакованы в 16-битные слова для эффективного использования памяти.
|
||||
Биты нумеруются от младшего к старшему внутри каждого слова.
|
||||
|
||||
@section Адресация:
|
||||
@section caddr Адресация:
|
||||
- Глобальная - абсолютный адрес в пространстве Modbus
|
||||
- Локальная - относительный адрес внутри массива coils
|
||||
- Макросы автоматически вычисляют смещения и маски
|
||||
@@ -44,7 +48,7 @@ Coils упакованы в 16-битные слова для эффективн
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
|
||||
* @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
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
/* Обработать функцию Read Coils (01 - 0x01) */
|
||||
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
@@ -115,4 +119,4 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
*/
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
#endif //__MODBUS_COILS_H_
|
||||
#endif //__MODBUS_COILS_H_
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_core.h
|
||||
* @brief Ядро Modbus протокола - определения и структуры
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_INTERNAL Modbus Internal Tools
|
||||
@ingroup MODBUS
|
||||
@brief Внутренние штуки библиотеки
|
||||
@{
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Базовые определения для реализации Modbus RTU устройства:
|
||||
- Структуры сообщений Modbus
|
||||
@@ -14,7 +15,7 @@
|
||||
Константы размеров полей
|
||||
Вспомогательные макросы
|
||||
|
||||
@section Структура сообщения:
|
||||
@section msg Структура сообщения:
|
||||
[ADDR][FUNC][DATA...][CRC]
|
||||
- Адрес: 1 байт
|
||||
- Функция: 1 байт
|
||||
@@ -28,28 +29,37 @@
|
||||
#include "modbus_config.h"
|
||||
#include "modbus_data.h"
|
||||
#include "__crc_algs.h"
|
||||
#include "__modbus_compat.h"
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_MESSAGE_DEFINES Modbus Message Tools
|
||||
* @ingroup MODBUS
|
||||
* @brief Определения протокола модбас
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
//-------------DEFINES FOR STRUCTURE----------------
|
||||
/* defines for structure of modbus message */
|
||||
#define MbAddr_SIZE 1 ///< size of (MbAddr)
|
||||
#define Func_Code_SIZE 1 ///< size of (Func_Code)
|
||||
#define Addr_SIZE 2 ///< size of (Addr)
|
||||
#define Qnt_SIZE 2 ///< size of (Qnt)
|
||||
#define ByteCnt_SIZE 1 ///< size of (ByteCnt)
|
||||
#define TransactionID_size 2 ///< size of (Transaction ID)
|
||||
#define ProtocolID_size 2 ///< size of (Protocol ID)
|
||||
#define PDULength_size 2 ///< size of (PDU Length)
|
||||
#define MbAddr_SIZE 1 ///< size of (Slave Addr)
|
||||
#define Func_Code_SIZE 1 ///< size of (Function Code)
|
||||
#define Addr_SIZE 2 ///< size of (Address)
|
||||
#define Qnt_SIZE 2 ///< size of (Quantity)
|
||||
#define ByteCnt_SIZE 1 ///< size of (Byte Count)
|
||||
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
|
||||
#define CRC_SIZE 2 ///< size of (MbCRC) in bytes
|
||||
|
||||
/** @brief Size of whole message */
|
||||
#ifndef MODBUS_PROTOCOL_TCP
|
||||
/** @brief Size of whole RTU message */
|
||||
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
||||
#else
|
||||
/** @brief Size of whole TCP message */
|
||||
#define INFO_SIZE_MAX (TransactionID_size+ProtocolID_size+PDULength_size+MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE)
|
||||
#endif
|
||||
|
||||
/** @brief Size of first part of message that will be received
|
||||
first receive info part of message, than defines size of rest message*/
|
||||
@@ -58,100 +68,104 @@ first receive info part of message, than defines size of rest message*/
|
||||
/** @brief Size of buffer: max size of whole message */
|
||||
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
||||
|
||||
/** @brief Structure for modbus exception codes */
|
||||
/**
|
||||
* @brief Enum for modbus exception codes
|
||||
* @details Prefix ET for Error Type
|
||||
*/
|
||||
typedef enum //MB_ExceptionTypeDef
|
||||
{
|
||||
// reading
|
||||
NO_ERRORS = 0x00, ///< no errors
|
||||
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ACKNOWLEDGE = 0x05, ///< idk
|
||||
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
ET_NO_ERRORS = 0x00, ///< no errors
|
||||
ET_ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ET_ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ET_ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
ET_SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ET_ACKNOWLEDGE = 0x05, ///< idk
|
||||
// ET_SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// ET_MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
}MB_ExceptionTypeDef;
|
||||
|
||||
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/** @brief Structure for modbus func codes */
|
||||
#define FC_ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/**
|
||||
* @brief Enum for modbus func codes
|
||||
* @details Prefix FC for Function Code
|
||||
*/
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
/* COMMANDS */
|
||||
// reading
|
||||
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
#else
|
||||
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
FC_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
FC_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
#endif
|
||||
|
||||
// writting
|
||||
MB_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
FC_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
FC_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
FC_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
FC_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
|
||||
MB_R_DIAGNOSTIC = 0x08, ///< Чтение диагностической информации устройства
|
||||
MB_R_DEVICE_INFO = 0x2B, ///< Чтение информации об устройстве
|
||||
FC_R_DIAGNOSTICS = 0x08, ///< Чтение диагностической информации устройства
|
||||
FC_R_DEVICE_ID = 0x2B, ///< Чтение информации об устройстве
|
||||
|
||||
/* ERRORS */
|
||||
// error reading
|
||||
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
|
||||
// error writting
|
||||
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
FC_ERR_W_COIL = FC_W_COIL + FC_ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
FC_ERR_W_HOLD_REG = FC_W_HOLD_REG + FC_ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
|
||||
MB_ERR_R_DIAGNOSTIC = MB_R_DIAGNOSTIC + ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||
MB_ERR_R_DEVICE_INFO = MB_R_DEVICE_INFO + ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||
FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||
}MB_FunctonTypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
/** @brief Enum for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
|
||||
}MB_MEITypeDef;
|
||||
|
||||
/** @brief Structure for comformity */
|
||||
/**
|
||||
* @brief Enum for Read Device Id codes
|
||||
* @details Prefix RID for Read ID
|
||||
*/
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MB_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
||||
RID_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
||||
@details All objects of this category are mandatory:
|
||||
VendorName,Product code, and revision number */
|
||||
VendorName, Product code, and revision number */
|
||||
|
||||
MB_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
||||
RID_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
||||
@details The device provides additional and optional
|
||||
identifications and description data objects */
|
||||
|
||||
MB_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
||||
RID_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
||||
@details The device provides additional and optional
|
||||
identifications and description private data about the physical
|
||||
device itself. All of these data are device dependent. */
|
||||
|
||||
MB_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
||||
RID_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
||||
@details The device provides one specific identifications object. */
|
||||
|
||||
/* ERRORS */
|
||||
MB_ERR_BASIC_IDENTIFICATIONS = MB_BASIC_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_REGULAR_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_EXTENDED_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
MB_ERR_SPEDIFIC_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||
}MB_ConformityTypeDef;
|
||||
}MB_ReadDevId;
|
||||
|
||||
/** @brief Structure for decive identifications message type */
|
||||
/** @brief Structure for device identifications message type */
|
||||
typedef struct
|
||||
{
|
||||
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
|
||||
MB_ConformityTypeDef ReadDevId;
|
||||
MB_ConformityTypeDef Conformity;
|
||||
MB_ReadDevId ReadDevId;
|
||||
uint8_t Conformity; ///< Identification conformity level of the device and type of supported access @ref MODBUS_DEVICE_CONFORMITY
|
||||
uint8_t MoreFollows;
|
||||
uint8_t NextObjId;
|
||||
uint8_t NumbOfObj;
|
||||
@@ -161,17 +175,23 @@ typedef struct
|
||||
/** @brief Structure for modbus messsage */
|
||||
typedef struct // RS_MsgTypeDef
|
||||
{
|
||||
#ifdef MODBUS_PROTOCOL_TCP
|
||||
uint16_t TransactionID; ///< Modbus TCP: ID Transaction
|
||||
uint16_t ProtocolID; ///< Modbus TCP: ID Protocol
|
||||
uint16_t PDULength; ///< Modbus TCP: PDU Length
|
||||
#endif
|
||||
|
||||
uint8_t MbAddr; ///< Modbus Slave Address
|
||||
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
|
||||
MB_FunctonTypeDef FuncCode; ///< Modbus Function Code
|
||||
MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
|
||||
uint16_t Addr; ///< Modbus Address of data
|
||||
uint16_t Qnt; ///< Quantity of modbus data
|
||||
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
||||
|
||||
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
|
||||
uint16_t MbData[DATA_SIZE]; ///< Modbus Data
|
||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||
|
||||
uint16_t MB_CRC; ///< Modbus CRC
|
||||
uint16_t MbCRC; ///< Modbus CRC
|
||||
}RS_MsgTypeDef;
|
||||
//--------------------------------------------------
|
||||
extern RS_MsgTypeDef MODBUS_MSG;
|
||||
@@ -199,7 +219,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
||||
* @param _parr_ - массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
||||
@verbatim Пояснение выражений
|
||||
@code Пояснение выражений
|
||||
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
|
||||
|
||||
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
|
||||
@@ -207,14 +227,14 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
@endcode
|
||||
*/
|
||||
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
||||
/**
|
||||
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
||||
@verbatim Пояснение выражений
|
||||
@code Пояснение выражений
|
||||
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
|
||||
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
|
||||
|
||||
@@ -226,7 +246,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
@endcode
|
||||
*/
|
||||
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
||||
|
||||
@@ -271,7 +291,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Реализация этих функций лежит в modbus_data.c */
|
||||
@@ -285,8 +305,11 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
||||
/** MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
#endif //__MODBUS_CORE_H_
|
||||
/** MODBUS_INTERNAL
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_devid.h
|
||||
* @brief Идентификаторы устройства Modbus
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_DEVID Device Identifications Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
******************************************************************************
|
||||
@brief Функции для работы с идентификаторами устройства
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль реализации функции Read Device Identifications (0x2B):
|
||||
- Базовая идентификация (Vendor, Product, Revision)
|
||||
- Расширенная идентификация (URL, Model, User fields)
|
||||
- Поддержка потоковой передачи больших объектов
|
||||
|
||||
@section Объекты идентификации:
|
||||
@section devobj Объекты идентификации:
|
||||
- VendorName, ProductCode, Revision - обязательные
|
||||
- VendorUrl, ProductName, ModelName - опциональные
|
||||
- User objects - пользовательские поля
|
||||
@@ -31,6 +32,12 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if MODBUS_NUMB_OF_USEROBJECTS > 0
|
||||
#define MODBUS_DEVICE_CONFORMITY 0x83
|
||||
#else
|
||||
#define MODBUS_DEVICE_CONFORMITY 0x82
|
||||
#endif
|
||||
|
||||
/** @brief Структура для объекта (идентификатора устройства модбас) */
|
||||
typedef struct
|
||||
{
|
||||
@@ -102,7 +109,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj);
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Обработать функцию Read Device Identifications (43/14 - 0x2B/0E) */
|
||||
@@ -113,3 +120,4 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
#endif //__MODBUS_DEVID_H_
|
||||
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_diag.h
|
||||
* @brief Диагностика устройства Modbus
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_DIAG Diagnostics Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
******************************************************************************
|
||||
@brief Функции для работы с диагностикой
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль реализации Diagnostics (Serial Line only) (0x08):
|
||||
- Полная поддержка всех подфункций диагностики
|
||||
- Возможность выставить/сбросить любой бит в диагностическом регистре
|
||||
- Сбор статистики работы устройства
|
||||
- Управление режимами работы
|
||||
****************************************** ************************************/
|
||||
******************************************************************************/
|
||||
#ifndef __MODBUS_DIAG_H_
|
||||
#define __MODBUS_DIAG_H_
|
||||
#include "modbus_core.h"
|
||||
@@ -100,7 +101,7 @@ void MB_Diagnostics_SlaveBusyCnt(void);
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Обработка команды диагностики (0x08) */
|
||||
@@ -119,4 +120,5 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
/** MODBUS_DIAG
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_holdregs.h
|
||||
* @brief Работа с регистрами хранения Modbus
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_INS Input Register Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
******************************************************************************
|
||||
@brief Функции для работы с входными регистрами
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль для доступа к регистрам внутри программы:
|
||||
- Функции для доступа к регистрам хранения по глобальным адресам
|
||||
|
||||
Модуль обработки команд для регистров хранения (Holding Registers):
|
||||
- Чтение множества регистров (0x03)
|
||||
- Запись одиночного регистра (0x06)
|
||||
- Запись множества регистров (0x10)
|
||||
|
||||
@section Регистры хранения:
|
||||
@section hold Регистры хранения:
|
||||
- Read/Write доступ
|
||||
- 16-битные значения (uint16_t)
|
||||
******************************************************************************/
|
||||
@@ -41,7 +45,7 @@ uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
/* Обработать функцию Read Holding Registers (03 - 0x03) */
|
||||
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_inputregs.h
|
||||
* @brief Работа с входными регистрами Modbus
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_HOLD Holding Registers Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
******************************************************************************
|
||||
@brief Функции для работы с регистрами хранения
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль для доступа к регистрам внутри программы:
|
||||
- Функции для доступа к входным регистрам по глобальным адресам
|
||||
|
||||
Модуль обработки команд для входных регистров (Input Registers):
|
||||
- Чтение множества регистров (0x04)
|
||||
|
||||
@section Входные регистры:
|
||||
@section in Входные регистры:
|
||||
- Read-Only доступ
|
||||
- 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
|
||||
* @ingroup MODBUS_INTERNAL
|
||||
* @brief Функции обработки запросов модбас
|
||||
@{
|
||||
* @{
|
||||
*/
|
||||
/* Обработать функцию Read Input Registers (04 - 0x04) */
|
||||
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_master.h
|
||||
* @brief Главный заголовочный файл Modbus библиотеки
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_MASTER Modbus master funtions
|
||||
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
******************************************************************************
|
||||
@brief Функции для работы в режиме Master
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль реализации обработки UART сообщение в режиме мастер
|
||||
Модуль реализации Modbus в режиме мастер
|
||||
******************************************************************************/
|
||||
#ifndef __MODBUS_MASTER_H_
|
||||
#define __MODBUS_MASTER_H_
|
||||
@@ -17,7 +18,7 @@
|
||||
/**
|
||||
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Макросы для создания запросов в режиме мастер
|
||||
* @brief API для формирования фрейма-запроса в режиме мастер
|
||||
* @details Примеры использования:
|
||||
* @code
|
||||
* // Чтение 10 holding registers начиная с адреса 0
|
||||
@@ -80,24 +81,20 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
|
||||
* @code
|
||||
* // Пример: Запросили 10 регистров с адреса 100, хотим получить значение регистра 105
|
||||
* 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);
|
||||
* }
|
||||
*
|
||||
* // Пример: Получить все запрошенные регистры
|
||||
* 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))
|
||||
* {
|
||||
* printf("Register %d: %d\n", addr, value);
|
||||
* }
|
||||
* }
|
||||
* uint16_t reg_value[125];
|
||||
* MB_RespGet_RegisterAll(modbus_msg)
|
||||
* @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);
|
||||
|
||||
|
||||
@@ -115,7 +112,7 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
||||
* @code
|
||||
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
|
||||
* 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");
|
||||
* }
|
||||
@@ -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++)
|
||||
* {
|
||||
* 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");
|
||||
* }
|
||||
@@ -132,7 +129,9 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
||||
* @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);
|
||||
|
||||
/** 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)
|
||||
* uint8_t length;
|
||||
* 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;
|
||||
* 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);
|
||||
*
|
||||
* 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
|
||||
* // Получить данные диагностики (значение счетчика)
|
||||
* 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);
|
||||
* }
|
||||
@@ -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);
|
||||
|
||||
/** MODBUS_REQ_DIAG_API
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file modbus_slave.h
|
||||
* @brief Главный заголовочный файл Modbus библиотеки
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_SLAVE Modbus slave funtions
|
||||
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
******************************************************************************
|
||||
@brief Функции для работы в режиме Slave
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль реализации обработки UART сообщение в режиме слейв
|
||||
Модуль реализации Modbus в режиме слейв
|
||||
******************************************************************************/
|
||||
#ifndef __MODBUS_SLAVE_H_
|
||||
#define __MODBUS_SLAVE_H_
|
||||
|
||||
107
Inc/rs_message.h
107
Inc/rs_message.h
@@ -1,29 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @file rs_message.h
|
||||
* @brief Библиотека обмена сообщениями по RS-интерфейсу
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
@defgroup RS_TOOLS RS Tools
|
||||
@brief Всякое для работы по UART/RS
|
||||
@{
|
||||
******************************************************************************
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
|
||||
через UART в режиме прерываний с поддержкой таймаутов.
|
||||
|
||||
@section Основные возможности:
|
||||
@section posibility Основные возможности:
|
||||
- Прием/передача в прерываниях
|
||||
- Обработка IDLE линии для определения конца фрейма
|
||||
- Таймауты приема через TIM
|
||||
- Гибкая настройка размера сообщений
|
||||
|
||||
@section Использование:
|
||||
@section usage Использование:
|
||||
1. Определить структуру сообщения и размеры буфера
|
||||
2. Реализовать weak-функции обработки сообщений
|
||||
3. Добавить вызовы RS_UART_Handler/RS_TIM_Handler в прерывания
|
||||
4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT()
|
||||
|
||||
@section Особенности:
|
||||
@section features Особенности:
|
||||
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
|
||||
- Состояния: отслеживается через флаги в RS_HandleTypeDef
|
||||
- Таймауты: контролируют максимальное время ожидания фрейма
|
||||
@@ -76,42 +76,6 @@
|
||||
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
|
||||
|
||||
|
||||
#ifndef printf_rs_err
|
||||
#define printf_rs_err(...)
|
||||
#endif
|
||||
|
||||
#ifndef printf_rs
|
||||
#define printf_rs(...)
|
||||
#endif
|
||||
|
||||
#ifndef __MYLIBS_CONFIG_H_
|
||||
// дефайны из mylibs include
|
||||
static int dummy;
|
||||
#define TrackerTypeDef(num_user_vars) void *
|
||||
#define num_of_usercnts(_user_) 0
|
||||
#define assert_tracecnt(_cntstruct_, _uservarnumb_) 0
|
||||
#define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(0)
|
||||
#define tern_assert_usertracker(_cntstruct_, _uservarnumb_) 0
|
||||
#define TrackerGet_Ok(_cntstruct_) dummy
|
||||
#define TrackerGet_Err(_cntstruct_) dummy
|
||||
#define TrackerGet_Warn(_cntstruct_) dummy
|
||||
#define TrackerGet_User(_cntstruct_, _uservarnumb_) dummy
|
||||
#define TrackerCnt_Ok(_cntstruct_)
|
||||
#define TrackerCnt_Err(_cntstruct_)
|
||||
#define TrackerCnt_Warn(_cntstruct_)
|
||||
#define TrackerCnt_User(_cntstruct_, _uservarnumb_)
|
||||
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
|
||||
#define TrackerClear_All(_cntstruct_)
|
||||
#define TrackerClear_Ok(_cntstruct_)
|
||||
#define TrackerClear_Err(_cntstruct_)
|
||||
#define TrackerClear_Warn(_cntstruct_)
|
||||
#define TrackerClear_User(_cntstruct_)
|
||||
#define TrackerClear_UserAll(_cntstruct_)
|
||||
#else
|
||||
#include "mylibs_include.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef RS_USER_VARS_NUMB
|
||||
#define RS_USER_VARS_NUMB 0
|
||||
#endif
|
||||
@@ -122,6 +86,65 @@ static int dummy;
|
||||
/** @endcond */
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
|
||||
* @ingroup RS_TOOLS
|
||||
* @brief Дефайны для отладки периферии
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef RS_USER_VARS_NUMB
|
||||
#define RS_USER_VARS_NUMB 0 ///< Количество переменных в @ref TrackerTypeDef
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Тип структуры для счетчиков-переменных
|
||||
* @param num_user_vars Есть возмоность добавления num_user_vars количества пользовательскиъх переменных
|
||||
*/
|
||||
#define TrackerTypeDef(num_user_vars) void *
|
||||
/** @brief Инкрементировать переменную - успешных событий */
|
||||
#define TrackerCnt_Ok(_cntstruct_)
|
||||
/** @brief Инкрементировать переменную - ошибок */
|
||||
#define TrackerCnt_Err(_cntstruct_)
|
||||
/** @brief Инкрементировать переменную - предупреждений */
|
||||
#define TrackerCnt_Warn(_cntstruct_)
|
||||
|
||||
|
||||
|
||||
#ifndef printf_rs
|
||||
/** @brief Printf обычных событий RS/UART/TIM */
|
||||
#define printf_rs(...)
|
||||
#endif
|
||||
|
||||
#ifndef printf_rs_err
|
||||
/** @brief Printf ошибок RS/UART/TIM */
|
||||
#define printf_rs_err(...)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef RS_TIM_Handler_ENTER
|
||||
/** @brief Действия при заходе в прерывания таймера */
|
||||
#define RS_TIM_Handler_ENTER()
|
||||
#endif
|
||||
#ifndef RS_TIM_Handler_EXIT
|
||||
/** @brief Действия при выходе из прерывания таймера */
|
||||
#define RS_TIM_Handler_EXIT()
|
||||
#endif
|
||||
|
||||
#ifndef RS_UART_Handler_ENTER
|
||||
/** @brief Действия при заходе в прерывания UART */
|
||||
#define RS_UART_Handler_ENTER()
|
||||
#endif
|
||||
#ifndef RS_UART_Handler_EXIT
|
||||
/** @brief Действия при выходе из прерывания UART */
|
||||
#define RS_UART_Handler_EXIT()
|
||||
#endif
|
||||
/** RS_TOOLS
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// направление передачи rs485
|
||||
#ifndef RS_EnableReceive
|
||||
#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
|
||||
|
||||
Reference in New Issue
Block a user