diff --git a/Inc/modbus.h b/Inc/modbus.h index ca745d6..fa3e458 100644 --- a/Inc/modbus.h +++ b/Inc/modbus.h @@ -106,7 +106,7 @@ HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*)); -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- + /////////////////////////---FUNCTIONS---///////////////////////////// #endif //__MODBUS_H_ diff --git a/Inc/modbus_coils.h b/Inc/modbus_coils.h index ff664c3..c03cf8b 100644 --- a/Inc/modbus_coils.h +++ b/Inc/modbus_coils.h @@ -34,51 +34,6 @@ Coils упакованы в 16-битные слова для эффективн //-------------------------------------------------- -/** - * @addtogroup MODBUS_COILS - * @{ - */ - -/** - * @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил - * @param _parr_ - массив коилов. - * @param _coil_ - Номер коила от начала массива _arr_. - * @note Используется вместе с @ref MB_Set_Coil_Mask - @verbatim Пояснение выражений - - (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_ - -Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0) - xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx - |register[0]----| |register[1]----| - |skip this------| |get this-------| - |shift to 14 bit| - @endverbatim - */ -#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16)) -/** - * @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра - * @param _coil_ - Номер коила от начала массива _arr_. - * @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr - @verbatim Пояснение выражений - - (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра - - _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре - - Визуальный пример: 30 коил будет регистре[1], на 14 бите: - register = 30/16 = 1 - bit = 30 - (16*30/16) = 30 - 16 = 14 - - xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx - |register[0]----| |register[1]----| - |skip this------| |get this-------| - |shift to 14 bit| - @endverbatim - */ -#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) )) - -/** MODBUS_COILS - * @} - */ - ///////////////////////////////////////////////////////////////////// /////////////////////////---FUNCTIONS---///////////////////////////// @@ -93,7 +48,7 @@ Coils упакованы в 16-битные слова для эффективн * @{ */ -/** @brief Structure for coils operation */ +/** @brief Enum for coils operation */ typedef enum { SET_COIL, @@ -144,7 +99,6 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception); * @} */ -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ @@ -161,8 +115,4 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg); */ /////////////////////////---FUNCTIONS---///////////////////////////// -#endif //__MODBUS_COILS_H_ - -/** MODBUS_COILS - * @} - */ \ No newline at end of file +#endif //__MODBUS_COILS_H_ \ No newline at end of file diff --git a/Inc/modbus_core.h b/Inc/modbus_core.h index 8997477..cf11c46 100644 --- a/Inc/modbus_core.h +++ b/Inc/modbus_core.h @@ -194,6 +194,42 @@ extern RS_MsgTypeDef MODBUS_MSG; */ #define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_)) +/** + * @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил + * @param _parr_ - массив коилов. + * @param _coil_ - Номер коила от начала массива _arr_. + * @note Используется вместе с @ref MB_Set_Coil_Mask + @verbatim Пояснение выражений + - (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_ + +Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0) + xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx + |register[0]----| |register[1]----| + |skip this------| |get this-------| + |shift to 14 bit| + @endverbatim + */ +#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16)) +/** + * @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра + * @param _coil_ - Номер коила от начала массива _arr_. + * @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr + @verbatim Пояснение выражений + - (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра + - _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре + + Визуальный пример: 30 коил будет регистре[1], на 14 бите: + register = 30/16 = 1 + bit = 30 - (16*30/16) = 30 - 16 = 14 + + xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx + |register[0]----| |register[1]----| + |skip this------| |get this-------| + |shift to 14 bit| + @endverbatim + */ +#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) )) + /** GENERAL_MODBUS_STUFF * @} */ @@ -233,7 +269,6 @@ extern RS_MsgTypeDef MODBUS_MSG; ///////////////////////////////////////////////////////////////////// /////////////////////////---FUNCTIONS---///////////////////////////// -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ diff --git a/Inc/modbus_devid.h b/Inc/modbus_devid.h index 58a6d27..1d37fbb 100644 --- a/Inc/modbus_devid.h +++ b/Inc/modbus_devid.h @@ -99,7 +99,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj); /** MODBUS_DEVID * @} */ -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- + /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ diff --git a/Inc/modbus_diag.h b/Inc/modbus_diag.h index 3a50701..90d256d 100644 --- a/Inc/modbus_diag.h +++ b/Inc/modbus_diag.h @@ -98,7 +98,6 @@ void MB_Diagnostics_SlaveBusyCnt(void); * @} */ -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ diff --git a/Inc/modbus_holdregs.h b/Inc/modbus_holdregs.h index bfe3b81..7ab4e67 100644 --- a/Inc/modbus_holdregs.h +++ b/Inc/modbus_holdregs.h @@ -23,7 +23,22 @@ ///////////////////////////////////////////////////////////////////// /////////////////////////---FUNCTIONS---///////////////////////////// -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- +/** + * @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS + * @{ + */ + +/* Записать регистр хранения по глобальному адресу. */ +MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal); +/* Считать регистр хранения по глобальному адресу. */ +uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception); + +/** MODBUS_DATA_ACCESS_FUNCTIONS + * @} + */ + + + /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ diff --git a/Inc/modbus_inputregs.h b/Inc/modbus_inputregs.h index 9fa47e2..7912553 100644 --- a/Inc/modbus_inputregs.h +++ b/Inc/modbus_inputregs.h @@ -21,7 +21,21 @@ ///////////////////////////////////////////////////////////////////// /////////////////////////---FUNCTIONS---///////////////////////////// -//---------PROCESS MODBUS COMMAND FUNCTIONS--------- +/** + * @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS + * @{ + */ + +/* Записать входной регистр по глобальному адресу. */ +MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal); +/* Считать входной регистр по глобальному адресу. */ +uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception); + +/** MODBUS_DATA_ACCESS_FUNCTIONS + * @} + */ + + /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions * @ingroup MODBUS_INTERNAL diff --git a/Src/modbus_coils.c b/Src/modbus_coils.c index 0398901..5b2d4d9 100644 --- a/Src/modbus_coils.c +++ b/Src/modbus_coils.c @@ -57,7 +57,7 @@ MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteV /** * @brief Считать коил по глобальному адресу. * @param Addr Адрес коила. - * @param Exception Указатель на переменную для кода исключения, в случа неудачи при чтении. + * @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении. * @return uint16_t Возвращает весь регистр с маской на запрошенном коиле. * * @details Позволяет обратиться к любому коилу по его глобальному адрессу. diff --git a/Src/modbus_holdregs.c b/Src/modbus_holdregs.c index 786552a..57503cf 100644 --- a/Src/modbus_holdregs.c +++ b/Src/modbus_holdregs.c @@ -24,6 +24,66 @@ #ifdef MODBUS_ENABLE_HOLDINGS + +/** + * @brief Записать регистр хранения по глобальному адресу. + * @param Addr Адрес регистра. + * @param WriteVal Число для записи. + * @return ExceptionCode Код исключения если регистра по адресу не существует, и NO_ERRORS если все ок. + * + * @details Позволяет обратиться к любому регистру по его глобальному адрессу. + Вне зависимости от того как регистры размещены в памяти. + */ +MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal) +{ + //---------CHECK FOR ERRORS---------- + MB_ExceptionTypeDef Exception = NO_ERRORS; + uint16_t *pHoldRegs; + + //------------WRITE COIL------------- + Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding); + if(Exception == 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 == NO_ERRORS) + { + return *(pHoldRegs); + } + else + { + return 0; + } +} + + + /** * @brief Обработать функцию Read Holding Registers (03 - 0x03). * @param modbus_msg Указатель на структуру собщения modbus. @@ -34,7 +94,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg) { //---------CHECK FOR ERRORS---------- // get origin address for data - uint16_t *pHoldRegs; + uint16_t *pHoldRegs; modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров if(modbus_msg->Except_Code != NO_ERRORS) return 0; @@ -102,6 +162,8 @@ uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) #else //MODBUS_ENABLE_HOLDINGS +MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal) {return ILLEGAL_FUNCTION;} +uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;} uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg) {return 0;} uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg) {return 0;} uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) {return 0;} diff --git a/Src/modbus_inputregs.c b/Src/modbus_inputregs.c index 3bc34c9..06d8981 100644 --- a/Src/modbus_inputregs.c +++ b/Src/modbus_inputregs.c @@ -14,6 +14,65 @@ #ifdef MODBUS_ENABLE_INPUTS + +/** + * @brief Записать входной регистр по глобальному адресу. + * @param Addr Адрес регистра. + * @param WriteVal Число для записи. + * @return ExceptionCode Код исключения если регистра по адресу не существует, и NO_ERRORS если все ок. + * + * @details Позволяет обратиться к любому регистру по его глобальному адрессу. + Вне зависимости от того как регистры размещены в памяти. + */ +MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal) +{ + //---------CHECK FOR ERRORS---------- + MB_ExceptionTypeDef Exception = NO_ERRORS; + uint16_t *pInRegs; + + //------------WRITE COIL------------- + Exception = MB_DefineRegistersAddress(&pInRegs, Addr, 1, RegisterType_Input); + if(Exception == 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); + + if(Exception) // if exception is not given to func fill it + *Exception = Exception_tmp; + + if(Exception_tmp == NO_ERRORS) + { + return *(pInRegs); + } + else + { + return 0; + } +} + + /** * @brief Обработать функцию Read Input Registers (04 - 0x04). * @param modbus_msg Указатель на структуру собщения modbus. @@ -47,6 +106,8 @@ uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg) #else //MODBUS_ENABLE_INPUTS +MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal) {return ILLEGAL_FUNCTION;} +uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;} uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg) {return 0;} #endif \ No newline at end of file