сделал новую версию рабаем с 0

This commit is contained in:
2026-06-25 11:21:08 +03:00
parent f695867969
commit cdd8fc3f71
2357 changed files with 42856 additions and 594273 deletions

View File

@@ -0,0 +1,215 @@
/**
*******************************************************************************
* @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);
}
}