release 0.3.1

doxygen + refactoring
This commit is contained in:
2025-11-05 00:08:41 +03:00
parent 106deb0fcc
commit ecda27792c
21 changed files with 310 additions and 189 deletions

View File

@@ -6,7 +6,7 @@
* @details
Файл содержит реализацию функций работы с Modbus.
@section Функции и макросы
@section Функции и макросы
### Инициализация:
- MODBUS_FirstInit() — Инициализация Modbus (подключение UART, TIM)

View File

@@ -23,7 +23,7 @@
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти.
*/
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = NO_ERRORS;
@@ -63,7 +63,7 @@ MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteV
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
Вне зависимости от того как коилы размещены в памяти.
*/
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp;
@@ -94,11 +94,17 @@ uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
*/
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
{
if(modbus_msg == NULL || coil_state == NULL)
return 0;
// Проверяем что ответ связан с коилами
if(modbus_msg->Func_Code != MB_R_COILS)
{
return 0;
}
// Проверяем что coil_addr в пределах запрошенного диапазона
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0;
@@ -108,15 +114,19 @@ int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_sta
// Вычисляем байт и бит
uint8_t byte_index = coil_index / 8;
uint8_t bit_index = coil_index % 8;
uint8_t data_index = coil_index / 16;
uint8_t bit_index = coil_index % 16;
// Проверяем что байт существует в данных
if(byte_index >= modbus_msg->ByteCnt)
return 0;
// Получаем байт и проверяем бит
uint8_t coil_byte = modbus_msg->DATA[byte_index] & 0xFF;
*coil_state = (coil_byte >> bit_index) & 0x01;
// Получаем байт и проверяем бит
if(bit_index < 8)
*coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
else
*coil_state = (modbus_msg->DATA[data_index] >> bit_index) & 0x01;
return 1;
}
@@ -211,7 +221,7 @@ uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
* @return fMessageHandled Статус о результате обработки комманды.
* @details Обработка команды Write Multiple Coils.
*/
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
@@ -274,11 +284,11 @@ uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
#else //MODBUS_ENABLE_COILS
int MB_GetCoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal) {return ILLEGAL_FUNCTION;}
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;}
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal) {return ILLEGAL_FUNCTION;}
uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;}
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
#endif

View File

@@ -9,7 +9,7 @@
- Поддержка потоковой передачи при большом количестве объектов
- Автоматический расчет MoreFollows флагов
@section Потоковая передача:
@section Потоковая передача:
При большом количестве объектов идентификация разбивается на несколько
сообщений с установкой флага MoreFollows и указанием NextObjId для
продолжения чтения в следующем запросе.
@@ -26,8 +26,18 @@ MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная струк
* @param modbus_msg Указатель на структуру сообщения
* @return int Количество объектов
*/
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg)
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
{
if(modbus_msg == NULL)
{
return 0;
}
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
return modbus_msg->DevId.NumbOfObj;
}
@@ -39,11 +49,17 @@ int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg)
* @param obj_length Указатель для длины объекта
* @return int Найден ли объект (1 - да, 0 - нет)
*/
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
uint8_t *data = (uint8_t*)modbus_msg->DATA;
unsigned ind = 0;
@@ -84,11 +100,17 @@ int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data,
* @param obj_length Указатель для длины объекта
* @return int Успешность получения (1 - получен, 0 - не найден)
*/
int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
{
if((modbus_msg == NULL) || (obj_data == NULL))
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
{
return 0;
}
if(index >= modbus_msg->DevId.NumbOfObj)
return 0;
@@ -652,9 +674,9 @@ void MB_DeviceInentificationInit(void)
#else //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
/* Получить количество объектов в сообщении */
int MB_GetNumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
int MB_FindObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
int MB_GetObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
void MB_WriteSingleObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj) {}
void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj) {}
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) {return 0;}

View File

@@ -42,11 +42,19 @@ void MB_DiagnosticsInit(void)
* @param data Указатель куда положить данные
* @return 1 - успех, 0 - ошибка
*/
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data)
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
{
if(modbus_msg == NULL || data == NULL)
return 0;
// Проверяем что ответ связан с диагностикой
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
{
return 0;
}
*data = modbus_msg->DATA[1];
return 1;
}
@@ -311,7 +319,7 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
#else //MODBUS_ENABLE_DIAGNOSTICS
void MB_DiagnosticsInit(void) {}
int MB_GetDiagnosticResponse(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;}
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;}
int MB_Diagnostics_WriteBit(int bit_num, int bit_state) {return 0;}
int MB_Diagnostics_GetBit(int bit_num) {return 0;}
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) {return 0;}

View File

