release 0.3

Добавлен master, НО до конца не проверен
This commit is contained in:
2025-11-04 21:45:09 +03:00
parent 465f293397
commit 1d0d2c1650
21 changed files with 1728 additions and 663 deletions

View File

@@ -5,7 +5,7 @@
******************************************************************************
@addtogroup MODBUS Modbus tools
******************************************************************************
@addtogroup MODBUS_FUNCTIONS Modbus library funtions
@addtogroup MODBUS_FUNCTIONS Main API for Modbus Library
@ingroup MODBUS
@{
******************************************************************************
@@ -24,13 +24,28 @@
- Инициализировать хендл мобдас. По умолчанию глобально создается hmodbus1
- После для запуска Modbus:
@verbatim
//----------------Прием модбас----------------//
//----------------Слейв модбас----------------//
#include "modbus.h"
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
//MODBUS_Config(&hmodbus1, 1, 1000, 0); // - если нужны другие настройки, не из modbus_config.h
MODBUS_Config(&hmodbus1, 1, 1000, MODBUS_MODE_SLAVE);
MODBUS_SlaveStart(&hmodbus1, NULL);
@endverbatim
@verbatim
//----------------Мастер модбас----------------//
#include "modbus.h"
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER); // - если нужны другие настройки, не из modbus_config.h
// Запрос на 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)
{
// modbus_msg содержит ответ от устройства
}
@endverbatim
@section Подключаемые модули:
@@ -58,6 +73,8 @@
#define __MODBUS_H_
#include "rs_message.h"
#include "modbus_master.h"
#include "modbus_slave.h"
#include "modbus_coils.h"
#include "modbus_holdregs.h"
#include "modbus_inputregs.h"
@@ -71,21 +88,16 @@
//----------------FUNCTIONS FOR USER----------------
/**
* @addtogroup MODBUS_INIT_FUNCTIONS Functions for Init
* @ingroup MODBUS_FUNCTIONS
* @brief Функции для инициализации
@{
*/
/* Инициализация периферии модбас. */
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim);
/* Программная конфигурация модбас. */
HAL_StatusTypeDef MODBUS_Config(RS_HandleTypeDef *hmodbus, uint8_t ID, uint16_t Timeout, uint8_t master);
/* Запуск слейв устройства */
HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg);
/** MODBUS_INIT_FUNCTIONS
* @}
*/
/* Реквест мастера модбас */
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*));
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/////////////////////////---FUNCTIONS---/////////////////////////////

View File

