/* * FreeModbus Libary: user callback functions and buffer define in slave mode * Copyright (C) 2013 Armink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $ */ #include "user_mb_app.h" #include "stm32f10x.h" #include "HT16C22.h" #include "key.h" #include "Relay.h" #include "SIM_EEPROM.h" extern u8 AC_Flag; //空调界面 extern u8 FH_Flag; //地暖界面 extern u8 FA_Flag; //新风界面 extern u8 AC_Open; //空调开机 extern u8 FH_Open; //地暖界面 extern u8 FA_Open; //新风界面 extern u8 XM_flag; extern u8 THA; extern u16 savedata[32]; void DoWhenWriteHoldingRegister(USHORT iRegIndex); /*------------------------Slave mode use these variables----------------------*/ //Slave mode:DiscreteInputs variables USHORT usSDiscInStart = S_DISCRETE_INPUT_START; #if S_DISCRETE_INPUT_NDISCRETES%8 UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1]; #else UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ; #endif //Slave mode:Coils variables USHORT usSCoilStart = S_COIL_START; #if S_COIL_NCOILS%8 UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ; #else UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ; #endif //Slave mode:InputRegister variables USHORT usSRegInStart = S_REG_INPUT_START; USHORT usSRegInBuf[S_REG_INPUT_NREGS] ; //Slave mode:HoldingRegister variables USHORT usSRegHoldStart = S_REG_HOLDING_START; USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ; /*------------------------Slave mode use these variables----------------------*/ /** * Modbus slave input register callback function. * * @param pucRegBuffer input register buffer * @param usAddress input register address * @param usNRegs input register number * * @return result */ eMBErrorCode eMBRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ) { eMBErrorCode eStatus = MB_ENOERR; USHORT iRegIndex; USHORT * pusRegInputBuf; USHORT REG_INPUT_START; USHORT REG_INPUT_NREGS; USHORT usRegInStart; pusRegInputBuf = usSRegInBuf; REG_INPUT_START = S_REG_INPUT_START; REG_INPUT_NREGS = S_REG_INPUT_NREGS; usRegInStart = usSRegInStart; /* it already plus one in modbus function method. */ usAddress--; if ((usAddress >= REG_INPUT_START) && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS)) { iRegIndex = usAddress - usRegInStart; while (usNRegs > 0) { *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8); *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF); iRegIndex++; usNRegs--; } } else { eStatus = MB_ENOREG; } return eStatus; } /** * Modbus slave holding register callback function. * * @param pucRegBuffer holding register buffer * @param usAddress holding register address * @param usNRegs holding register number * @param eMode read or write * * @return result */ eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode) { eMBErrorCode eStatus = MB_ENOERR; USHORT iRegIndex; USHORT * pusRegHoldingBuf; USHORT REG_HOLDING_START; USHORT REG_HOLDING_NREGS; USHORT usRegHoldStart; pusRegHoldingBuf = usSRegHoldBuf; REG_HOLDING_START = S_REG_HOLDING_START; REG_HOLDING_NREGS = S_REG_HOLDING_NREGS; usRegHoldStart = usSRegHoldStart; /* it already plus one in modbus function method. */ usAddress--; if ((usAddress >= REG_HOLDING_START) && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS)) { iRegIndex = usAddress - usRegHoldStart; switch (eMode) { /* read current register values from the protocol stack. */ case MB_REG_READ: while (usNRegs > 0) { *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8); *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF); /*if(iRegIndex==0) { pusRegHoldingBuf[iRegIndex]=0; }*/ iRegIndex++; usNRegs--; } break; /* write current register values with new values from the protocol stack. */ case MB_REG_WRITE: while (usNRegs > 0) { pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8; pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++; DoWhenWriteHoldingRegister(iRegIndex); iRegIndex++; usNRegs--; } break; } } else { eStatus = MB_ENOREG; } return eStatus; } /** * Modbus slave coils callback function. * * @param pucRegBuffer coils buffer * @param usAddress coils address * @param usNCoils coils number * @param eMode read or write * * @return result */ eMBErrorCode eMBRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode) { eMBErrorCode eStatus = MB_ENOERR; USHORT iRegIndex , iRegBitIndex , iNReg; UCHAR * pucCoilBuf; USHORT COIL_START; USHORT COIL_NCOILS; USHORT usCoilStart; iNReg = usNCoils / 8 + 1; pucCoilBuf = ucSCoilBuf; COIL_START = S_COIL_START; COIL_NCOILS = S_COIL_NCOILS; usCoilStart = usSCoilStart; /* it already plus one in modbus function method. */ usAddress--; if( ( usAddress >= COIL_START ) && ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) ) { iRegIndex = (USHORT) (usAddress - usCoilStart) / 8; iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8; switch ( eMode ) { /* read current coil values from the protocol stack. */ case MB_REG_READ: while (iNReg > 0) { *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8); iNReg--; } pucRegBuffer--; /* last coils */ usNCoils = usNCoils % 8; /* filling zero to high bit */ *pucRegBuffer = *pucRegBuffer << (8 - usNCoils); *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils); break; /* write current coil values with new values from the protocol stack. */ case MB_REG_WRITE: while (iNReg > 1) { xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8, *pucRegBuffer++); iNReg--; } /* last coils */ usNCoils = usNCoils % 8; /* xMBUtilSetBits has bug when ucNBits is zero */ if (usNCoils != 0) { xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils, *pucRegBuffer++); } break; } } else { eStatus = MB_ENOREG; } return eStatus; } /** * Modbus slave discrete callback function. * * @param pucRegBuffer discrete buffer * @param usAddress discrete address * @param usNDiscrete discrete number * * @return result */ eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) { eMBErrorCode eStatus = MB_ENOERR; USHORT iRegIndex , iRegBitIndex , iNReg; UCHAR * pucDiscreteInputBuf; USHORT DISCRETE_INPUT_START; USHORT DISCRETE_INPUT_NDISCRETES; USHORT usDiscreteInputStart; iNReg = usNDiscrete / 8 + 1; pucDiscreteInputBuf = ucSDiscInBuf; DISCRETE_INPUT_START = S_DISCRETE_INPUT_START; DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES; usDiscreteInputStart = usSDiscInStart; /* it already plus one in modbus function method. */ usAddress--; if ((usAddress >= DISCRETE_INPUT_START) && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES)) { iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8; iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8; while (iNReg > 0) { *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex, 8); iNReg--; } pucRegBuffer--; /* last discrete */ usNDiscrete = usNDiscrete % 8; /* filling zero to high bit */ *pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete); *pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete); } else { eStatus = MB_ENOREG; } return eStatus; } void FillCRC(uint8_t * pBuffer, uint16_t bufferLength) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < bufferLength - 2; i++) { crc ^= pBuffer[i]; for (uint16_t j = 0; j < 8; j++) { if (crc & 0x01) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } pBuffer[bufferLength - 2] = (crc & 0x00ff); pBuffer[bufferLength - 1] = (crc & 0xff00) >> 8; } uint8_t * MakeMessage(uint16_t addr, uint16_t value) { static uint8_t g_Message[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; g_Message[0] = local_addr & 0xff; g_Message[1] = 0x06; g_Message[2] = (addr & 0xff00) >> 8; g_Message[3] = (addr & 0x00ff) >> 0; g_Message[4] = (value & 0xff00) >> 8; g_Message[5] = (value & 0x00ff) >> 0; FillCRC(g_Message, 8); return g_Message; } uint8_t * MakeMultiMessage_KT(void) { static uint8_t g_Message[17] = {0x00, 0x10, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; g_Message[0] = local_addr & 0xff; g_Message[7] = (Reg_sta[0x01] & 0xff00) >> 8; g_Message[8] = (Reg_sta[0x01] & 0x00ff); g_Message[9] = (Reg_sta[0x02] & 0xff00) >> 8; g_Message[10] = (Reg_sta[0x02] & 0x00ff); g_Message[11] = (Reg_sta[0x03] & 0xff00) >> 8; g_Message[12] = (Reg_sta[0x03] & 0x00ff); g_Message[13] = (Reg_sta[0x04] & 0xff00) >> 8; g_Message[14] = (Reg_sta[0x04] & 0x00ff); FillCRC(g_Message, 17); return g_Message; } uint8_t * MakeMultiMessage_DN(void) { static uint8_t g_Message[13] = {0x00, 0x10, 0x00, 0x06, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; g_Message[0] = local_addr & 0xff; g_Message[7] = (Reg_sta[0x06] & 0xff00) >> 8; g_Message[8] = (Reg_sta[0x06] & 0x00ff); g_Message[9] = (Reg_sta[0x07] & 0xff00) >> 8; g_Message[10] = (Reg_sta[0x07] & 0x00ff); FillCRC(g_Message, 13); return g_Message; } extern u32 pwn_count; extern u32 key_pwn_count; extern u8 XM_flag; extern u8 key_XM_flag; uint8_t * MakeMultiMessage_XF(void) { static uint8_t g_Message[15] = {0x00, 0x10, 0x00, 0x09, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; g_Message[0] = local_addr & 0xff; g_Message[7] = (Reg_sta[0x09] & 0xff00) >> 8; g_Message[8] = (Reg_sta[0x09] & 0x00ff); g_Message[9] = (Reg_sta[0x0a] & 0xff00) >> 8; g_Message[10] = (Reg_sta[0x0a] & 0x00ff); g_Message[11] = (Reg_sta[0x0b] & 0xff00) >> 8; g_Message[12] = (Reg_sta[0x0b] & 0x00ff); FillCRC(g_Message, 15); return g_Message; } //寄存器写操作 u8 KJ_flag = 0; void DoWhenWriteHoldingRegister(USHORT iRegIndex) { //退出休眠模式 AC_Flag = 1; XM_flag = 0; pwn_count = 0; key_pwn_count = 0; key_XM_flag = 0; XM_flag = 0 ; switch(iRegIndex) { case Air_condition_switch: if (Reg_sta[Air_condition_switch] == 0 || Reg_sta[Air_condition_switch] == 1) { if(AC_Open != Reg_sta[Air_condition_switch]) { AC_Open = Reg_sta[Air_condition_switch]; savedata[24] = AC_Open; MemWriteByte(savedata, sizeof(savedata)); { if(Reg_sta[Air_condition_switch] == 1) { KJ_flag = 1; //Animation(); AC_Flag=1; XM_flag = 0; } } if(Reg_sta[Air_condition_switch]==0x00) { ht16c22_clear(); // XM_flag = 1; //Interface_flag_clear(); THA = 0; } } } //if(AC_Flag) //set_Relay_Sta(AC_Open,FH_Open,FA_Open); break; //工作模式 case Air_condition_mode: if(Reg_sta[Air_condition_mode] <= 1 && Reg_sta[Air_condition_mode] >= 0) { if(Reg_sta[Air_condition_mode] > 1) AC_mode = 0; else AC_mode = Reg_sta[Air_condition_mode]; savedata[23] = AC_mode; //冬季模式 if(AC_mode == 0) { //温度下限 savedata[29] = 20; Reg_sta[Temperature_Down_limit] = savedata[29]; //温度上限 savedata[30] = 28; Reg_sta[Temperature_Up_limit] = savedata[30]; } //夏季 else if (AC_mode == 1) { //温度下限 savedata[29] = 18; Reg_sta[Temperature_Down_limit] = savedata[29]; //温度上限 savedata[30] = 26; Reg_sta[Temperature_Up_limit] = savedata[30]; } //设置温度也随即改变 if(Reg_sta[Air_set_temp] < savedata[29]) AC_temp = savedata[29]; else if ( Reg_sta[Air_set_temp] >savedata[30]) AC_temp = savedata[30]; else AC_temp = Reg_sta[Air_set_temp]; savedata[21] = AC_temp; MemWriteByte(savedata, sizeof(savedata)); } // if(Reg_sta[Air_condition_mode] == 3) // AC_mode = 0; // else // AC_mode = Reg_sta[Air_condition_mode] + 1; break; case Air_wind_speed: if(Reg_sta[Air_wind_speed] <= 3 && Reg_sta[Air_wind_speed] >= 1) { if(Reg_sta[Air_wind_speed] > 3 || Reg_sta[Air_wind_speed] <1 ) AC_speed = 1; else AC_speed = Reg_sta[Air_wind_speed]; savedata[22] = AC_speed; MemWriteByte(savedata, sizeof(savedata)); } break; case Air_set_temp: if(Reg_sta[Air_set_temp] >= savedata[29] && Reg_sta[Air_set_temp] <= savedata[30]) { if(Reg_sta[Air_set_temp] < savedata[29]) AC_temp = savedata[29]; else if ( Reg_sta[Air_set_temp] >savedata[30]) AC_temp = savedata[30]; else AC_temp = Reg_sta[Air_set_temp]; savedata[21] = AC_temp; MemWriteByte(savedata, sizeof(savedata)); } break; case Relay_Sta_Read: break; case Floor_heating_switch: break; case Floor_heating_temp: break; case Fresh_air_switch: break; case Fresh_air_Param: break; case Fresh_air_wind_speed: break; case Compensates_temp: break; case Real_time_temp: break; case Real_time_Humidity: break; case Real_time_Fa_param: break; case Air_condition_Relay: break; case Floor_heating_Relay: break; case Fresh_air_reg: break; case Ltemp_Protection_valve: break; case Led_Brightness: int sii1; int sttl; sii1 = Reg_sta[Led_Brightness] & 0x0f; sttl = (Reg_sta[Led_Brightness] >>8) &0x01; if((sttl == 1 || sttl ==0 )&& (sii1 >= 1&& sii1 <=6)) { SI = Reg_sta[Led_Brightness] & 0x0f; if( SI>6 ||SI <1) { SI = 1; } savedata[27] = SI; savedata[20] = (Reg_sta[Led_Brightness] >>8) &0x01; MemWriteByte(savedata, sizeof(savedata)); } break; case Sleep_time_addr: if( Reg_sta[Sleep_time_addr] == 0xf||(Reg_sta[Sleep_time_addr] >= 0 && Reg_sta[Sleep_time_addr] <= 6)) { if(!Reg_sta[Sleep_time_addr]) { XM_time=30000; FOUR = 0; } else if(Reg_sta[Sleep_time_addr]==15) { XM_time=0; FOUR = 6; } else { XM_time=Reg_sta[Sleep_time_addr]*60000; FOUR = Reg_sta[Sleep_time_addr]; } savedata[25] = Reg_sta[Sleep_time_addr]; MemWriteByte(savedata, sizeof(savedata)); } break; case Lock_screen: break; //温度单位转换 case Temperature_Unit: if(Reg_sta[Temperature_Unit] == 0 || Reg_sta[Temperature_Unit] == 1) { if(Reg_sta[Temperature_Unit] < 0) Reg_sta[Temperature_Unit] = 0; else if(Reg_sta[Temperature_Unit] > 1) Reg_sta[Temperature_Unit] = 1; savedata[19] = Reg_sta[Temperature_Unit]; MemWriteByte(savedata, sizeof(savedata)); } break; case Temperature_Down_limit: if(Reg_sta[Temperature_Down_limit]>=5 && Reg_sta[Temperature_Down_limit] <=20) { if(Reg_sta[Temperature_Down_limit] < 5) savedata[29] = 5; else if ( Reg_sta[Temperature_Down_limit] >20) savedata[29] = 20; else savedata[29] = Reg_sta[Temperature_Down_limit]; MemWriteByte(savedata, sizeof(savedata)); } break; case Temperature_Up_limit: if(Reg_sta[Temperature_Up_limit]>=25 && Reg_sta[Temperature_Up_limit] <=40) { if(Reg_sta[Temperature_Down_limit] < 5) savedata[29] = 5; else if ( Reg_sta[Temperature_Down_limit] >20) savedata[29] = 20; else savedata[29] = Reg_sta[Temperature_Down_limit]; MemWriteByte(savedata, sizeof(savedata)); if(Reg_sta[Temperature_Up_limit] < 25) savedata[30] = 25; else if ( Reg_sta[Temperature_Up_limit] >40) savedata[30] = 40; else savedata[30] = Reg_sta[Temperature_Up_limit]; MemWriteByte(savedata, sizeof(savedata)); } break; case 0x65: // savedata[10] = Reg_sta[0x65]; // MemWriteByte(savedata, sizeof(savedata)); break; default: break; } }