#include "proto_PM100.h" #include "proto_Modbus.h" #include "stdio.h" #include "string.h" #include "bsp_Uart.h" #include "os_timer.h" char *proto_PM100_Str_WarmingCode[32] = { "Water flow low" , "" , "Dil.N2 flow low" , "BP Drooping" , "MP Drooping" , "Casing temp. high" , "BP-G oil level low" , "BP-M oil level low" , "MP-G oil level low" , "MP-M oil level low" , "Drv brg temp. high" , "Drvn brg temp. high" , "Oil level low" , "BOX temp.high" , "N2 valve open" , "Cooler 1 temp. high" , "Cooler 2 temp. high" , "Cooler 3 temp. high" , "Pump N2 flow low" , "Exh. N2 flow low" , "Exh. trap temp. high" , "Back press. high" , "Heater error" , "BP motor temp. high" , "MP motor temp. high" , "Driver temp. high" , "Communication error" , "Valve error" , "" , "" , "" , "Other warnings" }; char *proto_PM100_Str_AlarmCode[32] = { "Casing temp. HH" , "BP motor temp. high" , "MP motor temp. high" , "Water leakage" , "BP thermal" , "MP thermal" , "" , "" , "" , "Emergency stop(EMS)" , "MP no current" , "BP no current" , "" , "Back press. high" , "Power failure" , "MP driver protection active", "BP driver protection active", "BP overload 2" , "MP overload 2" , "BP step out" , "MP step out" , "Emergency off(EMO)" , "Exh. N2 flow low" , "Water flow low continued" , "External interlock" , "" , "" , "" , "" , "" , "" , "Other alarms" }; static void proto_PM100_Init(void); static void proto_PM100_Tx_Task(void); static void proto_PM100_Rx_Task(u8 *pData,u16 Len,void *other_data); static void proto_PM100_Control_Start(u8 Dev); static void proto_PM100_Control_Stop(u8 Dev); static void proto_PM100_Control_Reset(void); static void proto_PM100_Control_Set_Mode(u8 Mode); static void proto_PM100_Control_Set_Mode_Speed(u8 Dev,u8 Mode,u16 Speed); static void proto_PM100_Alarm_Control_Reset(void); static void proto_PM100_Dev_Status_Control_Reset(void); proto_PM100_t PM100 = { .Sys_StateQueue = queue(proto_PM100_Set_Data_t,10), .Sys_State = PROTO_PM100_CMD_GET_STATE_ALARM, .Init = proto_PM100_Init, .Tx_Task = proto_PM100_Tx_Task, .Rx_Task = proto_PM100_Rx_Task, .Set_Data.Analog_Code = PROTO_PM100_GET_DATA_CODE, .Alarm_Control.Reset = proto_PM100_Alarm_Control_Reset, .Dev_Status_Control.Reset = proto_PM100_Dev_Status_Control_Reset, .Control.Start = proto_PM100_Control_Start, .Control.Stop = proto_PM100_Control_Stop, .Control.Reset = proto_PM100_Control_Reset, .Control.Set_Mode = proto_PM100_Control_Set_Mode, .Control.Set_Speed = proto_PM100_Control_Set_Mode_Speed, }; static proto_PM100_t *pPM100 = &PM100; static void proto_PM100_Init(void) { /*让两个主动上发的信息有时间间隔*/ pPM100->Alarm_Control.StartTime = osTime_MSecTick; pPM100->Dev_Status_Control.StartTime = osTime_MSecTick + 500; COM_Uart3.Rx_DataAnalysis = proto_PM100_Rx_Task; /*清空时间和报警时长数组*/ for (int i = 0; i < 32; i++) { PM100.Opera_Status.alarm_start_str[i][0] = '\0'; PM100.Opera_Status.warning_start_str[i][0] = '\0'; PM100.Opera_Status.alarm_start_sec[i] = 0; PM100.Opera_Status.warning_start_sec[i] = 0; } } static void proto_PM100_Send(u8 *pData,u16 Len) { COM_Uart3.Send(&COM_Uart3,pData,Len); } static u8 proto_PM100_SysState_Switch(void) { proto_PM100_Set_Data_t Set_Data; if(0 == queue_pop(pPM100->Sys_StateQueue,&Set_Data)) { pPM100->Sys_State = PROTO_PM100_CMD_GET_STATE_ALARM; return 0; } else { pPM100->Sys_State = Set_Data.Sys_State; memcpy(&pPM100->Set_Data,&Set_Data,sizeof(proto_PM100_Set_Data_t)); return 1; } } static void proto_PM100_Alarm_Control_Reset(void) { pPM100->Alarm_Control.Code_Last = ((u64)pPM100->Opera_Status.Warming_Code << 32) | (u64)pPM100->Opera_Status.Alarm_Code; } static void proto_PM100_Dev_Status_Control_Reset(void) { memcpy(&pPM100->Dev_Status_Control.Opera_Status_Last,&pPM100->Opera_Status,sizeof(proto_PM100_Set_Data_t)); } static void proto_PM100_Control_Start(u8 Dev) { proto_PM100_Set_Data_t Set_Data; Set_Data.Sys_State = PROTO_PM100_CMD_START; Set_Data.Dev = Dev; queue_push_back(pPM100->Sys_StateQueue,(void *)&Set_Data); } static void proto_PM100_Control_Stop(u8 Dev) { proto_PM100_Set_Data_t Set_Data; Set_Data.Sys_State = PROTO_PM100_CMD_STOP; Set_Data.Dev = Dev; queue_push_back(pPM100->Sys_StateQueue,(void *)&Set_Data); } static void proto_PM100_Control_Reset(void) { proto_PM100_Set_Data_t Set_Data; Set_Data.Sys_State = PROTO_PM100_CMD_RESET; queue_push_back(pPM100->Sys_StateQueue,(void *)&Set_Data); } static void proto_PM100_Control_Set_Mode(u8 Mode) { proto_PM100_Set_Data_t Set_Data; Set_Data.Sys_State = PROTO_PM100_CMD_SET_MODE; Set_Data.Mode = Mode; queue_push_back(pPM100->Sys_StateQueue,(void *)&Set_Data); } static void proto_PM100_Control_Set_Mode_Speed(u8 Dev,u8 Mode,u16 Speed) { proto_PM100_Set_Data_t Set_Data; Set_Data.Sys_State = PROTO_PM100_CMD_SET_SPEED; Set_Data.Dev = Dev; Set_Data.Mode = Mode; Set_Data.Speed = Speed; queue_push_back(pPM100->Sys_StateQueue,(void *)&Set_Data); } /*数据校验*/ static u8 proto_PM100_CheckSum(u8 *pData,u16 len) { u16 i; u8 Sum=0; for(i=0;i 9900) { Speed = 99; } sprintf(&Tx[6],"%d",Speed); Tx[8] = PROTO_PM100_FRAME_STRUCT_ETX; sprintf(&Tx[9],"%02X",proto_PM100_CheckSum((u8 *)Tx,9)); Tx[11] = PROTO_PM100_FRAME_STRUCT_CR; Len = 12; proto_PM100_Send((u8*)Tx,Len); } /*获取模拟量参数*/ static void proto_PM100_Tx_Get_Data(u32 Analog_Code) { char Tx[20]; u16 Len; u8 i,AD[8]; Analog_Code = PROTO_PM100_GET_DATA_CODE; Tx[0] = PROTO_PM100_FRAME_STRUCT_STX; sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_GET_DATA); for(i=0;i<8;i++) { AD[i] = (Analog_Code >> (4 * (7 - i))) & 0x0000000f; sprintf(&Tx[4 + i],"%X",AD[i]); } Tx[12] = PROTO_PM100_FRAME_STRUCT_ETX; sprintf(&Tx[13],"%02X",proto_PM100_CheckSum((u8 *)Tx,13)); Tx[15] = PROTO_PM100_FRAME_STRUCT_CR; Len = 16; proto_PM100_Send((u8*)Tx,Len); } /*获取状态和报警*/ static void proto_PM100_Tx_Get_State_Alarm(void) { char Tx[20]; u16 Len; Tx[0] = PROTO_PM100_FRAME_STRUCT_STX; sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_GET_STATE_ALARM); Tx[4] = PROTO_PM100_FRAME_STRUCT_ETX; sprintf(&Tx[5],"%02X",proto_PM100_CheckSum((u8 *)Tx,5)); Tx[7] = PROTO_PM100_FRAME_STRUCT_CR; Len = 8; proto_PM100_Send((u8*)Tx,Len); } static void proto_PM100_Tx_Task(void) { u8 SendTimeFlag = 0; if(0 == (pPM100->error_code & PROTO_PM100_ERROR_CODE_TIMEOUT)) { pPM100->time_out_count++; if(pPM100->time_out_count > 10) { pPM100->error_code |= PROTO_PM100_ERROR_CODE_TIMEOUT; } } if( 1 == pPM100->AnalogData_Control.FirstFlag && 1 != pPM100->AnalogData_Control.EndFlag ) { pPM100->AnalogData_Control.CountTime++; if(pPM100->AnalogData_Control.CountTime >= 3) /*连续3次没接收到数据*/ { pPM100->AnalogData_Control.FirstFlag = 0; pPM100->AnalogData_Control.EndFlag = 0; pPM100->AnalogData_Control.CountTime = 0; pPM100->Sys_State = PROTO_PM100_CMD_GET_STATE_ALARM; } return; } switch(pPM100->Sys_State) { case PROTO_PM100_CMD_START : { proto_PM100_Tx_Start(pPM100->Set_Data.Dev); }break; case PROTO_PM100_CMD_STOP : { proto_PM100_Tx_Stop(pPM100->Set_Data.Dev); }break; case PROTO_PM100_CMD_RESET : { proto_PM100_Tx_Reset(); }break; case PROTO_PM100_CMD_SET_MODE : { proto_PM100_Tx_Set_Mode(pPM100->Set_Data.Mode); }break; case PROTO_PM100_CMD_SET_SPEED : { proto_PM100_Tx_Set_Mode_Speed(pPM100->Set_Data.Dev,pPM100->Set_Data.Mode,pPM100->Set_Data.Speed); }break; case PROTO_PM100_CMD_GET_DATA : { proto_PM100_Tx_Get_Data(pPM100->Set_Data.Analog_Code); pPM100->AnalogData_Control.FirstFlag = 1; SendTimeFlag = 1; }break; case PROTO_PM100_CMD_GET_STATE_ALARM : { proto_PM100_Tx_Get_State_Alarm(); SendTimeFlag = 1; }break; default: { }break; } if(SendTimeFlag) { return ; } else { pPM100->SendTime++; if(pPM100->SendTime >= 3) { pPM100->SendTime = 0; pPM100->Sys_State = PROTO_PM100_CMD_GET_STATE_ALARM; } } } /*接收数据解析*/ static void proto_PM100_Rx_Task(u8 *pData,u16 Len,void *other_data) { u8 SumCheck[2],SuccessFlag; u8 *pTextData; char TextData[10]; /*帧头判断*/ if(PROTO_PM100_FRAME_STRUCT_STX != pData[0]) { return; } /*帧尾判断*/ if( PROTO_PM100_FRAME_STRUCT_ETX != pData[Len-4] || PROTO_PM100_FRAME_STRUCT_CR != pData[Len-1] ) { return; } if(PROTO_PM100_CMD_GET_DATA == pPM100->Sys_State)/*实时模拟量数据不进行校验判断,已经粘包了*/ { } else { /*校验和判断*/ sprintf((char*)SumCheck,"%02X",proto_PM100_CheckSum(pData,Len - 3)); if(SumCheck[0] != pData[Len - 3] || SumCheck[1] != pData[Len - 2]) { return ; } } /*清除超时计数*/ pPM100->error_code &= (~PROTO_PM100_ERROR_CODE_TIMEOUT); pPM100->time_out_count = 0; SuccessFlag = 0; pTextData = &pData[1]; switch(pPM100->Sys_State) { case PROTO_PM100_CMD_START : case PROTO_PM100_CMD_STOP : case PROTO_PM100_CMD_RESET : case PROTO_PM100_CMD_SET_MODE : case PROTO_PM100_CMD_SET_SPEED : { if(0 == strncmp((char *)pTextData,PROTO_PM100_CMD_STR_SET_OK,strlen(PROTO_PM100_CMD_STR_SET_OK))) { SuccessFlag = 1; proto_PM100_SysState_Switch(); } else { SuccessFlag = 0; } }break; case PROTO_PM100_CMD_GET_DATA : { u16 Len_Index = 0; u8 *pData_u8 = pData; int DataIndex; float Data; float *pData_float = (float *)&pPM100->AnalogData; while(Len_Index < Len) { pData_u8 = &pData[Len_Index + 1]; snprintf(TextData,3,"%s",pData_u8); sscanf((char*)TextData,"%d",&DataIndex); if(DataIndex > 22) { Len_Index += 14; continue ; } snprintf(TextData,8,"%s",&pData_u8[3]); sscanf((char*)TextData,"%f",&Data); pData_float[DataIndex] = Data; Len_Index += 14; } Len_Index -=14; pData_u8 = &pData[Len_Index + 1]; if(0 == strncmp((char *)pData_u8,PROTO_PM100_CMD_STR_SET_END,strlen(PROTO_PM100_CMD_STR_SET_END))) { SuccessFlag = 1; pPM100->AnalogData_Control.EndFlag = 1; } else { SuccessFlag = 0; } /* if(Len > 8) { int DataIndex; float Data; float *pData = (float *)&pPM100->AnalogData; snprintf(TextData,3,"%s",pTextData); sscanf((char*)TextData,"%d",&DataIndex); if(DataIndex >= 32) { return ; } snprintf(TextData,8,"%s",&pTextData[3]); sscanf((char*)TextData,"%f",&Data); pData[DataIndex] = Data; SuccessFlag = 1; } else { if(0 == strncmp((char *)pTextData,PROTO_PM100_CMD_STR_SET_END,strlen(PROTO_PM100_CMD_STR_SET_END))) { SuccessFlag = 1; pPM100->AnalogData_Control.EndFlag = 1; } else { SuccessFlag = 0; } } */ }break; case PROTO_PM100_CMD_GET_STATE_ALARM : { u32 Data,i; if(0 != strncmp((char *)pTextData,PROTO_PM100_CMD_STR_GET_STATE_ALARM,strlen(PROTO_PM100_CMD_STR_GET_STATE_ALARM))) { SuccessFlag = 0; break; } if(PROTO_PM100_MODE_CHAR_NORMAL == pTextData[3]) { pPM100->Opera_Status.Run_Status = PROTO_PM100_MODE_NORMAL; } else if(PROTO_PM100_MODE_CHAR_POWER_SAVING == pTextData[3]) { pPM100->Opera_Status.Run_Status = PROTO_PM100_MODE_POWER_SAVING; } else/*异常*/ { SuccessFlag = 0; break; } if(PROTO_PM100_MODE_CHAR_RUNING == pTextData[4]) { pPM100->Opera_Status.MP_Status = PROTO_PM100_MODE_RUNING; } else if(PROTO_PM100_MODE_CHAR_STOP == pTextData[4]) { pPM100->Opera_Status.MP_Status = PROTO_PM100_MODE_STOP; } else/*异常*/ { SuccessFlag = 0; break; } if(PROTO_PM100_MODE_CHAR_RUNING == pTextData[5]) { pPM100->Opera_Status.BP_Status = PROTO_PM100_MODE_RUNING; } else if(PROTO_PM100_MODE_CHAR_STOP == pTextData[5]) { pPM100->Opera_Status.BP_Status = PROTO_PM100_MODE_STOP; } else/*异常*/ { SuccessFlag = 0; break; } pPM100->Opera_Status.Warming_Code = 0; pPM100->Opera_Status.Alarm_Code = 0; // for(i=0;i<8;i++) // { // snprintf(TextData,8,"%s",&pTextData[6]); // sscanf((char*)TextData,"%x",&Data); // pPM100->Opera_Status.Warming_Code |= (Data & 0x0000000f); // // snprintf(TextData,8,"%s",&pTextData[14]); // sscanf((char*)TextData,"%x",&Data); // pPM100->Opera_Status.Alarm_Code |= Data & 0x0000000f; // } sscanf((const char *)&pTextData[6], "%8x", &pPM100->Opera_Status.Warming_Code); sscanf((const char *)&pTextData[14], "%8x", &pPM100->Opera_Status.Alarm_Code); if(0 == proto_PM100_SysState_Switch()) { pPM100->Sys_State = PROTO_PM100_CMD_GET_DATA; /*如果队列没有数据,就获取数据*/ } SuccessFlag = 1; }break; default: { }break; } /*实时数据是分包获取的,需特殊处理*/ if(PROTO_PM100_CMD_GET_DATA == pPM100->Sys_State) { if(1 == pPM100->AnalogData_Control.FirstFlag) { /*分包数据接收完成*/ if(1 == pPM100->AnalogData_Control.EndFlag) { pPM100->AnalogData_Control.FirstFlag = 0; pPM100->AnalogData_Control.EndFlag = 0; pPM100->AnalogData_Control.CountTime = 0; proto_PM100_SysState_Switch(); } else if(0 == SuccessFlag) { } else { pPM100->AnalogData_Control.CountTime = 0; } } } else { if(0 == SuccessFlag) { } else { pPM100->SendTime = 0; return; } } }