#include "check.h" #include "includes.h" /****************************************************************************** ** 函数名称: ushort cmCRC_16(uchar *PuchMsg,ushort usDataLen) ** 功 能: 16位CRC校验 ** 修改日志: ******************************************************************************/ static u_int8_t auchCRCHi[]={ 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, //DESCRIPTION:RTU CRC校验的高位字节表 0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81, 0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, 0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01, 0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81, 0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01, 0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40}; static u_int8_t auchCRCLo[]={ 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4, //DESCRIPTION:RTU CRC校验的低位字节表 0x04,0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09, 0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD, 0x1D,0x1C,0xDC,0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3, 0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7, 0x37,0xF5,0x35,0x34,0xF4,0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A, 0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE, 0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26, 0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2, 0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F, 0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,0x78,0xB8,0xB9,0x79,0xBB, 0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5, 0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,0x50,0x90,0x91, 0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C, 0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,0x88, 0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C, 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40}; u_int16_t CRC16( u_int8_t *PuchMsg,u_int16_t usDataLen) { u_int8_t uchCRCHi; //high byte of CRC initialized u_int8_t uchCRCLo; //low byte of CRC initialized u_int8_t uIndex; //will index into CRC lookup table uchCRCHi=0xFF; uchCRCLo=0xFF; while(usDataLen--) { //calculate the CRC uIndex = uchCRCHi^(u_int8_t)(*PuchMsg++); uchCRCHi = uchCRCLo^auchCRCHi[uIndex]; uchCRCLo = auchCRCLo[uIndex]; } return(uchCRCHi <<8|uchCRCLo); } void CRC16_init(u_int16_t *crc16) { *crc16 = 0xFFFF; } void CRC16_update(u_int16_t *crc16, u_int8_t *PuchMsg,u_int32_t usDataLen) { u_int8_t uchCRCHi; //high byte of CRC initialized u_int8_t uchCRCLo; //low byte of CRC initialized u_int16_t uIndex; //will index into CRC lookup table uchCRCHi = (*crc16) >> 8; uchCRCLo = (*crc16) & 0xFF; while(usDataLen--) { //calculate the CRC uIndex = uchCRCHi^(u_int8_t)(*PuchMsg++); uchCRCHi = uchCRCLo^auchCRCHi[uIndex]; uchCRCLo = auchCRCLo[uIndex]; } *crc16 = (uchCRCHi <<8|uchCRCLo); } /****************************************************************************** ** 函数名称:check_sum(u_int8_t *pdata,u_int16_t length) ** 功 能:累加和取反校验 ** 修改日志: ******************************************************************************/ u_int8_t checksum(u_int8_t *pdata,u_int16_t length) { u_int8_t cs = 0; u_int16_t i = 0; for(i = 0; i < length; i++) { cs += *(pdata + i); } return ~(u_int8_t)cs; } /****************************************************************************** ** 函数名称:xor_check ** 功 能:异或 ** 修改日志: ******************************************************************************/ u_int8_t check_xor(u_int8_t *pdata,u_int16_t length) { u_int8_t cs = 0; u_int16_t i = 0; for(i = 0; i < length; i++) { cs ^= *(pdata + i); } return cs; } #define NUM 5 float f_Middle(float *ArrDataBuffer) { u_int8_t j = 0; u_int8_t k = 0; u_int8_t i = 0; float temp = 0; float Sum = 0; float Value = 0; for(j = 0; j < NUM-1; j++)//采样值由小到大排列 { for(k = 0; k < NUM-j-1; k++) { if(ArrDataBuffer[k] > ArrDataBuffer[k+1]) { temp = ArrDataBuffer[k]; ArrDataBuffer[k] = ArrDataBuffer[k+1]; ArrDataBuffer[k+1] = temp; } } } for(i = 1; i < NUM-1 ; i++) { Sum += ArrDataBuffer[i]; } Value = Sum / (NUM - 2); return(Value); } #if CFG_MODULE_CURRENT /// 中值平均滤波 /// /// /// @param none /// @param none /// @return none /// @note 修改日志 /// jjj于2017-06-02 float Middle1(float *ArrDataBuffer) { uint8_t j = 0; uint8_t k = 0; uint8_t l = 0; float temp = 0; float Sum = 0; float Value = 0; for(j = 0; j < CURRENT_SAMPLE_NUM-1; j++) //采样值由小到大排列 { for(k = 0; k < CURRENT_SAMPLE_NUM-j-1; k++) { if(ArrDataBuffer[k] > ArrDataBuffer[k+1]) { temp = ArrDataBuffer[k]; ArrDataBuffer[k] = ArrDataBuffer[k+1]; ArrDataBuffer[k+1] = temp; } } } for(l = 2; l < CURRENT_SAMPLE_NUM-2 ; l++) { Sum += ArrDataBuffer[l]; } Value = Sum / (CURRENT_SAMPLE_NUM - 4); return(Value); } /// 均方根程序 /// /// /// @param none /// @param none /// @return none /// @note 修改日志 /// jjj于2017-06-02 float RMS_Val(uint16_t (*data)[RMS_NUM]) { uint8_t i = 0; uint8_t j = 0; float sum[CURRENT_SAMPLE_NUM] = {0.0}; float sum_vol = 0.0; float voltage = 0.0; for(j = 0;j < CURRENT_SAMPLE_NUM; j++) { for(i = 0;i < RMS_NUM; i++) { voltage = data[j][i] * 0.0032258; // 3.3/1023(10位ADC) = 0.0032258 //参考电压3.3V / 2^12 = 3.3 /4095 = 0.0008058 voltage = (voltage-2.5) / 20 / 0.15 * 2000; //得到电流 变比2000 采样电阻0.15欧 //voltage = (voltage-2.5) / 20 / 0.15 * System_Cfg.curr_rat; //得到电流 变比2000 sum[j] += pow(voltage,2); } sum[j] = sum[j] / RMS_NUM; sum[j] = sqrt(sum[j]); //采用均方根算法,直接得到地线上电流大小 } sum_vol = Middle1(sum); // sum_vol = Curve_fitting(sum_vol); //二次函数拟合校准 if(sum_vol < 0) sum_vol = 0; return sum_vol; } #endif #if CFG_MODULE_TEMPHUMI /// 中值平均滤波 /// /// /// @param none /// @param none /// @return none /// @note 修改日志 /// jjj于2017-06-02 u_int16_t Middle2(u_int16_t *ArrDataBuffer) { uint8_t j = 0; uint8_t k = 0; uint8_t l = 0; u_int16_t temp = 0; u_int32_t Sum = 0; u_int16_t Value = 0; for(j = 0; j < TEMPHUMI_SAMPLE_NUM-1; j++) //采样值由小到大排列 { for(k = 0; k < TEMPHUMI_SAMPLE_NUM-j-1; k++) { if(ArrDataBuffer[k] > ArrDataBuffer[k+1]) { temp = ArrDataBuffer[k]; ArrDataBuffer[k] = ArrDataBuffer[k+1]; ArrDataBuffer[k+1] = temp; } } } for(l = 2; l < TEMPHUMI_SAMPLE_NUM-2 ; l++) { Sum += ArrDataBuffer[l]; } Value = Sum / (TEMPHUMI_SAMPLE_NUM - 4); return(Value); } #endif