Loading...
Searching...
No Matches
modbus_holdregs.c
Go to the documentation of this file.
/**
*******************************************************************************
* @file modbus_holdregs.c
* @brief Реализация работы с регистрами хранения Modbus
*******************************************************************************
* @details
Модуль для доступа к регистрам внутри программы:
- Функции для доступа к регистрам хранения по глобальным адресам
Модуль обработки команд для holding registers (регистров хранения):
- Чтение множественных регистров (0x03) - копирование данных в буфер ответа
- Запись одиночного регистра (0x06) - прямая запись значения
- Запись множественных регистров (0x10) - пакетная запись из буфера
@section hvalid Валидация данных:
- Проверка соответствия количества байт и регистров
- Валидация адресов через MB_DefineRegistersAddress()
- Обработка исключений при некорректных запросах
******************************************************************************/
#include "modbus_inputregs.h"
#ifdef MODBUS_ENABLE_HOLDINGS
/**
* @brief Записать регистр хранения по глобальному адресу.
* @param Addr Адрес регистра.
* @param WriteVal Число для записи.
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
uint16_t *pHoldRegs;
//------------WRITE COIL-------------
Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
if(Exception == ET_NO_ERRORS)
{
*(pHoldRegs) = WriteVal;
}
return Exception;
}
/**
* @brief Считать регистр хранения по глобальному адресу.
* @param Addr Адрес регистра.
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
* @return uint16_t Возвращает значение регистра.
*
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
Вне зависимости от того как регистры размещены в памяти.
*/
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
{
//---------CHECK FOR ERRORS----------
MB_ExceptionTypeDef Exception_tmp = 0;
uint16_t *pHoldRegs;
//------------READ COIL--------------
Exception_tmp = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
if(Exception) // if exception is not given to func fill it
*Exception = Exception_tmp;
if(Exception_tmp == ET_NO_ERRORS)
{
return *(pHoldRegs);
}
else
{
return 0;
}
}
/**
* @brief Обработать функцию Read Holding Registers (03 - 0x03).
* @param modbus_msg Указатель на структуру собщения modbus.
* @return fMessageHandled Статус о результате обработки комманды.
* @details Обработка команды Read Holding Registers.
*/
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != ET_NO_ERRORS)
return 0;
//-----------READING REGS------------
// setup output message data size
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
// read data
int i;
for (i = 0; i<modbus_msg->Qnt; i++)
{
modbus_msg->MbData[i] = *(pHoldRegs++);
}
return 1;
}
/**
* @brief Обработать функцию Write Single Register (06 - 0x06).
* @param modbus_msg Указатель на структуру собщения modbus.
* @return fMessageHandled Статус о результате обработки комманды.
* @details Обработка команды Write Single Register.
*/
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
{
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != ET_NO_ERRORS)
return 0;
//-----------WRITTING REG------------
*(pHoldRegs) = modbus_msg->Qnt;
return 1;
}
/**
* @brief Обработать функцию Write Multiple Registers (16 - 0x10).
* @param modbus_msg Указатель на структуру собщения modbus.
* @return fMessageHandled Статус о результате обработки комманды.
* @details Обработка команды Write Multiple Registers.
*/
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
{
//---------CHECK FOR ERRORS----------
if (modbus_msg->Qnt*2 != modbus_msg->ByteCnt)
{ // if quantity and bytes count arent match
modbus_msg->Except_Code = 3;
return 0;
}
// get origin address for data
uint16_t *pHoldRegs;
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
if(modbus_msg->Except_Code != ET_NO_ERRORS)
return 0;
//-----------WRITTING REGS-----------
for (int i = 0; i<modbus_msg->Qnt; i++)
{
*(pHoldRegs++) = modbus_msg->MbData[i];
}
return 1;
}
#endif //MODBUS_ENABLE_HOLDINGS
MB_Process_Write_Single_Reg
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Single Register (06 - 0x06).
Definition modbus_holdregs.c:120
MB_DefineRegistersAddress
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
Define Address Origin for Input/Holding Registers.
Definition __modbus_data.c:66
MB_Process_Write_Miltuple_Regs
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Multiple Registers (16 - 0x10).
Definition modbus_holdregs.c:139
MB_Process_Read_Hold_Regs
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
Обработать функцию Read Holding Registers (03 - 0x03).
Definition modbus_holdregs.c:92
MB_Holding_Read_Global
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
Считать регистр хранения по глобальному адресу.
Definition modbus_holdregs.c:61
MB_Holding_Write_Global
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
Записать регистр хранения по глобальному адресу.
Definition modbus_holdregs.c:36
MB_ExceptionTypeDef
MB_ExceptionTypeDef
Enum for modbus exception codes.
Definition modbus_core.h:76
ET_NO_ERRORS
@ ET_NO_ERRORS
no errors
Definition modbus_core.h:78
modbus_inputregs.h
Работа с входными регистрами Modbus.
RS_MsgTypeDef
Structure for modbus messsage.
Definition modbus_core.h:177
RS_MsgTypeDef::Qnt
uint16_t Qnt
Quantity of modbus data.
Definition modbus_core.h:188
RS_MsgTypeDef::Except_Code
MB_ExceptionTypeDef Except_Code
Exception Code for the command.
Definition modbus_core.h:192
RS_MsgTypeDef::ByteCnt
uint8_t ByteCnt
Quantity of bytes of data in message to transmit/receive.
Definition modbus_core.h:189
RS_MsgTypeDef::MbData
uint16_t MbData[DATA_SIZE]
Modbus Data.
Definition modbus_core.h:191
RS_MsgTypeDef::Addr
uint16_t Addr
Modbus Address of data.
Definition modbus_core.h:187