release 0.5 (*API CHANGED)
- чуть переделаны некоторые дефайны для универсализации - смена направления сделана через указател на функцию, а не глобальный дефайн - добавлен бета осцилограф модбас - некоторый рефакторинг
This commit is contained in:
@@ -65,6 +65,9 @@ CREATE_DEPRECATED_ALIAS(MB_EXTENDED_IDENTIFICATIONS, RID_EXTENDED_IDENTIFICATIO
|
||||
CREATE_DEPRECATED_ALIAS(MB_SPEDIFIC_IDENTIFICATIONS, RID_SPEDIFIC_IDENTIFICATIONS, MB_ReadDevId);
|
||||
|
||||
|
||||
#define MbAddr DeviceAddr
|
||||
|
||||
|
||||
/** MODBUS_LEGACY_API
|
||||
* @}
|
||||
*/
|
||||
|
||||
20
Inc/modbus.h
20
Inc/modbus.h
@@ -29,7 +29,7 @@
|
||||
//----------------Слейв модбас----------------//
|
||||
#include "modbus.h"
|
||||
|
||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3, NULL); // NULL, если управление RE/DE не нужно
|
||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||
@endcode
|
||||
@@ -37,19 +37,24 @@
|
||||
//----------------Мастер модбас----------------//
|
||||
#include "modbus.h"
|
||||
|
||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3, NULL); // NULL, если управление RE/DE не нужно
|
||||
MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
|
||||
|
||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||
// При получении ответа вызовется функция callback_func()
|
||||
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)
|
||||
|
||||
|
||||
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))
|
||||
{
|
||||
@@ -57,6 +62,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Ответ получен с ошибкой или не получен вовсе
|
||||
{
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@@ -107,6 +115,10 @@
|
||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
||||
#include "modbus_diag.h"
|
||||
#endif
|
||||
#ifdef MODBUS_ENABLE_OSCIL
|
||||
#include "modbus_oscil.h"
|
||||
#endif
|
||||
#include "modbus_data.h"
|
||||
|
||||
|
||||
#ifdef MODBUS_ENABLE_MASTER
|
||||
@@ -124,7 +136,7 @@
|
||||
//----------------FUNCTIONS FOR USER----------------
|
||||
|
||||
/* Инициализация периферии модбас. */
|
||||
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim);
|
||||
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, void (*pSetDirection)(int Tx));
|
||||
/* Программная конфигурация модбас. */
|
||||
HAL_StatusTypeDef MODBUS_Config(RS_HandleTypeDef *hmodbus, uint8_t ID, uint16_t Timeout, uint8_t master);
|
||||
/* Запуск слейв устройства */
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#define __MODBUS_CORE_H_
|
||||
|
||||
#include "modbus_config.h"
|
||||
#include "modbus_data.h"
|
||||
#include "__crc_algs.h"
|
||||
|
||||
/**
|
||||
@@ -41,31 +40,31 @@
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
//-------------DEFINES FOR STRUCTURE----------------
|
||||
/* defines for structure of modbus message */
|
||||
#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 (MbCRC) in bytes
|
||||
#define MbTransactionID_size 2 ///< size of (Transaction ID)
|
||||
#define MbProtocolID_size 2 ///< size of (Protocol ID)
|
||||
#define MbPDULength_size 2 ///< size of (PDU Length)
|
||||
#define MbDeviceAddr_size 1 ///< size of (Slave Addr)
|
||||
#define MbFuncCode_size 1 ///< size of (Function Code)
|
||||
#define MbAddr_size 2 ///< size of (Address)
|
||||
#define MbQnt_size 2 ///< size of (Quantity)
|
||||
#define MbByteCnt_size 1 ///< size of (Byte Count)
|
||||
#define MbData_size 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||
#define MbCRC_size 2 ///< size of (MbCRC) in bytes
|
||||
|
||||
#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)
|
||||
#define RS_INFO_SIZE_MAX (MbDeviceAddr_size+MbFuncCode_size+MbAddr_size+MbQnt_size+MbByteCnt_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)
|
||||
#define RS_INFO_SIZE_MAX (MbTransactionID_size+MbProtocolID_size+MbPDULength_size+MbDeviceAddr_size+MbFuncCode_size+MbAddr_size+MbQnt_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*/
|
||||
#define RX_FIRST_PART_SIZE INFO_SIZE_MAX
|
||||
#define RS_RX_FIRST_PART_SIZE RS_INFO_SIZE_MAX
|
||||
|
||||
/** @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
|
||||
#define RS_MSG_SIZE_MAX (RS_INFO_SIZE_MAX + MbData_size*2 + MbCRC_size) // max possible size of message
|
||||
|
||||
/**
|
||||
* @brief Enum for modbus exception codes
|
||||
@@ -129,7 +128,9 @@ typedef enum //MB_FunctonTypeDef
|
||||
FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||
}MB_FunctonTypeDef;
|
||||
|
||||
/** @brief Enum for MEI func codes */
|
||||
/**
|
||||
* @brief Enum for MEI func codes
|
||||
*/
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
|
||||
@@ -180,14 +181,14 @@ typedef struct // RS_MsgTypeDef
|
||||
uint16_t PDULength; ///< Modbus TCP: PDU Length
|
||||
#endif
|
||||
|
||||
uint8_t MbAddr; ///< Modbus Slave Address
|
||||
uint8_t DeviceAddr; ///< Modbus Slave Address
|
||||
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 MbData[DATA_SIZE]; ///< Modbus Data
|
||||
uint16_t MbData[MbData_size]; ///< Modbus Data
|
||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||
|
||||
uint16_t MbCRC; ///< Modbus CRC
|
||||
@@ -298,7 +299,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
||||
/* Check is address valid for certain array */
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB);
|
||||
/* Define Address Origin for Input/Holding Registers */
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType);
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType, uint8_t WriteFlag);
|
||||
/* Define Address Origin for coils */
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag);
|
||||
/** MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* @file modbus_holdregs.h
|
||||
* @brief Работа с регистрами хранения Modbus
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_INS Input Register Tools
|
||||
@addtogroup MODBUS_HOLD Holding Registers Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
@brief Функции для работы с входными регистрами
|
||||
@brief Функции для работы с регистрами хранения
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль для доступа к регистрам внутри программы:
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* @file modbus_inputregs.h
|
||||
* @brief Работа с входными регистрами Modbus
|
||||
*******************************************************************************
|
||||
@addtogroup MODBUS_HOLD Holding Registers Tools
|
||||
@addtogroup MODBUS_INS Input Register Tools
|
||||
@ingroup MODBUS_INTERNAL
|
||||
@brief Функции для работы с регистрами хранения
|
||||
@brief Функции для работы с входными регистрами
|
||||
*******************************************************************************
|
||||
* @details
|
||||
Модуль для доступа к регистрам внутри программы:
|
||||
|
||||
111
Inc/modbus_oscil.h
Normal file
111
Inc/modbus_oscil.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file modbus_oscil.h
|
||||
* @brief Заголовочный файл модуля осциллографа через MODBUS.
|
||||
*******************************************************************************
|
||||
* @addtogroup MODBUS_OSCIL Modbus Oscilloscope
|
||||
* @ingroup MODBUS
|
||||
* @brief Модуль для сбора и хранения данных осциллографа
|
||||
* @details
|
||||
* Реализует кольцевой буфер для хранения данных с нескольких каналов
|
||||
* с возможностью чтения через Modbus. Данные 8-битные, упаковываются
|
||||
* по 2 сэмпла в 16-битный регистр Modbus.
|
||||
*
|
||||
* Карта Modbus регистров (адрес относительный):
|
||||
* | Адрес | Биты | Назначение | Диапазон | Описание |
|
||||
* |--------|------|------------|----------|----------|
|
||||
* | 0x0000 | 0-3 | channels | 1-16 | Количество каналов |
|
||||
* | | 4-7 | reserved | 0 | Зарезервировано |
|
||||
* | | 8-15 | buffer_size| 1-125 | Размер буфера в регистрах |
|
||||
* | 0x0001 | 0-7 | tail | 0-124 | Начало новых данных |
|
||||
* | | 8-15 | head | 0-124 | Конец новых данных |
|
||||
* | 0x0002...| 0-15| data | - | Буфер данных |
|
||||
* @{
|
||||
******************************************************************************/
|
||||
#ifndef __MODBUS_OSCIL_H_
|
||||
#define __MODBUS_OSCIL_H_
|
||||
|
||||
#include "modbus_core.h"
|
||||
|
||||
#ifdef MODBUS_ENABLE_OSCIL
|
||||
|
||||
|
||||
/**
|
||||
* @brief Структура конфигурации осциллографа
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/* Адрес 0 */
|
||||
uint16_t Overrun:1; ///< Overrun
|
||||
uint16_t NumbOfChannels:4; ///< Количество каналов (1-16)
|
||||
uint16_t BufferSize:7; ///< Размер буфера в регистрах (1-125)
|
||||
|
||||
uint16_t SampleTime; ///< Адрес 1: Время между сэмплами в мкс/мс
|
||||
uint16_t reserved[2]; ///< Резерв
|
||||
uint32_t LastTick; ///< Адрес 4-5: Время последнего добавления (uint32_t)
|
||||
} MB_ConfigTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Структура указателей буфера
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Head:8; ///< Указатель на последний записанный байт
|
||||
uint16_t Tail:8; ///< Указатель на начало непрочитанных данных (байты)
|
||||
} MB_PreambleTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Основная структура осциллографа
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MB_ConfigTypeDef Config; /*!< @brief Отн. Адрес 0-6: Конфигурация */
|
||||
uint16_t User[4]; /*!< @brief Отн. Адрес 6-9: Пользовательские регистры */
|
||||
MB_PreambleTypeDef Preamble; /*!< @brief Отн. Адрес 10: Указатели head и tail буфера */
|
||||
uint8_t Data[MbData_size*2-1]; ///< /*!< @brief Отн. Адрес 11-131: Буфер данных (в байтах) */
|
||||
} MB_OscilTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_OSCIL_API API for Oscilloscope
|
||||
* @ingroup MODBUS_OSCIL
|
||||
* @brief API для работы с буфером осциллографа
|
||||
* @details Примеры использования:
|
||||
* @code
|
||||
* MB_OscilTypeDef oscil;
|
||||
*
|
||||
* // Инициализация осциллографа
|
||||
* MB_Oscil_Init(&oscil, 120, 4, 1000);
|
||||
*
|
||||
* // В цикле сбора данных
|
||||
* uint8_t ch_data[4] = {adc1, adc2, adc3, adc4};
|
||||
* MB_Oscil_Add(&oscil, ch_data);
|
||||
*
|
||||
* // После чтения данных через Modbus
|
||||
* MB_Oscil_UpdateTail(&oscil);
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Инициализация структуры осциллографа */
|
||||
HAL_StatusTypeDef MB_Oscil_Init(MB_OscilTypeDef *oscil, uint8_t BufferSize, uint8_t NumbOfChannels, uint16_t SampleTime);
|
||||
|
||||
/* Добавление данных всех каналов в буфер */
|
||||
HAL_StatusTypeDef MB_Oscil_Add(MB_OscilTypeDef *oscil, uint8_t *Data);
|
||||
|
||||
/* Обновление указателя Tail */
|
||||
HAL_StatusTypeDef MB_Oscil_UpdateTail(MB_OscilTypeDef *oscil);
|
||||
|
||||
/** MODBUS_OSCIL_API
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif //MODBUS_ENABLE_OSCIL
|
||||
|
||||
#endif //__MODBUS_OSCIL_H_
|
||||
|
||||
/** MODBUS_OSCIL
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT()
|
||||
|
||||
@section features Особенности:
|
||||
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
|
||||
- Буфер: RS_Buffer[RS_MSG_SIZE_MAX] Общий для приема/передачи
|
||||
- Состояния: отслеживается через флаги в RS_HandleTypeDef
|
||||
- Таймауты: контролируют максимальное время ожидания фрейма
|
||||
******************************************************************************/
|
||||
@@ -36,8 +36,8 @@
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////---DEFINES---////////////////////////////
|
||||
/* Check that all defines required by RS are defined */
|
||||
#ifndef MSG_SIZE_MAX
|
||||
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
|
||||
#ifndef RS_MSG_SIZE_MAX
|
||||
#error Define RS_MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@
|
||||
*/
|
||||
|
||||
/* Clear message-uart buffer */
|
||||
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
|
||||
#define RS_Clear_Buff(_buff_) for(int i=0; i<RS_MSG_SIZE_MAX;i++) _buff_[i] = NULL
|
||||
|
||||
/* Set/Reset flags */
|
||||
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
|
||||
@@ -68,7 +68,7 @@
|
||||
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
|
||||
|
||||
/* Clear all RS stuff */
|
||||
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
|
||||
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->BufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
|
||||
|
||||
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
|
||||
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
|
||||
@@ -237,7 +237,7 @@ typedef struct // RS_HandleTypeDef
|
||||
/* MESSAGE */
|
||||
uint8_t ID; ///< ID хендла
|
||||
RS_MsgTypeDef *pMessagePtr; ///< Указатель на структуру протокола
|
||||
uint8_t *pBufferPtr; ///< Указатеь на буфер UART
|
||||
uint8_t BufferPtr[RS_MSG_SIZE_MAX]; ///< Указатеь на буфер UART
|
||||
int32_t RS_Message_Size; ///< size of whole message, not only data
|
||||
|
||||
/* HANDLERS and SETTINGS */
|
||||
@@ -245,6 +245,7 @@ typedef struct // RS_HandleTypeDef
|
||||
TIM_HandleTypeDef *htim; ///< Хендл TIM
|
||||
RS_ModeTypeDef sRS_Mode; ///< Настройка: слейв/мастер @ref RS_ModeTypeDef
|
||||
uint16_t sRS_Timeout; ///< Настройка: Таймаут в тиках таймера
|
||||
void (*pSetDirection)(int Tx); ///< Указатель на функцию: смена направления
|
||||
void (*pCallback)(void*, void*); ///< Указатель на коллбек: принят ответ в режиме мастер
|
||||
|
||||
/* FLAGS */
|
||||
@@ -288,7 +289,7 @@ RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Инициалазация структуры @ref RS_HandleTypeDef */
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, void (*pSetDirection)(int Tx));
|
||||
|
||||
/* Отменить прием/передачу RS/UART */
|
||||
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
|
||||
|
||||
Reference in New Issue
Block a user