@@ -9,12 +9,12 @@
- Запись одиночного регистра (0x06) - прямая запись значения
- Запись множественных регистров (0x10) - пакетная запись из буфера
@section Валидация данных:
@section Валидация данных:
- Проверка соответствия количества байт и регистров
Валидация адресов через MB_DefineRegistersAddress()
- Обработка исключений при некорректных запросах
@section Echo-ответы:
@section Echo-ответы:
При успешной записи формируется echo-ответ с теми же данными,
что были в запросе (для функций 0x05, 0x06, 0x0F, 0x10).
******************************************************************************/

View File

@@ -6,7 +6,7 @@
* @details
Файл содержит реализацию функций для работы Modbus в режиме мастера.
@section Функции и макросы
@section Функции и макросы
- MB_Master_Collect_Message() — Сбор сообщения в режиме мастера
- MB_Master_Parse_Message() — Парс сообщения в режиме мастера
@@ -23,11 +23,19 @@
* @param reg_value Указатель для значения регистра
* @return 1 - успех, 0 - ошибка или reg_addr вне диапазона запроса
*/
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value)
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value)
{
if(modbus_msg == NULL || reg_value == NULL)
return 0;
// Проверяем что ответ связан с регистрами
if((modbus_msg->Func_Code != MB_R_DISC_IN) &&
(modbus_msg->Func_Code != MB_R_HOLD_REGS) &&
(modbus_msg->Func_Code != MB_R_IN_REGS))
{
return 0;
}
// Проверяем что reg_addr в пределах запрошенного диапазона
if(reg_addr < modbus_msg->Addr || reg_addr >= modbus_msg->Addr + modbus_msg->Qnt)
return 0;
@@ -302,173 +310,173 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
/** @brief Сформировать запрос на чтение коилов */
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на чтение дискретных регистров */
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на чтение холдинг регистров */
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на чтение инпут регистров */
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на запись одного коила */
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value)
{
RS_MsgTypeDef msg = {slave_addr, MB_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на запись одного регистра */
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value)
{
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
return msg;
}
/** @brief Сформировать запрос на запись нескольких регистров */
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data)
{
RS_MsgTypeDef msg = {slave_addr, MB_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
// Calculate byte count and prepare data
uint8_t byte_count = (quantity + 7) / 8;
msg.ByteCnt = byte_count;
// Copy coil data to message DATA array
for(int i = 0; i < byte_count; i++) {
if(i < DATA_SIZE) {
msg.DATA[i] = coils_data[i];
}
RS_MsgTypeDef msg = {slave_addr, MB_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
// Calculate byte count and prepare data
uint8_t byte_count = (quantity + 7) / 8;
msg.ByteCnt = byte_count;
// Copy coil data to message DATA array
for(int i = 0; i < byte_count; i++) {
if(i < DATA_SIZE) {
msg.DATA[i] = coils_data[i];
}
return msg;
}
return msg;
}
/** @brief Сформировать запрос на запись нескольких коилов */
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data)
{
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
// Copy register data to message DATA array
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
msg.DATA[i] = regs_data[i];
}
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
// Copy register data to message DATA array
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
msg.DATA[i] = regs_data[i];
}
return msg;
}
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DIAGNOSTIC, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DIAGNOSTIC, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
return msg;
}
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0000, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0000, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0001, data);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0001, data);
}
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0002, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0002, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0004, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0004, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000A, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000A, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000B, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000B, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000C, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000C, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000D, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000D, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000E, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000E, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000F, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000F, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0010, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0010, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0011, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0011, 0x0000);
}
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr)
{
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0012, 0x0000);
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0012, 0x0000);
}
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
}
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id)
{
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
return msg;
}
@@ -478,7 +486,7 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
#else
RS_MsgTypeDef msg_dummy = {0};
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}

View File

@@ -6,7 +6,7 @@
* @details
Файл содержит реализацию функций для работы Modbus в режиме слейва.
@section Функции и макросы
@section Функции и макросы
- MB_Slave_Response() — Ответ на запрос
- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
@@ -78,7 +78,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
// Write Multiple Coils
case MB_W_COILS:
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr);
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
hmodbus->f.DataUpdated = 1;

View File

@@ -10,7 +10,7 @@
- Таймаутов через таймер
- Двухстадийного приема (заголовок + данные)
@section Архитектура:
@section Архитектура:
В режиме слейв:
- Инициализация приема с сообщения с максимальным размером MSG_SIZE_MAX
- При срабатывании прерывания IDLE - обработка полученного сообщения
@@ -18,7 +18,7 @@
- Отправка запроса и переход в режим приема сообщения с максимальным размером MSG_SIZE_MAX
- При срабатывании прерывания IDLE - обработка полученного ответа
@section Необходимые обработчики:
@section Необходимые обработчики:
- RS_UART_Handler() в UARTx_IRQHandler вместо HAL_UART_IRQHandler()
- RS_TIM_Handler() в TIMx_IRQHandler вместо HAL_TIM_IRQHandler()
******************************************************************************/