/** * @file MODBUS_LOW_ATY.c * * @param Project DEVICE_GENERAL_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2023 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief Familiar functions of modbus for all device * * @note 4 byte per reg, save float or uint32 * * @version * - 1_01_221029 > ATY * -# Preliminary version, first Release ******************************************************************************** */ #ifndef __MODBUS_LOW_ATY_C #define __MODBUS_LOW_ATY_C #include "MODBUS_LOW_ATY.h" /******************************* For user *************************************/ /******************************************************************************/ #if defined (MODBUS_FLOAT_MODE) float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0}; /** * @brief modbus process with float * @note only make 03/06/10 function code, others will return err 01 */ void Modbus_Process(uint8_t* buf, uint8_t len) { uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00}; uint16_t snedBufSize = 4; if(len < 4) return; // check buf min size if(buf[0] != MODBUS_ADDR) return; // check addr if(CheckCrc16Modbus(buf, len)) return; // check crc sendBuf[0] = buf[0]; sendBuf[1] = buf[1]; switch(buf[1]) // check function code { // case MODBUS_FUNC_READ_COILS:{break; } // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; } case MODBUS_FUNC_READ_HOLDING_REGISTERS:{ uint16_t i = 0, startAddr = 0, regCount = 0; startAddr = ((buf[2] << 8) + buf[3]); regCount = ((buf[4] << 8) + buf[5]); if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; snedBufSize = 6; break; } sendBuf[2] = regCount * 4; snedBufSize += 1; for(i = 0; i < regCount; i++){ sendBuf[2 + (i * 4) + 1] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 24; sendBuf[2 + (i * 4) + 2] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 16; sendBuf[2 + (i * 4) + 3] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 8; sendBuf[2 + (i * 4) + 4] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]); snedBufSize += 4; } break; } // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; } // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; } case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{ uint16_t startAddr = 0; float regValue = 0.0; startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]); if(startAddr >= MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; snedBufSize = 6; break; } regValue = (((uint32_t)buf[4] << 24) + ((uint32_t)buf[5] << 16) + ((uint32_t)buf[6] << 8) + (uint32_t)buf[7]); mbRegHoding[startAddr] = regValue / MUL_FLOAT; // sendBuf[2] = buf[2]; // sendBuf[3] = buf[3]; // sendBuf[4] = buf[4]; // sendBuf[5] = buf[5]; // sendBuf[6] = buf[6]; // sendBuf[7] = buf[7]; sendBuf[2] = startAddr >> 8; sendBuf[3] = startAddr; sendBuf[4] = ((uint32_t)regValue >> 24); sendBuf[5] = ((uint32_t)regValue >> 16); sendBuf[6] = ((uint32_t)regValue >> 8); sendBuf[7] = (uint32_t)regValue; snedBufSize += 6; break; } // case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{ // uint16_t i = 0, startAddr = 0, regCount = 0; // startAddr = ((buf[2] << 8) + buf[3]); // regCount = ((buf[4] << 8) + buf[5]); // if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){ // sendBuf[1] = buf[1] + 0x80; // sendBuf[2] = 0x02; // snedBufSize = 6; // break; // } // for(i = 0; i < regCount; i++) // mbRegHoding[startAddr + i] = // ((buf[7 + (i * 2)] << 8) + buf[8 + (i * 2)]) / MUL_FLOAT; // sendBuf[2] = startAddr >> 8; // sendBuf[3] = startAddr; // sendBuf[4] = regCount >> 8; // sendBuf[5] = regCount; // snedBufSize += 4; // break; } default:{ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x01; snedBufSize = 6; break; } } sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1); sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0); UartSendBytes(sendBuf, snedBufSize); } #elif defined(MODBUS_FLOAT_CODE_MODE) __XDATA float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0}; union{ float f_t; uint8_t u8_t[4]; }mbFloatChange_u; /** * @brief modbus process with float * @note only make 03/06/10 function code, others will return err 01 */ void Modbus_Process(uint8_t* buf, uint8_t len) { uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00}; uint16_t sendBufSize = 4; if(len < 4) return; // check buf min size if(buf[0] != MODBUS_ADDR) return; // check addr if(CheckCrc16Modbus(buf, len)) return; // check crc sendBuf[0] = buf[0]; sendBuf[1] = buf[1]; switch(buf[1]) // check function code { // case MODBUS_FUNC_READ_COILS:{break; } // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; } case MODBUS_FUNC_READ_HOLDING_REGISTERS:{ uint16_t i = 0, startAddr = 0, regCount = 0; startAddr = ((buf[2] << 8) + buf[3]); regCount = ((buf[4] << 8) + buf[5]); if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } sendBuf[2] = regCount * 4; sendBufSize += 1; for(i = 0; i < regCount; i++){ mbFloatChange_u.f_t = mbRegHoding[startAddr + i]; #ifdef BIG_ENDIAN sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[0]; sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[1]; sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[2]; sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[3]; #else sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[3]; sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[2]; sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[1]; sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[0]; #endif sendBufSize += 4; // sendBufSize += 4; // aty240117 } break; } // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; } // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; } case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{ uint16_t startAddr = 0; float regValue = 0.0; startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]); if(startAddr >= MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } #ifdef BIG_ENDIAN mbFloatChange_u.u8_t[0] = buf[4]; mbFloatChange_u.u8_t[1] = buf[5]; mbFloatChange_u.u8_t[2] = buf[6]; mbFloatChange_u.u8_t[3] = buf[7]; #else mbFloatChange_u.u8_t[3] = buf[4]; mbFloatChange_u.u8_t[2] = buf[5]; mbFloatChange_u.u8_t[1] = buf[6]; mbFloatChange_u.u8_t[0] = buf[7]; #endif regValue = mbFloatChange_u.f_t; mbRegHoding[startAddr] = regValue; sendBuf[2] = startAddr >> 8; sendBuf[3] = startAddr; #ifdef BIG_ENDIAN sendBuf[4] = mbFloatChange_u.u8_t[0]; sendBuf[5] = mbFloatChange_u.u8_t[1]; sendBuf[6] = mbFloatChange_u.u8_t[2]; sendBuf[7] = mbFloatChange_u.u8_t[3]; #else sendBuf[4] = mbFloatChange_u.u8_t[3]; sendBuf[5] = mbFloatChange_u.u8_t[2]; sendBuf[6] = mbFloatChange_u.u8_t[1]; sendBuf[7] = mbFloatChange_u.u8_t[0]; #endif sendBufSize += 6; break; } case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{ uint16_t i = 0, startAddr = 0, regCount = 0; startAddr = ((buf[2] << 8) + buf[3]); regCount = ((buf[4] << 8) + buf[5]); if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } for(i = 0; i < regCount; i++) { float regValue = 0.0; #ifdef BIG_ENDIAN mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 1]; mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 2]; mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 3]; mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 4]; #else mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 1]; mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 2]; mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 3]; mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 4]; #endif regValue = mbFloatChange_u.f_t; mbRegHoding[startAddr + i] = regValue; } sendBuf[2] = startAddr >> 8; sendBuf[3] = startAddr; sendBuf[4] = regCount >> 8; sendBuf[5] = regCount; sendBufSize += 4; break; } default:{ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x01; sendBufSize = 6; break; } } sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1); sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0); UartSendBytes(sendBuf, sendBufSize); } #else uint16_t mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0x0000}; /** * @brief modbus process * @note only make 03/06/10 function code, others will return err 01 */ void Modbus_Process(uint8_t* buf, uint8_t len) { uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00}; uint16_t sendBufSize = 4; if(len < 4) return; // check buf min size if(buf[0] != MODBUS_ADDR) return; // check addr if(CheckCrc16Modbus(buf, len)) return; // check crc sendBuf[0] = buf[0]; sendBuf[1] = buf[1]; switch(buf[1]) // check function code { // case MODBUS_FUNC_READ_COILS:{break; } // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; } case MODBUS_FUNC_READ_HOLDING_REGISTERS:{ uint16_t i = 0, startAddr = 0, regCount = 0; startAddr = (buf[2] << 8 + buf[3]); regCount = (buf[4] << 8 + buf[5]); if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } sendBuf[2] = regCount * 2; sendBufSize += 1; for(i = 0; i < regCount; i++){ sendBuf[3 + (i * 2)] = mbRegHoding[startAddr + i] >> 8; sendBuf[3 + (i * 2) + 1] = mbRegHoding[startAddr + i]; sendBufSize += 2; } break; } // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; } // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; } case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{ uint16_t startAddr = 0, regValue = 0; startAddr = (buf[2] << 8 + buf[3]); regValue = (buf[4] << 8 + buf[5]); if(startAddr >= MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } mbRegHoding[startAddr] = regValue; sendBuf[2] = startAddr >> 8; sendBuf[3] = startAddr; sendBuf[4] = regValue >> 8; sendBuf[5] = regValue; sendBufSize += 4; break; } case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{ uint16_t i = 0, startAddr = 0, regCount = 0; startAddr = (buf[2] << 8 + buf[3]); regCount = (buf[4] << 8 + buf[5]); if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x02; sendBufSize = 6; break; } for(i = 0; i < regCount; i++) mbRegHoding[startAddr + i] = (buf[7 + (i * 2)] << 8 + buf[8 + (i * 2)]); sendBuf[2] = startAddr >> 8; sendBuf[3] = startAddr; sendBuf[4] = regCount >> 8; sendBuf[5] = regCount; sendBufSize += 4; break; } default:{ sendBuf[1] = buf[1] + 0x80; sendBuf[2] = 0x01; sendBufSize = 6; break; } } sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0); sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1); UartSendBytes(sendBuf, sendBufSize); } #endif /* MODBUS_FLOAT_MODE */ #endif /* __MODBUS_LOW_ATY_C */ /******************************** End Of File *********************************/