@@ -82,11 +82,46 @@ typedef enum
/////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS Modbus Data Access
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS API for Data Access
* @ingroup MODBUS_FUNCTIONS
* @brief Функции для доступа к данным модбас
@{
*/
/**
* @addtogroup MODBUS_REQ_COILS_API API for Coils
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения coils из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
* int coil_state;
* if(MB_GetCoilState(&MODBUS_MSG, 25, &coil_state))
* {
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
* }
*
* // Пример: Получить состояние всех запрошенных coils
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
* {
* int state;
* if(MB_GetCoilState(&MODBUS_MSG, addr, &state))
* {
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
* }
* }
* @endcode
*/
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
/** MODBUS_REQ_COILS_API
* @}
*/
/**
* @brief Считать коил по локальному адресу.
@@ -137,9 +172,9 @@ uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
@{
*/
/* Обработать функцию Read Coils (01 - 0x01) */
uint8_t MB_Proccess_Read_Coils(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Single Coils (05 - 0x05) */
uint8_t MB_Proccess_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Multiple Coils (15 - 0x0F) */
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);

View File

@@ -117,39 +117,39 @@ typedef enum //MB_FunctonTypeDef
/** @brief Structure for MEI func codes */
typedef enum //MB_FunctonTypeDef
{
MEI_DEVICE_IDENTIFICATION = 0x0E,
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
}MB_MEITypeDef;
/** @brief Structure for comformity */
typedef enum //MB_FunctonTypeDef
{
MB_BASIC_IDENTIFICATION = 0x01, /*!< @brief Basic Device Identification.
MB_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
@details All objects of this category are mandatory:
VendorName,Product code, and revision number */
MB_REGULAR_IDENTIFICATION = 0x02, /*!< @brief Regular Device Identification.
MB_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
@details The device provides additional and optional
identification and description data objects */
identifications and description data objects */
MB_EXTENDED_IDENTIFICATION = 0x03, /*!< @brief Extended Device Identification.
MB_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
@details The device provides additional and optional
identification and description private data about the physical
identifications and description private data about the physical
device itself. All of these data are device dependent. */
MB_SPEDIFIC_IDENTIFICATION = 0x04, /*!< @brief Specific Device Identification.
@details The device provides one specific identification object. */
MB_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
@details The device provides one specific identifications object. */
/* ERRORS */
MB_ERR_BASIC_IDENTIFICATION = MB_BASIC_IDENTIFICATION + ERR_VALUES_START,
MB_ERR_REGULAR_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START,
MB_ERR_EXTENDED_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START,
MB_ERR_SPEDIFIC_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START,
MB_ERR_BASIC_IDENTIFICATIONS = MB_BASIC_IDENTIFICATIONS + ERR_VALUES_START,
MB_ERR_REGULAR_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
MB_ERR_EXTENDED_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
MB_ERR_SPEDIFIC_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
}MB_ConformityTypeDef;
/** @brief Structure for decive identification message type */
/** @brief Structure for decive identifications message type */
typedef struct
{
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identification Interface
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
MB_ConformityTypeDef ReadDevId;
MB_ConformityTypeDef Conformity;
uint8_t MoreFollows;
@@ -163,7 +163,7 @@ typedef struct // RS_MsgTypeDef
{
uint8_t MbAddr; ///< Modbus Slave Address
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
MB_DevIdMsgTypeDef DevId; ///< Read Device Identification Header struct
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

View File

@@ -3,12 +3,12 @@
* @file modbus_devid.h
* @brief Идентификаторы устройства Modbus
******************************************************************************
@addtogroup MODBUS_DEVID Device Identificators Tools
@addtogroup MODBUS_DEVID Device Identifications Tools
@ingroup MODBUS_INTERNAL
@{
******************************************************************************
* @details
Модуль реализации функции Read Device Identification (0x2B):
Модуль реализации функции Read Device Identifications (0x2B):
- Базовая идентификация (Vendor, Product, Revision)
- Расширенная идентификация (URL, Model, User fields)
- Поддержка потоковой передачи больших объектов
@@ -48,8 +48,8 @@ typedef struct
MB_DeviceObjectTypeDef Reserved[0x79];
MB_DeviceObjectTypeDef User[MODBUS_NUMB_OF_USEROBJECTS];
}MB_DeviceIdentificationTypeDef;
extern MB_DeviceIdentificationTypeDef MB_DEVID;
}MB_DeviceIdentificationsTypeDef;
extern MB_DeviceIdentificationsTypeDef MB_DEVID;
void MB_DeviceInentificationInit(void);
///////////////---DEVICE IDENTIVICATIONS DEFINES---//////////////////
@@ -77,6 +77,52 @@ void MB_DeviceInentificationInit(void);
/////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
* @ingroup MODBUS_REQUEST_MSG
* @brief Макросы для чтения идентификторов из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример 1: Получить VendorName (ID = 0x00)
* uint8_t length;
* char vendor_name[64];
* if(MB_FindObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
* {
* // получено
* }
*
* // Пример 2: Перебрать все объекты в сообщении
* uint8_t obj_id, obj_length;
* char obj_data[256];
*
* int obj_count = MB_GetNumberOfObjects(&MODBUS_MSG);
* printf("Total objects: %d\n", obj_count);
*
* for(int i = 0; i < obj_count; i++)
* {
* if(MB_GetObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
* {
* // получено
* }
* }
* @endcode
*/
/* Получить количество объектов в сообщении */
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg);
/* Найти объект по ID в сообщении */
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
/* Получить объект по индексу в сообщении */
int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length);
/** MODBUS_REQ_DEFID_API
* @}
*/
/* Записать Один Объект Идентификатора в массив данных */
void MB_WriteSingleObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj);
/* Записать Массив Объектов Идентификатора в массив данных */
@@ -88,8 +134,8 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj);
@{
*/
/* Обработать функцию Read Device Identification (43/14 - 0x2B/0E) */
uint8_t MB_Proccess_Read_Device_Identification(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Read Device Identifications (43/14 - 0x2B/0E) */
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
/** MODBUS_CMD_PROCESS_FUNCTIONS
* @}
*/

View File

@@ -53,12 +53,39 @@ extern MB_DiagnosticsInfoTypeDef MB_DIAG;
/////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---/////////////////////////////
/* Инициализация диагностических счетчиков */
void MB_DiagnosticsInit(void);
/**
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения диагностической информации из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* Получить данные диагностики (значение счетчика)
* uint16_t counter_value;
* if(MB_GetDiagnosticResponse(&MODBUS_MSG, &counter_value))
* {
* printf("Counter value: %d\n", counter_value);
* }
* @endcode
*/
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data);
/** MODBUS_REQ_DIAG_API
* @}
*/
/**
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS Modbus Data Access
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
@{
*/
@@ -79,7 +106,7 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void);
*/
/* Обработка команды диагностики (0x08) */
uint8_t MB_Proccess_Diagnostics(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
/** MODBUS_CMD_PROCESS_FUNCTIONS
* @}

View File

@@ -30,11 +30,11 @@
@{
*/
/* Обработать функцию Read Holding Registers (03 - 0x03) */
uint8_t MB_Proccess_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Single Coils (06 - 0x06) */
uint8_t MB_Proccess_Write_Single_Reg(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg);
/* Обработать функцию Write Multiple Register (16 - 0x10) */
uint8_t MB_Proccess_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
/** MODBUS_CMD_PROCESS_FUNCTIONS
* @}

View File

@@ -24,13 +24,13 @@
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
/**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Proccess Functions
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
* @ingroup MODBUS_FUNCTIONS
* @brief Функции обработки запросов модбас
@{
*/
/* Обработать функцию Read Input Registers (04 - 0x04) */
uint8_t MB_Proccess_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
/** MODBUS_CMD_PROCESS_FUNCTIONS
* @}

121
Inc/modbus_master.h Normal file
View File

@@ -0,0 +1,121 @@
/**
******************************************************************************
* @file modbus_master.h
* @brief Главный заголовочный файл Modbus библиотеки
******************************************************************************
@addtogroup MODBUS_MASTER Modbus master funtions
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
@{
******************************************************************************
* @details
Модуль реализации обработки UART сообщение в режиме мастер
******************************************************************************/
#ifndef __MODBUS_MASTER_H_
#define __MODBUS_MASTER_H_
#include "rs_message.h"
#ifdef MODBUS_ENABLE_MASTER
#define MODBUS_MODE_MASTER 1
#endif
/**
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
* @ingroup MODBUS_FUNCTIONS
* @brief Макросы для создания запросов в режиме мастер
* @details Примеры использования:
*
* // Чтение 10 holding registers начиная с адреса 0
* RS_MsgTypeDef read_msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
*
* // Запись одного coil
* RS_MsgTypeDef write_coil_msg = MB_REQUEST_WRITE_SINGLE_COIL(1, 5, 1);
*
* // Диагностический запрос
* RS_MsgTypeDef diag_msg = MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(1);
*
* // Идентификация устройства
* RS_MsgTypeDef dev_id_msg = MB_REQUEST_READ_DEVICE_ID_BASIC(1);
*/
//---------КЛАССИЧЕСКИЕ ДАННЫЕ-----------
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity);
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity);
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity);
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity);
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value);
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value);
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data);
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data);
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data);
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data);
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr);
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr);
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id);
/** MODBUS_REQUEST_MSG
* @}
*/
/**
* @addtogroup MODBUS_REGS_API API for Registers
* @ingroup MODBUS_REQUEST_MSG
* @brief API для чтения регистров из ответа в режиме мастер
* @details Примеры использования:
*
* @code
* // Пример: Запросили 10 регистров с адреса 100, хотим получить значение регистра 105
* uint16_t reg_value;
* if(MB_GetRegisterValue(&MODBUS_MSG, 105, &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 value;
* if(MB_GetRegisterValue(&MODBUS_MSG, addr, &value))
* {
* printf("Register %d: %d\n", addr, value);
* }
* }
* @endcode
*/
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value);
/** MODBUS_REQ_REGS_API
* @}
*/
/* Сбор сообщения в буфер UART в режиме мастер (фрейм мастера из msg -> uart) */
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
/* Парс сообщения в режиме мастер (фрейм слейва из uart -> msg) */
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
#endif //__MODBUS_MASTER_H_
/** MODBUS_MASTER
* @}
*/

