Files
secs2-bootloader/usr/protocol/proto_CS200.c

274 lines
7.2 KiB
C

#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;
}
}
}