/** ****************************************************************************** * @file modbus_coils.h * @brief Работа с коилами Modbus ****************************************************************************** @addtogroup MODBUS_COILS Coils Tools @ingroup MODBUS_INTERNAL @{ ****************************************************************************** * @details Модуль предоставляет функции и макросы для работы с битовыми данными: - Чтение coils (0x01) Упаковка битов в байты - Запись одиночного coil (0x05) Установка/сброс бита - Запись множественных coils (0x0F) - распаковка байтов в биты - Макросы для локального доступа к coils @section Организация битовых данных: Coils упакованы в 16-битные слова для эффективного использования памяти. Биты нумеруются от младшего к старшему внутри каждого слова. @section Адресация: - Глобальная - абсолютный адрес в пространстве Modbus - Локальная - относительный адрес внутри массива coils - Макросы автоматически вычисляют смещения и маски ******************************************************************************/ #ifndef __MODBUS_COILS_H_ #define __MODBUS_COILS_H_ #include "modbus_core.h" ///////////////////////////////////////////////////////////////////// ////////////////////---MODBUS FUNCTION DEFINES---//////////////////// /** @brief Structure for coils operation */ typedef enum { SET_COIL, RESET_COIL, TOOGLE_COIL, }MB_CoilsOpTypeDef; //-------------------------------------------------- /** * @brief Macros to set pointer to a certain register that contains certain coil * @param _parr_ - массив коилов. * @param _coil_ - Номер коила от начала массива _arr_. * @note Используется вместе с @ref MB_Set_Coil_Mask @verbatim Пояснение выражений (_coil_/16) - get index (address shift) of register that contain certain coil Visual explanation: 30th coil in coils registers array 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 Macros to set mask to a certain bit in coils register * @param _coil_ - Номер коила от начала массива _arr_. * @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr @verbatim Пояснение выражений (16*(_coil_/16) - how many coils we need to skip. e.g. (16*30/16) - skip 16 coils from first register _coil_-(16*(_coil_/16)) - shift to certain coil in certain register e.g. Coil(30) gets in register[1] (30/16 = 1) coil №14 (30 - (16*30/16) = 30 - 16 = 14) Visual explanation: 30th coil in coils registers array 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)) )) ///////////////////////////////////////////////////////////////////// /////////////////////////---FUNCTIONS---///////////////////////////// /** * @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS Modbus Data Access * @ingroup MODBUS_FUNCTIONS * @brief Функции для доступа к данным модбас @{ */ /** * @brief Read Coil at its local address. * @param _parr_ - массив коилов. * @param _coil_ - Номер коила от начала массива _arr_. * @return uint16_t Возвращает запрошенный коил на 0м бите. * * @details Позволяет обратиться к коилу по адресу относительно _arr_. */ #define MB_Read_Coil_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_)) /** * @brief Set Coil at its local address. * @param _parr_ Указатель на массив коилов. * @param _coil_ - Номер коила от начала массива _arr_. * * @details Позволяет обратиться к коилу по адресу относительно _arr_. */ #define MB_Set_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_) /** * @brief Reset Coil at its local address. * @param _parr_ Указатель на массив коилов. * @param _coil_ - Номер коила от начала массива _arr_. * * @details Позволяет обратиться к коилу по адресу относительно _arr_. */ #define MB_Reset_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_)) /** * @brief Set Coil at its local address. * @param _parr_ Указатель на массив коилов. * @param _coil_ - Номер коила от начала массива _arr_. * * @details Позволяет обратиться к коилу по адресу относительно _arr_. */ #define MB_Toogle_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_) /* Set or Reset Coil at its global address */ MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal); /* Read Coil at its global address */ uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception); /** MODBUS_DATA_ACCESS_FUNCTIONS * @} */ //---------PROCESS MODBUS COMMAND FUNCTIONS--------- /** * @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS @{ */ /* Proccess command Read Coils (01 - 0x01) */ uint8_t MB_Proccess_Read_Coils(RS_MsgTypeDef *modbus_msg); /* Proccess command Write Single Coils (05 - 0x05) */ uint8_t MB_Proccess_Write_Single_Coil(RS_MsgTypeDef *modbus_msg); /* Proccess command Write Multiple Coils (15 - 0x0F) */ uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg); /** MODBUS_CMD_PROCESS_FUNCTIONS * @} */ /////////////////////////---FUNCTIONS---///////////////////////////// #endif //__MODBUS_COILS_H_ /** MODBUS_COILS * @} */