34
Inc/modbus_slave.h Normal file
View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* @file modbus_slave.h
* @brief Главный заголовочный файл Modbus библиотеки
******************************************************************************
@addtogroup MODBUS_SLAVE Modbus slave funtions
@ingroup MODBUS_CMD_PROCESS_FUNCTIONS
@{
******************************************************************************
* @details
Модуль реализации обработки UART сообщение в режиме слейв
******************************************************************************/
#ifndef __MODBUS_SLAVE_H_
#define __MODBUS_SLAVE_H_
#include "rs_message.h"
#ifdef MODBUS_ENABLE_SLAVE
#define MODBUS_MODE_SLAVE 0
#endif
/* Ответ на сообщение в режиме слейва */
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg);
/* Сбор сообщения в буфер UART в режиме слейв (фрейм слейва из msg -> uart) */
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
/* Парс сообщения в режиме слейв (фрейм мастера из uart -> msg) */
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff);
#endif //__MODBUS_SLAVE_H_
/** MODBUS_MASTER
* @}
*/

View File

@@ -40,10 +40,6 @@
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
#endif
#ifndef RX_FIRST_PART_SIZE
#error Define RX_FIRST_PART_SIZE (Size of first part of message). This is necessary to receive the first part of the message, from which determine the size of the remaining part of the message.
#endif
/**
* @cond Заглушки и внутренний недокументированный стаф
*/
@@ -55,14 +51,14 @@
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0;
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0; _hRS_->f.RX_Continue = 0;
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0;
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
@@ -79,13 +75,6 @@
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
// направление передачи rs485
#ifndef RS_EnableReceive
#define RS_EnableReceive()
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit()
#endif
#ifndef printf_rs_err
#define printf_rs_err(...)
@@ -122,10 +111,20 @@ static int dummy;
#include "mylibs_include.h"
#endif
#ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0
#endif
/** @endcond */
// направление передачи rs485
#ifndef RS_EnableReceive
#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit() ///< Функция изменения направления передачи на ПЕРЕДАЧУ для RS-485
#endif
////////////////////////////---DEFINES---////////////////////////////
@@ -151,61 +150,44 @@ typedef enum // RS_StatusTypeDef
}RS_StatusTypeDef;
#define RS_MASTER_START 0x3
#define RS_MASTER_MODE_START 0x3 ///< Начало режимов мастера (до него - режим слейв)
/** @brief Enums for RS Modes */
typedef enum // RS_ModeTypeDef
{
RS_SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
RS_SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
// RS_MASTER = 0x03, ///< Master mode
RS_SLAVE_ALWAYS_WAIT = 0x01, ///< Слейв в постоянном ожидании
RS_RESERVED = 0x02, ///< резерв
RS_MASTER_REQUEST = 0x03, ///< Мастер с ручным запросом
//RS_MASTER_POLLING = 0x04, ///< Мастер с опросом в фоновом режиме
}RS_ModeTypeDef;
/** @brief Enums for RS UART Modes */
typedef enum // RS_ITModeTypeDef
{
BLCK_MODE = 0x00, ///< Blocking mode
IT_MODE = 0x01, ///< Interrupt mode
}RS_ITModeTypeDef;
/** @brief Enums for Abort modes */
typedef enum // RS_AbortTypeDef
{
ABORT_TX = 0x01, ///< Abort transmit
ABORT_RX = 0x02, ///< Abort receive
ABORT_RX_TX = 0x03, ///< Abort receive and transmit
ABORT_RS = 0x04, ///< Abort uart and reset RS structure
ABORT_TX = 0x01, ///< Отменить передачу
ABORT_RX = 0x02, ///< Отменить прием
ABORT_RX_TX = 0x03, ///< Отменить прием и передачу
ABORT_RS = 0x04, ///< Отменить любую работу UART в целом
}RS_AbortTypeDef;
/** @brief Enums for RX Size modes */
typedef enum // RS_RXSizeTypeDef
{
RS_RX_Size_Const = 0x01, ///< size of receiving message is constant
RS_RX_Size_NotConst = 0x02, ///< size of receiving message isnt constant
}RS_RXSizeTypeDef;
//-----------STRUCTURE FOR HANDLE RS------------
/** @brief Struct for flags RS */
typedef struct
{
unsigned RX_Half:1; ///< flag: 0 - receiving msg before ByteCnt, 0 - receiving msg after ByteCnt
unsigned RS_Busy:1; ///< 1 - RS занят, 0 - RS свободен
unsigned RX_Ongoing:1; ///< 1 - Прием данных в активном состоянии, 0 - Ожидаем начало приема данных
unsigned RS_Busy:1; ///< flag: 1 - RS is busy, 0 - RS isnt busy
unsigned RX_Ongoing:1; ///< flag: 1 - receiving data right now, 0 - waiting for receiving data
unsigned RX_Busy:1; ///< 1 - Режим приема активен, 0 - Прием не активен
unsigned TX_Busy:1; ///< 1 - Режим передачи активен, 0 - Прием не активен
unsigned RX_Busy:1; ///< flag: 1 - receiving is active, 0 - receiving isnt active
unsigned TX_Busy:1; ///< flag: 1 - transmiting is active, 0 - transmiting isnt active
unsigned RX_Done:1; ///< flag: 1 - receiving is done, 0 - receiving isnt done
unsigned TX_Done:1; ///< flag: 1 - transmiting is done, 0 - transmiting isnt done
unsigned RX_Done:1; ///< 1 - Прием закончен, 0 - Прием еще в процессе или не инициализирован
unsigned TX_Done:1; ///< 1 - Передача закончена, 0 - Передача еще в процессе или не инициализирована
// setted by user
unsigned RX_Continue:1; ///< flag: 0 - continue receiving, 0 - start receiving from ind = 0
unsigned MessageHandled:1; ///< flag: 1 - RS command is handled, 0 - RS command isnt handled yet
unsigned EchoResponse:1; ///< flag: 1 - response with received msg, 0 - response with own msg
unsigned DeferredResponse:1; ///< flag: 1 - response not in interrupt, 0 - response in interrupt
unsigned DataUpdated:1; ///< flag: 1 - Received command to write colis/resg
unsigned ReInit_UART:1; ///< flag: 1 - need to reinitialize uart, 0 - nothing
// Выставление следующие флагов определяет пользователь
unsigned RX_Continue:1; ///< 0 - Продолжить принимать, 0 - Начать прием сначала
unsigned MessageHandled:1; ///< 1 - Обработка запроса успешна, 0 - Обработка запроса в процессе или ошибка
unsigned EchoResponse:1; ///< 1 - Ответить эхом, 0 - Ответить своим сообщением
unsigned DeferredResponse:1; ///< 1 - Не начинать передачу в IT, 0 - Ответить в прерывании
unsigned DataUpdated:1; ///< 1 - Данные были обновлены
}RS_FlagsTypeDef;
@@ -217,25 +199,24 @@ typedef struct
typedef struct // RS_HandleTypeDef
{
/* MESSAGE */
uint8_t ID; ///< ID of RS "channel"
RS_MsgTypeDef *pMessagePtr; ///< pointer to message struct
uint8_t *pBufferPtr; ///< pointer to message buffer
uint8_t ID; ///< ID хендла
RS_MsgTypeDef *pMessagePtr; ///< Указатель на структуру протокола
uint8_t *pBufferPtr; ///< Указатеь на буфер UART
int32_t RS_Message_Size; ///< size of whole message, not only data
/* HANDLERS and SETTINGS */
UART_HandleTypeDef *huart; ///< handler for used uart
TIM_HandleTypeDef *htim; ///< handler for used tim
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
RS_ITModeTypeDef sRS_IT_Mode; ///< setting: 1 - IT mode, 0 - Blocking mode
uint16_t sRS_Timeout; ///< setting: timeout in ms
RS_RXSizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
UART_HandleTypeDef *huart; ///< Хендл UART
TIM_HandleTypeDef *htim; ///< Хендл TIM
RS_ModeTypeDef sRS_Mode; ///< Настройка: слейв/мастер @ref RS_ModeTypeDef
uint16_t sRS_Timeout; ///< Настройка: Таймаут в тиках таймера
void (*pCallback)(void*, void*); ///< Указатель на коллбек: принят ответ в режиме мастер
/* FLAGS */
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
RS_FlagsTypeDef f; ///< Флаги для контроля приема/передачи
/* RS STATUS */
uint32_t lastPacketTick;
RS_StatusTypeDef RS_STATUS; ///< RS status
uint32_t lastPacketTick; ///< Время последнего принятого пакета
RS_StatusTypeDef RS_STATUS; ///< Статус RS
TrackerTypeDef(RS_USER_VARS_NUMB) rs_err;
}RS_HandleTypeDef;
@@ -249,47 +230,53 @@ extern RS_HandleTypeDef hmodbus1;
///////////////////////////---FUNCTIONS---///////////////////////////
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
/*--------------------Defined by users purposes--------------------*/
/* Respond accord to received message */
/* Пользовательская функция для ответа на запрос по UART */
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Collect message in buffer to transmit it */
/* Пользовательская функция для обработки принятого ответа по UART */
__weak RS_StatusTypeDef RS_Response_Callback(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Пользовательская функция для сбора сообщения в буфер UART */
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
/* Parse message from buffer to process it */
/* Пользовательская функция для парса сообщения из буфера UART */
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
//-------------------------GENERAL FUNCTIONS-------------------------
/*-----------------Should be called from main code-----------------*/
/* Start receive IT */
/* Начать прием по прерываниям */
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Start transmit IT */
/* Начать передачу по прерываниям */
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Initialize UART and handle RS stucture */
/* Инициалазация структуры @ref RS_HandleTypeDef */
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
/* ReInitialize UART and RS receive */
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *suart);
/* Abort RS/UART */
/* Отменить прием/передачу RS/UART */
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
//-------------------------GENERAL FUNCTIONS-------------------------
//-------------------------------------------------------------------
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
/* Handle for starting receive */
/* Обработчик для начала приема */
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Handle for starting transmit */
/* Обработчик для начала передачи */
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* UART TX Callback: define behaviour after transmiting message */
/* UART TX Callback: коллбек после окончания передачи */
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
/* Handler for UART */
/* Обработчик прерывания UART */
void RS_UART_Handler(RS_HandleTypeDef *hRS);
/* Handler for TIM */
/* Обработчик прерывания TIM */
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
/* Запуск таймаута приема. */
RS_StatusTypeDef RS_Timeout_Start(RS_HandleTypeDef *hRS);
/* Остановка таймаута приема. */
RS_StatusTypeDef RS_Timeout_Stop(RS_HandleTypeDef *hRS);
/* Обновление (сброс) таймаута приема. */
RS_StatusTypeDef RS_Timeout_Update(RS_HandleTypeDef *hRS);
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
///////////////////////////---FUNCTIONS---///////////////////////////