release 0.3
Добавлен master, НО до конца не проверен
This commit is contained in:
36
Inc/modbus.h
36
Inc/modbus.h
@@ -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---/////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
* @}
|
||||
|
||||
@@ -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
|
||||
* @}
|
||||
|
||||
@@ -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
121
Inc/modbus_master.h
Normal 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, ®_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
34
Inc/modbus_slave.h
Normal 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
|
||||
* @}
|
||||
*/
|
||||
143
Inc/rs_message.h
143
Inc/rs_message.h
@@ -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---///////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user