Loading...
Searching...
No Matches
modbus.c
Go to the documentation of this file.
/**
*******************************************************************************
* @file modbus.c
* @brief Модуль для реализации MODBUS.
*******************************************************************************
* @details
Файл содержит реализацию функций работы с Modbus.
@section mbapi Функции и макросы
### Инициализация:
- MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM)
- MODBUS_Config() — Конфигурацмя Modbus (ID, Timeout).
- MODBUS_SlaveStart() — Запуск Modbus как Slave.
- MODBUS_MasterRequest() — Отправить запрос в MODBUS как Master.
### Функции для работы с RS (UART):
- RS_Parse_Message() / RS_Collect_Message() — Парсинг и сборка сообщения.
- RS_Response() — Отправка ответа.
******************************************************************************/
#include "modbus.h"
/* MODBUS HANDLES */
RS_HandleTypeDef hmodbus1; ///< Default Handle for Modbus
RS_MsgTypeDef MODBUS_MSG; ///< Default Message Struct for Modbus
/* DEFINE DATA FOR MODBUS */
MB_DataStructureTypeDef MB_DATA = {0};; ///< Coils & Registers
static void MB_DefaultCallback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg);
//-------------------------------------------------------------------
//-----------------------------FOR USER------------------------------
/**
* @brief Инициализация периферии модбас.
* @param hmodbus Указатель на хендлер RS
* @param huart Указатель на хендлер UART
* @param htim Указатель на хендлер TIM
* @details Подключает хендлы периферии к hmodbus
* Конфигурация выставляется по умолчанию из modbus_config.h
*/
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim)
{
if((hmodbus == NULL) || (huart == NULL))
{
return HAL_ERROR;
}
MB_DeviceInentificationInit();
//-----------SETUP MODBUS-------------
// set up modbus: MB_RX_Size_NotConst and Timeout enable
hmodbus->ID = MODBUS_DEVICE_ID;
hmodbus->sRS_Timeout = MODBUS_TIMEOUT;
hmodbus->sRS_Mode = RS_SLAVE_ALWAYS_WAIT;
// INIT
hmodbus->RS_STATUS = RS_Init(hmodbus, huart, htim, 0);
RS_EnableReceive();
if(hmodbus->RS_STATUS == RS_OK)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief Программная конфигурация модбас.
* @param hmodbus указатель на хендлер RS
* @param Timeout Время тишины между двумя байтами после которых перезапускается прием
* @param master Режим мастер (пока не сделан)
* @details Конфигурирует ID, таймаут и режим hmodbus
*/
HAL_StatusTypeDef MODBUS_Config(RS_HandleTypeDef *hmodbus, uint8_t ID, uint16_t Timeout, uint8_t master)
{
if(hmodbus == NULL)
{
return HAL_ERROR;
}
if(!master)
{
if((ID < 1) || (ID > 247))
{
return HAL_ERROR;
}
hmodbus->ID = ID;
}
else
hmodbus->ID = 0;
hmodbus->sRS_Timeout = Timeout;
if(master)
hmodbus->sRS_Mode = RS_MASTER_REQUEST;
else
hmodbus->sRS_Mode = RS_SLAVE_ALWAYS_WAIT;
return HAL_OK;
}
/**
* @brief Запуск слейв модбас.
* @param hmodbus Указатель на хендлер RS.
* @param modbus_msg Указатель на структуру сообщения.
(NULL чтобы использовать дефолтную)
* @details Конфигурирует ID, таймаут и режим hmodbus
*/
HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{
if(hmodbus == NULL)
{
return HAL_ERROR;
}
if(hmodbus->sRS_Mode >= RS_MASTER_MODE_START)
{
return HAL_ERROR;
}
MB_DiagnosticsInit();
if(modbus_msg)
hmodbus->RS_STATUS = RS_Receive_IT(hmodbus, modbus_msg);
else
hmodbus->RS_STATUS = RS_Receive_IT(hmodbus, &MODBUS_MSG);
if(hmodbus->RS_STATUS == RS_OK)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief Реквест мастера модбас.
* @param hmodbus Указатель на хендлер RS.
* @param modbus_msg Указатель на структуру сообщения
* @details Конфигурирует ID, таймаут и режим hmodbus
*/
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*))
{
if(hmodbus == NULL)
{
return HAL_ERROR;
}
if(modbus_msg == NULL)
{
return HAL_ERROR;
}
if(hmodbus->sRS_Mode < RS_MASTER_MODE_START)
{
return HAL_ERROR;
}
if(hmodbus->f.RS_Busy)
return HAL_BUSY;
if(pClbk) // если задан используем пользовательский коллбек
hmodbus->pCallback = (void (*)(void*, void*))(pClbk);
else // иначе дефолтный
hmodbus->pCallback = (void (*)(void*, void*))(&MB_DefaultCallback);
hmodbus->RS_STATUS = RS_Transmit_IT(hmodbus, modbus_msg);
if(hmodbus->RS_STATUS == RS_OK)
return HAL_OK;
else
return HAL_ERROR;
}
//-------------------------------------------------------------------
//-----------------------------INTERNAL------------------------------
/**
* @brief Дефолтный коллбек для мастера.
* @param hmodbus Указатель на хендлер RS
* @param modbus_msg Указатель на структуру сообщения
* @details В этот коллбек попадут все запросы, с NULL-коллбеком
*/
static void MB_DefaultCallback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{
__NOP();
return;
}
/* Реализация функций из rs_message.c для протокола */
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
{
if(hmodbus->sRS_Mode >= RS_MASTER_MODE_START)
{
return RS_ERR;
}
return MB_Slave_Response(hmodbus, modbus_msg);
}
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
{
if(hmodbus->sRS_Mode < RS_MASTER_MODE_START)
{
return MB_Slave_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff);
}
else
{
return MB_Master_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff);
}
}
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
{
if(hmodbus->sRS_Mode < RS_MASTER_MODE_START)
{
return MB_Slave_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff);
}
else
{
return MB_Master_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff);
}
}
MODBUS_TIMEOUT
#define MODBUS_TIMEOUT
Таймаут в тиках таймера
Definition modbus_config.h:26
MODBUS_DEVICE_ID
#define MODBUS_DEVICE_ID
Адрес устройства в сети Modbus.
Definition modbus_config.h:25
MB_DeviceInentificationInit
void MB_DeviceInentificationInit(void)
Инициализация идентификаторов.
Definition modbus_devid.c:177
MB_DiagnosticsInit
void MB_DiagnosticsInit(void)
Инициализация диагностических счетчиков
Definition modbus_diag.c:22
MODBUS_MasterRequest
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void(*pClbk)(RS_HandleTypeDef *, RS_MsgTypeDef *))
Реквест мастера модбас.
Definition modbus.c:136
MODBUS_Config
HAL_StatusTypeDef MODBUS_Config(RS_HandleTypeDef *hmodbus, uint8_t ID, uint16_t Timeout, uint8_t master)
Программная конфигурация модбас.
Definition modbus.c:72
MODBUS_SlaveStart
HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
Запуск слейв модбас.
Definition modbus.c:105
MODBUS_FirstInit
HAL_StatusTypeDef MODBUS_FirstInit(RS_HandleTypeDef *hmodbus, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim)
Инициализация периферии модбас.
Definition modbus.c:42
MB_Master_Collect_Message
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Сбор сообщения в буфер UART в режиме мастер (фрейм мастера из msg -> uart).
Definition modbus_master.c:388
MB_Master_Parse_Message
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Парс сообщения в режиме мастер (фрейм слейва из uart -> msg).
Definition modbus_master.c:469
MODBUS_MSG
RS_MsgTypeDef MODBUS_MSG
Default Message Struct for Modbus.
Definition modbus.c:25
MB_Slave_Collect_Message
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Сбор сообщения в буфер UART в режиме слейв (фрейм слейва из msg -> uart).
Definition modbus_slave.c:167
MB_Slave_Response
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
Ответ на сообщение в режиме слейва.
Definition modbus_slave.c:24
MB_Slave_Parse_Message
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Парс сообщения в режиме слейв (фрейм мастера из uart -> msg).
Definition modbus_slave.c:330
RS_Receive_IT
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Начать прием по прерываниям.
Definition rs_message.c:43
RS_Collect_Message
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
Пользовательская функция для сбора сообщения в буфер UART.
Definition modbus.c:193
RS_Transmit_IT
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Начать передачу по прерываниям.
Definition rs_message.c:91
RS_Parse_Message
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
Пользовательская функция для парса сообщения из буфера UART.
Definition modbus.c:205
RS_StatusTypeDef
RS_StatusTypeDef
Enums for respond CMD about RS status.
Definition rs_message.h:164
RS_Response
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Пользовательская функция для ответа на запрос по UART.
Definition modbus.c:184
RS_MASTER_MODE_START
#define RS_MASTER_MODE_START
Начало режимов мастера (до него - режим слейв)
Definition rs_message.h:181
RS_Init
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr)
Инициалазация структуры RS_HandleTypeDef.
Definition rs_message.c:156
hmodbus1
RS_HandleTypeDef hmodbus1
Default Handle for Modbus.
Definition modbus.c:24
RS_EnableReceive
#define RS_EnableReceive()
Функция изменения направления передачи на ПРИЕМ для RS-485.
Definition rs_message.h:150
RS_MASTER_REQUEST
@ RS_MASTER_REQUEST
Мастер с ручным запросом
Definition rs_message.h:187
RS_SLAVE_ALWAYS_WAIT
@ RS_SLAVE_ALWAYS_WAIT
Слейв в постоянном ожидании
Definition rs_message.h:185
MB_DefaultCallback
static void MB_DefaultCallback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
Coils & Registers.
Definition modbus.c:176
modbus.h
Главный заголовочный файл Modbus библиотеки
MB_DataStructureTypeDef
Структура со всеми регистрами и коилами модбас
Definition modbus_data.h:146
RS_FlagsTypeDef::RS_Busy
unsigned RS_Busy
1 - RS занят, 0 - RS свободен
Definition rs_message.h:204
RS_HandleTypeDef
Handle for RS communication.
Definition rs_message.h:228
RS_HandleTypeDef::ID
uint8_t ID
ID хендла
Definition rs_message.h:230
RS_HandleTypeDef::pCallback
void(* pCallback)(void *, void *)
Указатель на коллбек: принят ответ в режиме мастер
Definition rs_message.h:240
RS_HandleTypeDef::f
RS_FlagsTypeDef f
Флаги для контроля приема/передачи
Definition rs_message.h:243
RS_HandleTypeDef::sRS_Mode
RS_ModeTypeDef sRS_Mode
Настройка: слейв/мастер RS_ModeTypeDef.
Definition rs_message.h:238
RS_HandleTypeDef::RS_STATUS
RS_StatusTypeDef RS_STATUS
Статус RS.
Definition rs_message.h:247
RS_HandleTypeDef::sRS_Timeout
uint16_t sRS_Timeout
Настройка: Таймаут в тиках таймера
Definition rs_message.h:239
RS_MsgTypeDef
Structure for modbus messsage.
Definition modbus_core.h:177