Работает Modbus, проверено на ESP32-S3-Zero
Заготовка для модбас на ИВР
This commit is contained in:
50
modbus.cpp
50
modbus.cpp
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus.c
|
||||
* @file modbus.cpp
|
||||
* @brief Модуль для реализации MODBUS.
|
||||
**************************************************************************
|
||||
* @details Файл содержит реализацию функций работы с Modbus, включая:
|
||||
@@ -50,16 +50,18 @@
|
||||
* Таким образом, сами коилы могут представлять собой как массив так и структуру.
|
||||
*
|
||||
* @section Инструкция по подключению
|
||||
* Для корректной работы надо подключить обработчики RS_UART_Handler(), RS_TIM_Handler(),
|
||||
* в соответствубщие низкоуровневые прерывания UART_IRQHandler, TIM_IRQHandler. После HAL'овского обработчика
|
||||
*
|
||||
* Также необходимо в modbus_config.h настроить дефайны для нужной работы UART
|
||||
* Настройте modbus_config.h дефайны для нужной работы UART
|
||||
*
|
||||
* После для запуска Modbus:
|
||||
* @verbatim
|
||||
//----------------Прием модбас----------------//
|
||||
#include "rs_message.h"
|
||||
MODBUS_FirstInit();
|
||||
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
|
||||
|
||||
void loop()
|
||||
{
|
||||
RS_Process(&hmodbus1);(&hmodbus1, &MODBUS_MSG);
|
||||
}
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -73,6 +75,7 @@ MB_DeviceIdentificationTypeDef MB_INFO;
|
||||
MB_DataStructureTypeDef MB_DATA;
|
||||
RS_MsgTypeDef MODBUS_MSG;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//-----------------------------FOR USER------------------------------
|
||||
/**
|
||||
@@ -91,6 +94,7 @@ void MODBUS_FirstInit(void)
|
||||
hmodbus1.sRS_RX_Size_Mode = RS_RX_Size_NotConst;
|
||||
hmodbus1.pMessagePtr = &MODBUS_MSG;
|
||||
// INIT
|
||||
rs_huart.begin(115200, SERIAL_8N1, 8, 9);
|
||||
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &rs_huart, 0);
|
||||
|
||||
RS_EnableReceive();
|
||||
@@ -188,6 +192,7 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
||||
// if quantity too big return error
|
||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Address");
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
// if all ok - return no errors
|
||||
@@ -195,7 +200,10 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
||||
}
|
||||
// if address isnt from this array return error
|
||||
else
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Address");
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for Input/Holding Registers
|
||||
@@ -213,6 +221,7 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
||||
/* check quantity error */
|
||||
if (Qnt > 125)
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Value");
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
@@ -226,6 +235,7 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Address");
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
@@ -239,11 +249,13 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Address");
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Function");
|
||||
return ILLEGAL_FUNCTION;
|
||||
}
|
||||
// if found requeried array return no err
|
||||
@@ -266,6 +278,7 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
||||
/* check quantity error */
|
||||
if (Qnt > 2000)
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Value");
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
@@ -277,6 +290,7 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Illegal Data Address");
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
|
||||
@@ -611,20 +625,24 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms
|
||||
{
|
||||
// Read Coils
|
||||
case MB_R_COILS:
|
||||
MB_DEBUG_PRINT("[MB] Read Coils request");
|
||||
hmodbus->f.MessageHandled = MB_Read_Coils(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
// Read Hodling Registers
|
||||
case MB_R_HOLD_REGS:
|
||||
MB_DEBUG_PRINT("[MB] Read Hodling Registers request");
|
||||
hmodbus->f.MessageHandled = MB_Read_Hold_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
case MB_R_IN_REGS:
|
||||
MB_DEBUG_PRINT("[MB] Read Input Registers request");
|
||||
hmodbus->f.MessageHandled = MB_Read_Input_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
// Write Single Coils
|
||||
case MB_W_COIL:
|
||||
MB_DEBUG_PRINT("[MB] Write Single Coil request");
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Coil(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -634,6 +652,7 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms
|
||||
break;
|
||||
|
||||
case MB_W_HOLD_REG:
|
||||
MB_DEBUG_PRINT("[MB] Write Single Hodling Register request");
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Reg(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -644,6 +663,7 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms
|
||||
|
||||
// Write Multiple Coils
|
||||
case MB_W_COILS:
|
||||
MB_DEBUG_PRINT("[MB] Write Multiple Coils request");
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -654,6 +674,7 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms
|
||||
|
||||
// Write Multiple Registers
|
||||
case MB_W_HOLD_REGS:
|
||||
MB_DEBUG_PRINT("[MB] Write Multiple Hodling Registers request");
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
@@ -663,22 +684,29 @@ RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_ms
|
||||
break;
|
||||
|
||||
case MB_R_DEVICE_INFO:
|
||||
MB_DEBUG_PRINT("[MB] Read Device Information request");
|
||||
hmodbus->f.MessageHandled = MB_Read_Device_Identification(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
/* unknown func code */
|
||||
default: modbus_msg->Except_Code = ILLEGAL_FUNCTION; /* set exception code: illegal function */
|
||||
default:
|
||||
MB_DEBUG_PRINT("[MB] Illegal function");
|
||||
modbus_msg->Except_Code = ILLEGAL_FUNCTION; /* set exception code: illegal function */
|
||||
}
|
||||
|
||||
if(hmodbus->f.MessageHandled == 0)
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Function not handled");
|
||||
modbus_msg->Func_Code = static_cast<MB_FunctonTypeDef>(
|
||||
static_cast<int>(modbus_msg->Func_Code) + ERR_VALUES_START
|
||||
);
|
||||
MB_ERR_DEBUG_PRINT2_HEX("[MB] Function Code:", modbus_msg->Func_Code);
|
||||
MB_ERR_DEBUG_PRINT2_DEC("[MB] Error Code:", modbus_msg->Except_Code);
|
||||
}
|
||||
else
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Function handled, responsing...");
|
||||
}
|
||||
|
||||
|
||||
@@ -733,6 +761,7 @@ RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo
|
||||
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Response is invalid (ByteCnt not match DataSize)");
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
@@ -754,6 +783,7 @@ RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo
|
||||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||||
else // otherwise return data_size err
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Response is invalid (ByteCnt not match DataSize)");
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
@@ -844,6 +874,7 @@ RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modb
|
||||
modbus_msg->Func_Code = static_cast<MB_FunctonTypeDef>(
|
||||
static_cast<int>(modbus_msg->Func_Code) + ERR_VALUES_START
|
||||
);
|
||||
MB_DEBUG_PRINT("[MB] Request is invalid (ByteCnt not match DataSize)");
|
||||
return RS_PARSE_MSG_ERR;
|
||||
}
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
@@ -869,6 +900,9 @@ RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modb
|
||||
// compare crc
|
||||
if (modbus_msg->MB_CRC != CRC_VALUE)
|
||||
{
|
||||
MB_DEBUG_PRINT("[MB] Request CRC is invalid");
|
||||
MB_ERR_DEBUG_PRINT2_HEX("[MB] Request CRC: ", modbus_msg->MB_CRC);
|
||||
MB_ERR_DEBUG_PRINT2_HEX("[MB] Calced CRC: ", CRC_VALUE);
|
||||
modbus_msg->Func_Code = static_cast<MB_FunctonTypeDef>(
|
||||
static_cast<int>(modbus_msg->Func_Code) + ERR_VALUES_START
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user