#include "proto_CS200.h" #include "proto_Modbus.h" #include "stdio.h" #include "string.h" #include "bsp_Uart.h" /*CS200量程*/ #define CS200_RANGE (2.0) #define CS200_RANGE_START (0x4000) #define CS200_RANGE_END (0xC000) #define CS200_MODBUS_ADDR_GetCurrentData (0x00) #define CS200_MODBUS_ADDR_SetFlow (0x02) static void proto_CS200_Init(void); static void proto_CS200_Tx_Task(void); static void proto_CS200_Rx_Task(u8 *pData,u16 Len); static void proto_SetFlow_1(float Value); static void proto_SetFlow_2(float Value); proto_CS200_t CS200 = { .ID_1 = 32, .ID_2 = 33, .Init = proto_CS200_Init, .Tx_Task = proto_CS200_Tx_Task, .Rx_Task = proto_CS200_Rx_Task, .SetFlow_1 = proto_SetFlow_1, .SetFlow_2 = proto_SetFlow_2, }; static proto_CS200_t *pCS200 = &CS200; static void proto_CS200_Init(void) { COM_Uart1.Rx_DataAnalysis = pCS200 ->Rx_Task; } static void proto_CS200_Send(u8 *pData,u16 Len) { COM_Uart1.Send(&COM_Uart1,pData,Len); } /*设置*/ static void proto_SetFlow_1(float Value) { float FlowRange; if(0 == pCS200->CurrentData[0].Range_u16) { FlowRange = CS200_RANGE; } else { FlowRange = pCS200->CurrentData[0].Range_u16 / 1000.0; } pCS200->SetFlowValue_1 = CS200_RANGE_START + (float)(CS200_RANGE_END - CS200_RANGE_START) * Value / FlowRange; } static void proto_SetFlow_2(float Value) { float FlowRange; if(0 == pCS200->CurrentData[1].Range_u16) { FlowRange = CS200_RANGE; } else { FlowRange = pCS200->CurrentData[1].Range_u16 / 1000.0; } pCS200->SetFlowValue_2 = CS200_RANGE_START + (float)(CS200_RANGE_END - CS200_RANGE_START) * Value / FlowRange; } /*发送指令*/ static void proto_CS200_Tx_GetCurrentData(u8 ID) { u16 Addr = CS200_MODBUS_ADDR_GetCurrentData; u8 Len = 14; ModbusReadData(ID,Addr,Len,proto_CS200_Send); } static void proto_CS200_Tx_SetFlow_1(void) { u16 Addr = CS200_MODBUS_ADDR_SetFlow; u8 Len = 1; u16 Data[1]= {pCS200->SetFlowValue_1}; ModbusyWriteOnlData(pCS200->ID_1,Addr,*Data,proto_CS200_Send); } static void proto_CS200_Tx_SetFlow_2(void) { u16 Addr = CS200_MODBUS_ADDR_SetFlow; u8 Len = 1; u16 Data[1]= {pCS200->SetFlowValue_2}; ModbusyWriteOnlData(pCS200->ID_2,Addr,*Data,proto_CS200_Send); } static void proto_CS200_Rx_Task(u8 *pData,u16 Len) { u8 SendTimeFlag = 0; u8 ModbusID,CMD; u16 CheckCRC16,ModbusCrc; u16 Addr,Data; u32 u32Temp; float FlowTemp; proto_CS2000_CurrentData_t *pCurrentData; ModbusID = *pData; CMD = *(pData+1); CheckCRC16 = pData[Len-2] << 8 | pData[Len-1]; if(ModbusID == pCS200->ID_1) { pCurrentData = &pCS200->CurrentData[0]; } else if(ModbusID == pCS200->ID_2) { pCurrentData = &pCS200->CurrentData[1]; } else { return; } pCS200->TimeCount = 0; if(CMD != 0x03 &&CMD != 0x04 && CMD != 0x06 && CMD != 0x10) return ; ModbusCrc = ModbusCrc16(pData,Len-2); ModbusCrc = (ModbusCrc >> 8) | (ModbusCrc << 8); if(CheckCRC16 != ModbusCrc) return ; switch(pCS200->State) { case CS200_STATE_Init: { pCS200->State = CS200_STATE_GetCurrentData; }break; case CS200_STATE_GetCurrentData: { pCurrentData->ID = pData[3 ] << 8 | pData[4 ]; pCurrentData->BaudRate = pData[5 ] << 8 | pData[6 ]; pCurrentData->SetFlow = pData[7 ] << 8 | pData[8 ]; pCurrentData->Flow = pData[9] << 8 | pData[10]; pCurrentData->Range_u16 = pData[11] << 8 | pData[12]; //单位ml pCurrentData->ValveCmd = pData[13] << 8 | pData[14]; u32Temp = pData[15] << 24 | pData[16] << 16 | pData[17] << 8 | pData[18] << 8; pCurrentData->SumFlow = *((float *)&u32Temp); pCurrentData->SumFlow_Mode = pData[19] << 8 | pData[20]; pCurrentData->Parity = pData[21] << 8 | pData[22]; pCurrentData->Valve_U = pData[23] << 8 | pData[24]; u32Temp = pData[25] << 24 | pData[26] << 16 | pData[27] << 8 | pData[28] << 8; pCurrentData->Range_Float = *((float *)&u32Temp); pCurrentData->SoftStartValue = pData[29] << 8 | pData[30]; FlowTemp = pCurrentData->Flow; pCurrentData->RealFlow = pCurrentData->Range_u16 / 1000.0 * (FlowTemp - CS200_RANGE_START) / ((float)(CS200_RANGE_END - CS200_RANGE_START)); if(pCS200->SetFlowValue_1 != pCS200->CurrentData[0].SetFlow) { pCS200->State = CS200_STATE_SetFlow_1; pCS200->ReadState = CS200_READ_STATE_ID_1; } else if(pCS200->SetFlowValue_2 != pCS200->CurrentData[1].SetFlow) { pCS200->State = CS200_STATE_SetFlow_2; pCS200->ReadState = CS200_READ_STATE_ID_2; } SendTimeFlag = 1; }break; case CS200_STATE_SetFlow_1: { pCS200->State = CS200_STATE_GetCurrentData; }break; case CS200_STATE_SetFlow_2: { pCS200->State = CS200_STATE_GetCurrentData; }break; } if(SendTimeFlag) { return; } else { pCS200->ErrorFlag &= (~(0x00000001 << pCS200->State));/*消除异常状态*/ pCS200->SendTime = 0; return; } } static void proto_CS200_Tx_Task(void) { u8 SendTimeFlag = 0; if(++pCS200->TimeCount > 50)/*通讯超时*/ { memset(&pCS200->CurrentData,0,sizeof(pCS200->CurrentData)); } switch(pCS200->State) { case CS200_STATE_Init: { }break; case CS200_STATE_GetCurrentData: { switch(pCS200->ReadState) { case CS200_READ_STATE_ID_1: { proto_CS200_Tx_GetCurrentData(pCS200->ID_1); pCS200->ReadState = CS200_READ_STATE_ID_2; }break; case CS200_READ_STATE_ID_2: { proto_CS200_Tx_GetCurrentData(pCS200->ID_2); pCS200->ReadState = CS200_READ_STATE_ID_1; }break; default: { proto_CS200_Tx_GetCurrentData(pCS200->ID_1); pCS200->ReadState = CS200_READ_STATE_ID_2; }break; } SendTimeFlag = 1; }break; case CS200_STATE_SetFlow_1: { proto_CS200_Tx_SetFlow_1(); }break; case CS200_STATE_SetFlow_2: { proto_CS200_Tx_SetFlow_2(); }break; default: { }break; } if(SendTimeFlag) { return ; } else { pCS200->SendTime++; if(pCS200->SendTime >= 3) { pCS200->ErrorFlag |= (0x00000001 << pCS200->State);/*记录异常状态*/ pCS200->SendTime = 0; pCS200->State = CS200_STATE_GetCurrentData; } } }