/** ******************************************************************************* * @file modbus_inputregs.c * @brief Реализация работы с входными регистрами Modbus ******************************************************************************* * @details Модуль для доступа к регистрам внутри программы: - Функции для доступа к входным регистрам по глобальным адресам Модуль обработки команды чтения input registers (0x04): @section ivalid Валидация данных: - Проверка соответствия количества байт и регистров - Валидация адресов через MB_DefineRegistersAddress() - Обработка исключений при некорректных запросах ******************************************************************************/ #include "modbus_inputregs.h" #ifdef MODBUS_ENABLE_INPUTS /** * @brief Записать входной регистр по глобальному адресу. * @param Addr Адрес регистра. * @param WriteVal Число для записи. * @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок. * * @details Позволяет обратиться к любому регистру по его глобальному адрессу. Вне зависимости от того как регистры размещены в памяти. */ MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal) { //---------CHECK FOR ERRORS---------- MB_ExceptionTypeDef Exception = ET_NO_ERRORS; uint16_t *pInRegs; //------------WRITE COIL------------- Exception = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input, 1); if(Exception == ET_NO_ERRORS) { *(pInRegs) = WriteVal; } return Exception; } /** * @brief Считать входной регистр по глобальному адресу. * @param Addr Адрес регистра. * @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении. * @return uint16_t Возвращает значение регистра. * * @details Позволяет обратиться к любому регистру по его глобальному адрессу. Вне зависимости от того как регистры размещены в памяти. */ uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) { //---------CHECK FOR ERRORS---------- MB_ExceptionTypeDef Exception_tmp = 0; uint16_t *pInRegs; //------------READ COIL-------------- Exception_tmp = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input, 0); if(Exception) // if exception is not given to func fill it *Exception = Exception_tmp; if(Exception_tmp == ET_NO_ERRORS) { return *(pInRegs); } else { return 0; } } /** * @brief Обработать функцию Read Input Registers (04 - 0x04). * @param modbus_msg Указатель на структуру собщения modbus. * @return fMessageHandled Статус о результате обработки комманды. * @details Обработка команды Read Input Registers. */ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg) { //---------CHECK FOR ERRORS---------- // get origin address for data uint16_t *pInRegs; modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input, 0); // определение адреса регистров 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; iQnt; i++) { if(*((int16_t *)pInRegs) > 0) modbus_msg->MbData[i] = (*pInRegs++); else modbus_msg->MbData[i] = (*pInRegs++); } return 1; } #endif //MODBUS_ENABLE_INPUTS