初版程序
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifndef _PROTO_CS200_H_
|
||||
#define _PROTO_CS200_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "proto_Modbus.h"
|
||||
|
||||
#define CS200_STATE_Init 0
|
||||
#define CS200_STATE_GetCurrentData 1
|
||||
#define CS200_STATE_SetFlow_1 2
|
||||
#define CS200_STATE_SetFlow_2 3
|
||||
|
||||
#define CS200_READ_STATE_ID_1 0
|
||||
#define CS200_READ_STATE_ID_2 1
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 ID;
|
||||
u16 BaudRate;
|
||||
u16 SetFlow;
|
||||
u16 Flow;
|
||||
u16 Range_u16;
|
||||
u8 ValveCmd;
|
||||
float SumFlow; //累计流量
|
||||
u8 SumFlow_Mode; //累计流量模式
|
||||
u8 Parity; //校验位
|
||||
u16 Valve_U; //阀电压
|
||||
float Range_Float;
|
||||
float SoftStartValue; //软启动值
|
||||
|
||||
float RealFlow; //实机流量值
|
||||
}proto_CS2000_CurrentData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
proto_CS2000_CurrentData_t CurrentData[2];
|
||||
u16 ErrorFlag;
|
||||
u8 SendTime;
|
||||
u8 TimeCount;
|
||||
|
||||
u8 ID_1,ID_2;
|
||||
u8 State;
|
||||
u8 ReadState;
|
||||
u16 SetFlowValue_1;
|
||||
u16 SetFlowValue_2;
|
||||
|
||||
void (*Init)(void);
|
||||
void (*Tx_Task)(void);
|
||||
void (*Rx_Task)(u8 *,u16);
|
||||
void (*SetFlow_1)(float);
|
||||
void (*SetFlow_2)(float);
|
||||
}proto_CS200_t;
|
||||
|
||||
|
||||
|
||||
extern proto_CS200_t CS200;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,169 @@
|
||||
#include "proto_HSMS.h"
|
||||
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#include "bsp_print.h"
|
||||
#include "bsp_W5500.h"
|
||||
#include "proto_SECS2.h"
|
||||
|
||||
|
||||
static void proto_HSMS_Init(void);
|
||||
static void proto_W5500_DataAnalysis(bsp_W5500_Class_t *pW5500_Class,u8 *pData,u16 Len);
|
||||
static void proto_HSMS_Rx_DataAnalysis(u8 *pData,u16 Len);
|
||||
static void proto_HSMS_Tx_Rsq(proto_HSMS_Header_Data_t *pHeader_Data,u8 *Tx_Data,u16 Tx_Data_Len,void *OtherData);
|
||||
|
||||
u8 proto_HSMS_Tx_Buffer[1024];
|
||||
|
||||
proto_HSMS_t HSMS =
|
||||
{
|
||||
.Init = proto_HSMS_Init,
|
||||
.Tx_RsqData = proto_HSMS_Tx_Rsq,
|
||||
};
|
||||
|
||||
proto_HSMS_t *pHSMS = &HSMS;
|
||||
|
||||
static void proto_HSMS_Init(void)
|
||||
{
|
||||
W5500.W5500_Class[0].Rx_DataAnalysis = proto_W5500_DataAnalysis;
|
||||
}
|
||||
|
||||
static void proto_HSMS_Send(u8 *pData,u16 Len)
|
||||
{
|
||||
Debug_UartSend(pData, Len);
|
||||
W5500.Socket_Send(&W5500.W5500_Class[0],pData,Len);
|
||||
}
|
||||
|
||||
static void proto_W5500_DataAnalysis(bsp_W5500_Class_t *pW5500_Class,u8 *pData,u16 Len)
|
||||
{
|
||||
proto_HSMS_Rx_DataAnalysis(pData,Len);
|
||||
}
|
||||
|
||||
/*响应请求*/
|
||||
static void proto_HSMS_Tx_Rsq(proto_HSMS_Header_Data_t *pHeader_Data,u8 *Tx_Data,u16 Tx_Data_Len,void *OtherData)
|
||||
{
|
||||
u8 *Tx = proto_HSMS_Tx_Buffer;
|
||||
u16 Len;
|
||||
|
||||
pHeader_Data->Data_Len = 10 + Tx_Data_Len;
|
||||
u32TOu8(pHeader_Data->Data_Len,Tx,PROTO_HSMS_ENDIAN);
|
||||
u16TOu8(pHeader_Data->Device_Id,&Tx[4],PROTO_HSMS_ENDIAN);
|
||||
|
||||
Tx[6] = pHeader_Data->Header_Byte2.ALL_Data;
|
||||
Tx[7] = pHeader_Data->Header_Byte3;
|
||||
Tx[8] = pHeader_Data->PType;
|
||||
Tx[9] = pHeader_Data->SType;
|
||||
u32TOu8(pHeader_Data->Sys_Byte,&Tx[10],PROTO_HSMS_ENDIAN);
|
||||
Len = 14;
|
||||
|
||||
if(NULL != Tx_Data && 0 != Tx_Data_Len)
|
||||
{
|
||||
memcpy(&Tx[Len],Tx_Data,Tx_Data_Len);
|
||||
Len += Tx_Data_Len;
|
||||
}
|
||||
|
||||
|
||||
proto_HSMS_Send(Tx,Len);
|
||||
Debug_UartSend(Tx,Len);
|
||||
}
|
||||
|
||||
void proto_HSMS_Header_DataAnalysis(proto_HSMS_Header_Data_t *pHeader_Data,u8 *pData)
|
||||
{
|
||||
/*拷贝数据进行解析*/
|
||||
pHeader_Data->Data_Len = u8TOu32(&pData[0],PROTO_HSMS_ENDIAN);
|
||||
pHeader_Data->Device_Id = u8TOu16(&pData[4],PROTO_HSMS_ENDIAN);
|
||||
pHeader_Data->Header_Byte2.ALL_Data = pData[6];
|
||||
pHeader_Data->Header_Byte3 = pData[7];
|
||||
pHeader_Data->PType = pData[8];
|
||||
pHeader_Data->SType = pData[9];
|
||||
pHeader_Data->Sys_Byte = u8TOu32(&pData[10],PROTO_HSMS_ENDIAN);
|
||||
}
|
||||
|
||||
void proto_HSMS_Rx_DataAnalysis(u8 *pData,u16 Len)
|
||||
{
|
||||
if(Len < 14)/*不满足最低长度*/
|
||||
return ;
|
||||
|
||||
proto_HSMS_Header_DataAnalysis(&pHSMS->Rx_Header_Data,pData);
|
||||
|
||||
/*长度判断*/
|
||||
if((pHSMS->Rx_Header_Data.Data_Len + 4) != Len)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
/*不是SECS2编码格式*/
|
||||
if(proto_HSMS_PTYPE_SECS2 != pHSMS->Rx_Header_Data.PType)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
switch(pHSMS->Rx_Header_Data.SType)
|
||||
{
|
||||
/*数据消息*/
|
||||
case PROTO_HSMS_STYPE_Data_Message :
|
||||
{
|
||||
/*匹配设备ID*/
|
||||
|
||||
if(pHSMS->Flash_ConfigData.Device_Id != pHSMS->Rx_Header_Data.Device_Id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
memcpy(&pHSMS->Tx_Header_Data,&pHSMS->Rx_Header_Data,sizeof(proto_HSMS_Header_Data_t));
|
||||
/*去除HSMS头部数据*/
|
||||
SECS2.Rx_DataAnalysis(&pHSMS->Tx_Header_Data,&pData[14],Len-14);
|
||||
|
||||
}break;
|
||||
/*选择请求*/
|
||||
case PROTO_HSMS_STYPE_Select_Req :
|
||||
{
|
||||
memcpy(&pHSMS->Tx_Header_Data,&pHSMS->Rx_Header_Data,sizeof(proto_HSMS_Header_Data_t));
|
||||
pHSMS->Tx_Header_Data.SType = PROTO_HSMS_STYPE_Select_Rsq;
|
||||
proto_HSMS_Tx_Rsq(&pHSMS->Tx_Header_Data,NULL,0,NULL);
|
||||
}break;
|
||||
/*选择响应*/
|
||||
case PROTO_HSMS_STYPE_Select_Rsq :
|
||||
{
|
||||
|
||||
}break;
|
||||
/*取消选择请求*/
|
||||
case PROTO_HSMS_STYPE_Deselect_Req :
|
||||
{
|
||||
memcpy(&pHSMS->Tx_Header_Data,&pHSMS->Rx_Header_Data,sizeof(proto_HSMS_Header_Data_t));
|
||||
pHSMS->Tx_Header_Data.SType = PROTO_HSMS_STYPE_Deselect_Rsq;
|
||||
proto_HSMS_Tx_Rsq(&pHSMS->Tx_Header_Data,NULL,0,NULL);
|
||||
}break;
|
||||
/*取消选择响应*/
|
||||
case PROTO_HSMS_STYPE_Deselect_Rsq :
|
||||
{
|
||||
|
||||
}break;
|
||||
/*连接测试请求*/
|
||||
case PROTO_HSMS_STYPE_Linktest_Req :
|
||||
{
|
||||
memcpy(&pHSMS->Tx_Header_Data,&pHSMS->Rx_Header_Data,sizeof(proto_HSMS_Header_Data_t));
|
||||
pHSMS->Tx_Header_Data.SType = PROTO_HSMS_STYPE_Linktest_Rsp;
|
||||
proto_HSMS_Tx_Rsq(&pHSMS->Tx_Header_Data,NULL,0,NULL);
|
||||
}break;
|
||||
/*连接测试响应*/
|
||||
case PROTO_HSMS_STYPE_Linktest_Rsp :
|
||||
{
|
||||
|
||||
}break;
|
||||
/*拒绝请求*/
|
||||
case PROTO_HSMS_STYPE_Reject_Req :
|
||||
{
|
||||
|
||||
}break;
|
||||
/*断开请求*/
|
||||
case PROTO_HSMS_STYPE_Separate_Req :
|
||||
{
|
||||
|
||||
}break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef _PROTO_HSMS_H_
|
||||
#define _PROTO_HSMS_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "proto_Modbus.h"
|
||||
|
||||
#define PROTO_HSMS_ENDIAN BIG_ENDIAN
|
||||
|
||||
/*表示类型 PType*/
|
||||
#define proto_HSMS_PTYPE_SECS2 0 /*SECS-II 编码格式*/
|
||||
|
||||
/*会话类型 SType*/
|
||||
#define PROTO_HSMS_STYPE_Data_Message 0 /*数据消息*/
|
||||
#define PROTO_HSMS_STYPE_Select_Req 1 /*选择请求*/
|
||||
#define PROTO_HSMS_STYPE_Select_Rsq 2 /*选择响应*/
|
||||
#define PROTO_HSMS_STYPE_Deselect_Req 3 /*取消选择请求*/
|
||||
#define PROTO_HSMS_STYPE_Deselect_Rsq 4 /*取消选择响应*/
|
||||
#define PROTO_HSMS_STYPE_Linktest_Req 5 /*连接测试请求*/
|
||||
#define PROTO_HSMS_STYPE_Linktest_Rsp 6 /*连接测试响应*/
|
||||
#define PROTO_HSMS_STYPE_Reject_Req 7 /*拒绝请求*/
|
||||
#define PROTO_HSMS_STYPE_Separate_Req 9 /*断开请求*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 Data_Len; /*字节长度*/
|
||||
u16 Device_Id; /*会话/设备标识*/
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 Stream: 7;
|
||||
u8 Wait: 1; /*指令是否需要回复*/
|
||||
}Analysis_Data;
|
||||
u8 ALL_Data;
|
||||
}Header_Byte2;
|
||||
|
||||
u8 Header_Byte3; /*头部字节3*/
|
||||
u8 PType; /*表示类型*/
|
||||
u8 SType; /*会话类型*/
|
||||
u32 Sys_Byte; /*系统字节:标记这次指令的ID,通常用于超时判断(响应时依据发送者指令的最后4字节作为回复,发送时生成不重复的4个字节)*/
|
||||
}proto_HSMS_Header_Data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 Device_Id; /*会话/设备标识*/
|
||||
}proto_HSMS_Flash_Data_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
proto_HSMS_Header_Data_t Rx_Header_Data; /*接收解析的头部数据*/
|
||||
proto_HSMS_Header_Data_t Tx_Header_Data; /*发送时的头部数据*/
|
||||
proto_HSMS_Flash_Data_t Flash_ConfigData; /*存入Flash的配置参数*/
|
||||
|
||||
void (*Init)(void);
|
||||
void (*Tx_RsqData)(proto_HSMS_Header_Data_t *,u8 *,u16 ,void *);
|
||||
|
||||
}proto_HSMS_t;
|
||||
|
||||
extern proto_HSMS_t HSMS;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,294 @@
|
||||
#include "proto_Modbus.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "bsp_Uart.h"
|
||||
|
||||
u16 ModbusCrc16(u8 *pData, u16 Len)
|
||||
{
|
||||
u16 CRC_16 = 0xffff;
|
||||
u16 i;
|
||||
while(Len--)
|
||||
{
|
||||
CRC_16 = CRC_16^(*pData++);
|
||||
for(i=0; i++<8; )
|
||||
{
|
||||
if(CRC_16&0x0001)
|
||||
{
|
||||
CRC_16 = (CRC_16>>1)^0xa001;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRC_16>>=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CRC_16;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* 函数: Float2u16
|
||||
* 功能: 提取浮点数的高16或低16位
|
||||
* 参数: FloatData : 要转换的浮点数
|
||||
HorL : 返回高16位还是低16位
|
||||
* 返回: 返回对应的高16位还是低16位
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
u16 FloatTOu16(float FloatData,u8 HorL)
|
||||
{
|
||||
u16 Temp = 0XFFFF;
|
||||
if(HorL == U16_DATA_L)
|
||||
{
|
||||
Temp = *((u32 *)&FloatData) & 0x0000ffff;
|
||||
}
|
||||
else if(HorL == U16_DATA_H)
|
||||
{
|
||||
Temp = ((*((u32 *)&FloatData)) >> 16) & 0x0000ffff;
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* 函数: u32TOu16
|
||||
* 功能: 提取u32的高16或低16位
|
||||
* 参数: u32Data : 要转换的u32
|
||||
HorL : 返回高16位还是低16位
|
||||
* 返回: 返回对应的高16位还是低16位
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
u16 u32TOu16(u32 u32Data,u8 HorL)
|
||||
{
|
||||
u16 Temp = 0XFFFF;
|
||||
if(HorL == U16_DATA_L)
|
||||
{
|
||||
Temp = u32Data & 0x0000ffff;
|
||||
}
|
||||
else if(HorL == U16_DATA_H)
|
||||
{
|
||||
Temp = (u32Data >> 16) & 0x0000ffff;
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
void u32TOu8(u32 u32Data,u8 *pData,u8 Endian)
|
||||
{
|
||||
if(BIG_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
pData[i] = (u32Data >> (8 * (3 - i))) & 0xff;
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
pData[i] = (u32Data >> (8 * i)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void u16TOu8(u16 u16Data,u8 *pData,u8 Endian)
|
||||
{
|
||||
if(BIG_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
pData[i] = (u16Data >> (8 * (1 - i))) & 0xff;
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
pData[i] = (u16Data >> (8 * i)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float u32TOFloat(u32 u32Data,u8 HorL)
|
||||
{
|
||||
float Temp = 0;
|
||||
Temp = *((float *)&u32Data);
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/*将u8Endian端序的p_u8Data转换为单片机对应的小端序*/
|
||||
u32 u8TOu32(u8 *p_u8Data,u8 u8Endian)
|
||||
{
|
||||
u32 Temp = 0;
|
||||
if(BIG_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << ((3 - i) * 8);
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << (i * 8);
|
||||
}
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/*将u8Endian端序的p_u8Data转换为单片机对应的小端序*/
|
||||
u16 u8TOu16(u8 *p_u8Data,u8 u8Endian)
|
||||
{
|
||||
u32 Temp = 0;
|
||||
if(BIG_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << ((1 - i) * 8);
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << (i * 8);
|
||||
}
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
|
||||
/*字节端序转换*/
|
||||
u32 u32_EndianConv(u32 Data)
|
||||
{
|
||||
u32 TempData = 0;
|
||||
TempData = (((Data >> 0 ) & 0xff) << 24)
|
||||
| (((Data >> 8 ) & 0xff) << 16)
|
||||
| (((Data >> 16) & 0xff) << 8 )
|
||||
| (((Data >> 24) & 0xff) << 0 );
|
||||
return TempData;
|
||||
}
|
||||
|
||||
/*字节端序转换*/
|
||||
u16 u16_EndianConv(u16 Data)
|
||||
{
|
||||
u16 TempData = 0;
|
||||
TempData = (((Data >> 0) & 0xff) << 8)
|
||||
| (((Data >> 8) & 0xff) << 0);
|
||||
return TempData;
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
* 函数: ModbusReadData
|
||||
* 功能: MODBUS读数据
|
||||
* 参数: Id :MODBUS从机地址
|
||||
* Addr :写数据的起始地址
|
||||
* Num :写的寄存器数量
|
||||
* UsartSendBuffer :串口发送函数
|
||||
* 返回: 无
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
void ModbusReadData(u8 Id,u16 Addr,u16 Num,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[8];
|
||||
u16 CRC16;
|
||||
Tx[0] = Id;
|
||||
Tx[1] = 0x03;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Num >> 8) & 0xff;
|
||||
Tx[5] = Num & 0xff;
|
||||
CRC16 = ModbusCrc16(Tx,6);
|
||||
Tx[6] = CRC16 & 0xff;
|
||||
Tx[7] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,8);
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* 函数: ModbusWriteMultipleData
|
||||
* 功能: MODBUS写数据
|
||||
* 参数: Id :MODBUS从机地址
|
||||
* Addr :写数据的起始地址
|
||||
* Num :写的寄存器数量
|
||||
* Data :写的数据
|
||||
* UsartSendBuffer :串口发送函数
|
||||
* 返回: 无
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
void ModbusWriteMultipleData(u8 ID,u16 Addr,u16 Num,u16 *Data,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[50],i;
|
||||
u16 CRC16;
|
||||
Tx[0] = ID;
|
||||
Tx[1] = 0x10;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Num >> 8) & 0xff;
|
||||
Tx[5] = Num & 0xff;
|
||||
Tx[6] = Num * 2;
|
||||
for(i = 0;i < Tx[6]/2;i++)
|
||||
{
|
||||
Tx[7 + 2 * i] = (Data[i] >> 8) & 0xff;
|
||||
Tx[8 + 2 * i] = Data[i] & 0xff;
|
||||
}
|
||||
CRC16 = ModbusCrc16(Tx,7 + 2 * i);
|
||||
Tx[7 + 2 * i] = CRC16 & 0xff;
|
||||
Tx[8 + 2 * i] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,9 + 2 * i);
|
||||
}
|
||||
|
||||
void ModbusyWriteOnlData(u8 ID,u16 Addr,u16 Value,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[8];
|
||||
u16 CRC16;
|
||||
Tx[0] = ID;
|
||||
Tx[1] = 0x06;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Value >> 8) & 0xff;
|
||||
Tx[5] = Value & 0xff;
|
||||
CRC16 = ModbusCrc16(Tx,6);
|
||||
Tx[6] = CRC16 & 0xff;
|
||||
Tx[7] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,8);
|
||||
}
|
||||
|
||||
|
||||
//01 10 00 02 00 01 02 12 34 CRC
|
||||
//ID Func StartAddress RegNumber wDataAddress
|
||||
u8 ModbusAnalysis(ModbusAnalysisData_t *pModbus, u8 *pData, u16 len)
|
||||
{
|
||||
u16 CRC_16;
|
||||
u16 TempU16;
|
||||
|
||||
if(NULL == pModbus) return 0;
|
||||
if(len < 8) return 0;
|
||||
|
||||
CRC_16 = ModbusCrc16(pData, len-2);
|
||||
TempU16 = *(pData+len-1);
|
||||
TempU16 <<= 8;
|
||||
TempU16 |= *(pData+len-2);
|
||||
if(TempU16 != CRC_16) return 0;
|
||||
|
||||
pModbus->ID = *pData;
|
||||
pModbus->Func = *(pData+1);
|
||||
|
||||
pModbus->StartAddress = (*(pData+2))<<8;
|
||||
pModbus->StartAddress |= *(pData+3);
|
||||
|
||||
/*单独写一个寄存器*/
|
||||
if(0x06 == pModbus->Func)
|
||||
{
|
||||
pModbus->wDataAddress = pData+4;
|
||||
}
|
||||
else if(0x10 == pModbus->Func) /*写多个寄存器*/
|
||||
{
|
||||
pModbus->RegNumber = (*(pData+4))<<8;
|
||||
pModbus->RegNumber |= *(pData+5);
|
||||
pModbus->wDataAddress = pData+7;
|
||||
}
|
||||
else
|
||||
{
|
||||
pModbus->RegNumber = (*(pData+4))<<8;
|
||||
pModbus->RegNumber |= *(pData+5);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef _PROTO_MODBUS_H_
|
||||
#define _PROTO_MODBUS_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define MODBUS_DEFAULT_ID (0x01)
|
||||
#define MODBUS_SENDBUF_LEN (512U)
|
||||
|
||||
#define U16_DATA_L (0)//低16位
|
||||
#define U16_DATA_H (1)//高16位
|
||||
|
||||
#define BIG_ENDIAN (0)//大端序
|
||||
#define LITTLE_ENDIAN (1)//小端序
|
||||
|
||||
typedef struct _ModbusCommunicationSendBuf{
|
||||
u8 SendBuffer[MODBUS_SENDBUF_LEN];
|
||||
u16 Len;
|
||||
}ModbusCommunicationSendBuf_t;
|
||||
|
||||
typedef struct _ModbusAnalysisData
|
||||
{
|
||||
u8 ID; /*ModbusID*/
|
||||
u8 Func; /*功能号*/
|
||||
u16 StartAddress; /*起始地址*/
|
||||
u16 RegNumber; /*寄存器数量*/
|
||||
u8 *wDataAddress; /*写入寄存器数据地址*/
|
||||
}ModbusAnalysisData_t;
|
||||
|
||||
typedef enum _ModbusErrorCode
|
||||
{
|
||||
ModbusErrorCode_Success = 0x00,
|
||||
ModbusErrorCode_IllegalFunction = 0x01,
|
||||
ModbusErrorCode_IllegalAddr = 0x02,
|
||||
ModbusErrorCode_IllegalData = 0x03,
|
||||
ModbusErrorCode_DeviceBusy = 0x06
|
||||
}ModbusErrorCode_e;
|
||||
|
||||
typedef struct proto_Modbus_t proto_Modbus_t;
|
||||
struct proto_Modbus_t
|
||||
{
|
||||
u8 ID;
|
||||
u16 (*DataRead)(u16); /*Modbus读数据*/
|
||||
ModbusErrorCode_e (*DataWrite)(u16,u16); /*Modbus写数据*/
|
||||
void (*Init)(void); /*初始化函数*/
|
||||
void (*Task)(void); /*任务函数*/
|
||||
void (*DataAnalysis)(u8 *,u16,void *); /*数据解析*/
|
||||
};
|
||||
|
||||
u16 ModbusCrc16(u8 *pData, u16 Len);
|
||||
u16 FloatTOu16(float FloatData,unsigned char HorL);
|
||||
u16 u32TOu16(u32 u32Data,unsigned char HorL);
|
||||
u32 u8TOu32(u8 *p_u8Data,unsigned char u8Endian);
|
||||
u16 u8TOu16(u8 *p_u8Data,unsigned char u8Endian);
|
||||
|
||||
void u32TOu8(u32 u32Data,u8 *pData,u8 Endian);
|
||||
void u16TOu8(u16 u16Data,u8 *pData,u8 Endian);
|
||||
|
||||
u32 u32_EndianConv(u32 Data);
|
||||
u16 u16_EndianConv(u16 Data);
|
||||
|
||||
void ModbusReadData(u8 Id,u16 Addr,u16 Num,void (*UsartSendBuffer)(u8 *,u16 ));
|
||||
void ModbusWriteMultipleData(u8 ID,u16 Addr,u16 Num,u16 *Data,void (*UsartSendBuffer)(u8 *,u16 ));
|
||||
void ModbusyWriteOnlData(u8 ID,u16 Addr,u16 Value,void (*UsartSendBuffer)(u8 *,u16 ));
|
||||
u8 ModbusAnalysis(ModbusAnalysisData_t *pModbus, u8 *pData, u16 len);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,751 @@
|
||||
#include "proto_PM100.h"
|
||||
#include "proto_Modbus.h"
|
||||
#include "proto_SECS2.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;
|
||||
}
|
||||
SECS2.Set_Ask.flag = 0;
|
||||
SECS2.Set_Ask.state = PROTO_PM100_CMD_GET_STATE_ALARM;
|
||||
}
|
||||
|
||||
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<len;i++)
|
||||
{
|
||||
Sum += pData[i];
|
||||
}
|
||||
return Sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*启动设备*/
|
||||
static void proto_PM100_Tx_Start(u8 Dev)
|
||||
{
|
||||
char Tx[20];
|
||||
u16 Len;
|
||||
Tx[0] = PROTO_PM100_FRAME_STRUCT_STX;
|
||||
|
||||
sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_START);
|
||||
|
||||
if(PROTO_PM100_DEV_MP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_MP;
|
||||
}
|
||||
else if(PROTO_PM100_DEV_BP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_BP;
|
||||
}
|
||||
else/*异常*/
|
||||
{
|
||||
return ;
|
||||
}
|
||||
Tx[5] = PROTO_PM100_FRAME_STRUCT_ETX;
|
||||
sprintf(&Tx[6],"%02X",proto_PM100_CheckSum((u8 *)Tx,6));
|
||||
Tx[8] = PROTO_PM100_FRAME_STRUCT_CR;
|
||||
Len = 9;
|
||||
proto_PM100_Send((u8*)Tx,Len);
|
||||
}
|
||||
|
||||
/*停止设备*/
|
||||
static void proto_PM100_Tx_Stop(u8 Dev)
|
||||
{
|
||||
char Tx[20];
|
||||
u16 Len;
|
||||
Tx[0] = PROTO_PM100_FRAME_STRUCT_STX;
|
||||
|
||||
sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_STOP);
|
||||
|
||||
if(PROTO_PM100_DEV_MP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_MP;
|
||||
}
|
||||
else if(PROTO_PM100_DEV_BP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_BP;
|
||||
}
|
||||
else/*异常*/
|
||||
{
|
||||
return ;
|
||||
}
|
||||
Tx[5] = PROTO_PM100_FRAME_STRUCT_ETX;
|
||||
sprintf(&Tx[6],"%02X",proto_PM100_CheckSum((u8 *)Tx,6));
|
||||
Tx[8] = PROTO_PM100_FRAME_STRUCT_CR;
|
||||
Len = 9;
|
||||
proto_PM100_Send((u8*)Tx,Len);
|
||||
}
|
||||
|
||||
|
||||
/*复位设备*/
|
||||
static void proto_PM100_Tx_Reset(void)
|
||||
{
|
||||
char Tx[20];
|
||||
u16 Len;
|
||||
Tx[0] = PROTO_PM100_FRAME_STRUCT_STX;
|
||||
|
||||
sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_RESET);
|
||||
|
||||
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_Set_Mode(u8 Mode)
|
||||
{
|
||||
char Tx[20];
|
||||
u16 Len;
|
||||
Tx[0] = PROTO_PM100_FRAME_STRUCT_STX;
|
||||
|
||||
sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_SET_MODE);
|
||||
|
||||
if(PROTO_PM100_MODE_NORMAL == Mode)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_MODE_CHAR_NORMAL;
|
||||
}
|
||||
else if(PROTO_PM100_MODE_POWER_SAVING == Mode)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_MODE_CHAR_POWER_SAVING;
|
||||
}
|
||||
else/*异常*/
|
||||
{
|
||||
return ;
|
||||
}
|
||||
Tx[5] = PROTO_PM100_FRAME_STRUCT_ETX;
|
||||
sprintf(&Tx[6],"%02X",proto_PM100_CheckSum((u8 *)Tx,6));
|
||||
Tx[8] = PROTO_PM100_FRAME_STRUCT_CR;
|
||||
Len = 9;
|
||||
proto_PM100_Send((u8*)Tx,Len);
|
||||
}
|
||||
|
||||
/*设置模式和转速*/
|
||||
static void proto_PM100_Tx_Set_Mode_Speed(u8 Dev,u8 Mode,u16 Speed)
|
||||
{
|
||||
char Tx[20];
|
||||
u16 Len;
|
||||
Tx[0] = PROTO_PM100_FRAME_STRUCT_STX;
|
||||
|
||||
sprintf(&Tx[1],"%s",PROTO_PM100_CMD_STR_SET_SPEED);
|
||||
|
||||
if(PROTO_PM100_DEV_MP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_MP;
|
||||
}
|
||||
else if(PROTO_PM100_DEV_BP == Dev)
|
||||
{
|
||||
Tx[4] = PROTO_PM100_DEV_CHAR_BP;
|
||||
}
|
||||
else/*异常*/
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
if(PROTO_PM100_MODE_NORMAL == Mode)
|
||||
{
|
||||
Tx[5] = PROTO_PM100_MODE_CHAR_NORMAL;
|
||||
}
|
||||
else if(PROTO_PM100_MODE_POWER_SAVING == Mode)
|
||||
{
|
||||
Tx[5] = PROTO_PM100_MODE_CHAR_POWER_SAVING;
|
||||
}
|
||||
else/*异常*/
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(Speed > 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(pPM100->SendTime >= 3)
|
||||
{
|
||||
pPM100->SendTime = 0;
|
||||
if(SECS2.Set_Ask.state != pPM100->Sys_State && pPM100->Sys_State != PROTO_PM100_CMD_GET_DATA)
|
||||
{
|
||||
SECS2.Set_Ask.flag = 3;
|
||||
}
|
||||
pPM100->Sys_State = PROTO_PM100_CMD_GET_STATE_ALARM;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
/*接收数据解析*/
|
||||
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;
|
||||
SECS2.Set_Ask.flag = 1;
|
||||
proto_PM100_SysState_Switch();
|
||||
}
|
||||
else
|
||||
{
|
||||
SECS2.Set_Ask.flag = 2;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
#ifndef _PROTO_PM100_H_
|
||||
#define _PROTO_PM100_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "algo_queue.h"
|
||||
|
||||
|
||||
|
||||
/*数据帧格式 STX TEXT ETX SUM CR*/
|
||||
#define PROTO_PM100_FRAME_STRUCT_STX (0x02)
|
||||
|
||||
#define PROTO_PM100_FRAME_STRUCT_ETX (0x03)
|
||||
|
||||
#define PROTO_PM100_FRAME_STRUCT_CR (0x0D)
|
||||
|
||||
|
||||
/*设备*/
|
||||
#define PROTO_PM100_DEV_MP 0 /*主泵*/
|
||||
#define PROTO_PM100_DEV_BP 1 /*增加泵*/
|
||||
|
||||
#define PROTO_PM100_MODE_NORMAL 0 /*NORMAL 正常*/
|
||||
#define PROTO_PM100_MODE_POWER_SAVING 1 /*POWER-SAVING 节能*/
|
||||
|
||||
#define PROTO_PM100_MODE_RUN 0 /*设备运行*/
|
||||
#define PROTO_PM100_MODE_ALARM 1 /*设备报警*/
|
||||
#define PROTO_PM100_MODE_PE 2
|
||||
#define PROTO_PM100_MODE_IDIE 3 /*设备空闲/停止*/
|
||||
#define PROTO_PM100_MODE_OFFLINE 4 /*设备离线*/
|
||||
#define PROTO_PM100_MODE_ONLINE 5 /*设备在线*/
|
||||
|
||||
#define PROTO_PM100_MODE_RUNING 0 /*运行*/
|
||||
#define PROTO_PM100_MODE_STOP 1 /*停止*/
|
||||
|
||||
#define PROTO_PM100_DEV_CHAR_MP ('M') /*主泵*/
|
||||
#define PROTO_PM100_DEV_CHAR_BP ('B') /*增加泵*/
|
||||
|
||||
#define PROTO_PM100_MODE_CHAR_NORMAL ('N') /*NORMAL 正常*/
|
||||
#define PROTO_PM100_MODE_CHAR_POWER_SAVING ('S') /*POWER-SAVING 节能*/
|
||||
|
||||
#define PROTO_PM100_MODE_CHAR_RUNING ('R') /*运行*/
|
||||
#define PROTO_PM100_MODE_CHAR_STOP ('S') /*停止*/
|
||||
|
||||
/*指令*/
|
||||
/*字符串*/
|
||||
#define PROTO_PM100_CMD_STR_START ("S20") /*启动*/
|
||||
#define PROTO_PM100_CMD_STR_STOP ("S21") /*停止*/
|
||||
#define PROTO_PM100_CMD_STR_RESET ("S22") /*复位*/
|
||||
#define PROTO_PM100_CMD_STR_SET_MODE ("S23") /*设置泵模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
#define PROTO_PM100_CMD_STR_SET_SPEED ("S24") /*设置转速模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
#define PROTO_PM100_CMD_STR_GET_DATA ("M20") /*读取用户选择的模拟量*/
|
||||
#define PROTO_PM100_CMD_STR_GET_STATE_ALARM ("M21") /*读取运行状态与报警*/
|
||||
|
||||
#define PROTO_PM100_CMD_STR_SET_OK ("OK") /*设置成功*/
|
||||
#define PROTO_PM100_CMD_STR_SET_NG ("NG") /*设置失败*/
|
||||
#define PROTO_PM100_CMD_STR_SET_END ("END") /*发送结束*/
|
||||
|
||||
/*CMD*/
|
||||
#define PROTO_PM100_CMD_START 0 /*启动*/
|
||||
#define PROTO_PM100_CMD_STOP 2 /*停止*/
|
||||
#define PROTO_PM100_CMD_RESET 3 /*复位*/
|
||||
#define PROTO_PM100_CMD_SET_MODE 4 /*设置泵模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
#define PROTO_PM100_CMD_SET_SPEED 5 /*设置转速模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
#define PROTO_PM100_CMD_GET_DATA 6 /*读取用户选择的模拟量*/
|
||||
#define PROTO_PM100_CMD_GET_STATE_ALARM 7 /*读取运行状态与报警*/
|
||||
|
||||
#define BP_ON ("BPON") /*bp启动*/
|
||||
#define MP_ON ("MPON") /*mp启动*/
|
||||
#define ALL_RESET ("ALLRESET") /*重置*/
|
||||
#define BP_STOP ("BPSTOP") /*bp停止*/
|
||||
#define MP_STOP ("MPSTOP") /*mp停止*/
|
||||
#define NORMAL ("N") /*正常模式*/
|
||||
#define POWER_SAVE ("S") /*节能模式*/
|
||||
#define MP_NORMAL_SPEED ("MN") /*mp正常模式转速*/
|
||||
#define MP_SAVE_SPEED ("MS") /*mp节能模式转速*/
|
||||
#define BP_NORMAL_SPEED ("BN") /*bp正常模式转速*/
|
||||
#define BP_SAVE_SPEED ("BS") /*bp节能模式转速*/
|
||||
|
||||
#define PROTO_PM100_GET_DATA_CODE (0x007FD9FF)/*获取哪些实数数据*/
|
||||
|
||||
|
||||
#define PROTO_PM100_ERROR_CODE_TIMEOUT (0x0001)/*通讯超时*/
|
||||
|
||||
/*PM100模拟量数据*/
|
||||
typedef struct
|
||||
{
|
||||
float Total_running_time; /*H*/
|
||||
float BP_power ; /*KW*/
|
||||
float MP_power ; /*KW*/
|
||||
float BP_motor_speed ; /*K/min*/
|
||||
float MP_motor_speed ; /*K/min*/
|
||||
float BP_current ; /*A*/
|
||||
float MP_current ; /*A*/
|
||||
float BP_casing_temp ; /*℃*/
|
||||
float MP_casing_temp ; /*℃*/
|
||||
float Reserved_1[2] ; /* */
|
||||
float Cooling_water_flow; /*L/min*/
|
||||
float Pump_N2_flow ; /*Pam3/s*/
|
||||
float Reserved ; /* */
|
||||
float Back_pressure_1 ; /*KPa*/
|
||||
float Heater1 ; /*℃*/
|
||||
float Heater2 ; /*℃*/
|
||||
float Heater3 ; /*℃*/
|
||||
float Heater4 ; /*℃*/
|
||||
float Vacuum_pressure ; /*KPa*/
|
||||
float Cooler_1 ; /*℃*/
|
||||
float Cooler_2 ; /*℃*/
|
||||
float Cooler_3 ; /*℃*/
|
||||
float Reserved_2[9] ; /*H*/
|
||||
}proto_PM100_AnalogData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 Sys_State;
|
||||
u8 Dev;
|
||||
u8 Mode;
|
||||
u16 Speed;
|
||||
u32 Analog_Code; /*获取哪些模拟量数据*/
|
||||
}proto_PM100_Set_Data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 Run_Status;
|
||||
u8 MP_Status;
|
||||
u8 BP_Status;
|
||||
u32 Warming_Code; /*设备状态码*/
|
||||
u32 Alarm_Code; /*报警状态码*/
|
||||
char alarm_start_str[32][15]; // 报警开始时间字符串 YYYYMMDDHHMMSS
|
||||
char warning_start_str[32][15]; // 警告开始时间字符串
|
||||
u32 alarm_start_sec[32]; // 报警开始秒数(基准2000-01-01)
|
||||
u32 warning_start_sec[32]; // 警告开始秒数
|
||||
}proto_Opera_Status_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
queue Sys_StateQueue; /*状态队列*/
|
||||
u8 Sys_State; /*协议程序运行状态*/
|
||||
u8 SendTime; /*指令发送次数*/
|
||||
proto_PM100_AnalogData_t AnalogData;
|
||||
|
||||
u16 time_out_count; /*超时计数*/
|
||||
u32 error_code; /*设备状态*/
|
||||
|
||||
struct
|
||||
{
|
||||
u8 FirstFlag;
|
||||
u8 EndFlag;
|
||||
u16 CountTime;
|
||||
}AnalogData_Control; /*读取模拟数据相关的控制参数*/
|
||||
|
||||
struct
|
||||
{
|
||||
u64 Code_Last; /*上一次的报警值*/
|
||||
|
||||
u16 StartTime; /*计时*/
|
||||
void (*Reset)(void); /*复位报警,不再上发*/
|
||||
}Alarm_Control; /*报警上发的相关数据*/
|
||||
|
||||
proto_PM100_Set_Data_t Set_Data; /*设置的参数*/
|
||||
|
||||
proto_Opera_Status_t Opera_Status;
|
||||
|
||||
struct
|
||||
{
|
||||
proto_Opera_Status_t Opera_Status_Last; /*上一次的设备状态*/
|
||||
|
||||
u16 StartTime; /*计时*/
|
||||
void (*Reset)(void); /*更新状态,不再上发*/
|
||||
}Dev_Status_Control; /*设备状态控制*/
|
||||
|
||||
struct
|
||||
{
|
||||
void (*Start)(u8); /*启动*/
|
||||
void (*Stop)(u8); /*停止*/
|
||||
void (*Reset)(void); /*复位*/
|
||||
void (*Set_Mode)(u8); /*设置泵模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
void (*Set_Speed)(u8,u8,u16); /*设置转速模式:NORMAL/POWER-SAVING 正常/节能*/
|
||||
}Control;
|
||||
|
||||
void (*Init)(void);
|
||||
void (*Rx_Task)(u8 *,u16,void *);
|
||||
void (*Tx_Task)(void);
|
||||
}proto_PM100_t;
|
||||
|
||||
|
||||
extern proto_PM100_t PM100;
|
||||
extern char *proto_PM100_Str_WarmingCode[32];
|
||||
extern char *proto_PM100_Str_AlarmCode[32];
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,894 @@
|
||||
#include "proto_Para_Modbus.h"
|
||||
#include "string.h"
|
||||
#include "bsp_Uart.h"
|
||||
#include "os_timer.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#include "test_echo.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "bsp_W5500.h"
|
||||
#include "bsp_W5500_1.h"
|
||||
#include "proto_HSMS.h"
|
||||
#include "bsp_Flash.h"
|
||||
#include "bsp_Wdg.h"
|
||||
#include "bsp_DS1302.h"
|
||||
|
||||
static ModbusAnalysisData_t ModbusAnalysisData;//指令解析结构体
|
||||
static ModbusCommunicationSendBuf_t SendStruct;//发送结构体
|
||||
|
||||
static void ModbusCommunicationDataReceive(u8 *pData, u16 len,void *other_data);
|
||||
static void ModbusCommunicationDataSend(u8 *pData, u16 len);
|
||||
static void proto_Modbus_Init(void);
|
||||
static void proto_Modbus_Task(void);
|
||||
static ModbusErrorCode_e ModbusCommunicationDataWrite(u16 Addr, u16 Value);
|
||||
static u16 ModbusCommunicationDataRead(u16 Addr);
|
||||
|
||||
proto_Modbus_t Para_Modbus=
|
||||
{
|
||||
.ID = 0x01,
|
||||
.DataRead = ModbusCommunicationDataRead,
|
||||
.DataWrite = ModbusCommunicationDataWrite,
|
||||
.DataAnalysis = ModbusCommunicationDataReceive,
|
||||
.Init = proto_Modbus_Init,
|
||||
.Task = proto_Modbus_Task,
|
||||
};
|
||||
|
||||
static proto_Modbus_t *pModbus = &Para_Modbus;
|
||||
static bsp_Uart_t *rx_uart = NULL;
|
||||
|
||||
static void ModbusCommunicationDataSend(u8 *pData, u16 Len)
|
||||
{
|
||||
if(&COM_Uart1 == rx_uart)
|
||||
{
|
||||
COM_Uart1.Send(&COM_Uart1,pData,Len);
|
||||
}
|
||||
else if(&COM_Uart2 == rx_uart)
|
||||
{
|
||||
COM_Uart2.Send(&COM_Uart2,pData,Len);
|
||||
}
|
||||
}
|
||||
|
||||
static void proto_Modbus_Init(void)
|
||||
{
|
||||
COM_Uart1.Rx_DataAnalysis = ModbusCommunicationDataReceive;
|
||||
COM_Uart2.Rx_DataAnalysis = ModbusCommunicationDataReceive;
|
||||
}
|
||||
static void proto_Modbus_Task(void)
|
||||
{
|
||||
|
||||
}
|
||||
static void ModbusCommunicationDataReceive(u8 *pData, u16 len,void *other_data)
|
||||
{
|
||||
ModbusErrorCode_e ErrorCode;
|
||||
u8 inx;
|
||||
u16 TempAddr, TempData, Crc16;
|
||||
|
||||
if (0 == ModbusAnalysis(&ModbusAnalysisData, pData, len))//检查数据长度 校验是否正确
|
||||
return;
|
||||
if (pModbus->ID != ModbusAnalysisData.ID)//判断ID是否正确
|
||||
return;
|
||||
|
||||
ErrorCode = ModbusErrorCode_Success;
|
||||
rx_uart = (bsp_Uart_t *)other_data;
|
||||
|
||||
/* //检查地址是否超出范围
|
||||
if ((ModbusAnalysisData.StartAddress >= MODBUS_REG_LEN) || (ModbusAnalysisData.RegNumber >= MODBUS_REG_LEN) ||
|
||||
(ModbusAnalysisData.StartAddress + ModbusAnalysisData.RegNumber >= MODBUS_REG_LEN))
|
||||
{
|
||||
ErrorCode = ModbusErrorCode_IllegalAddr;
|
||||
goto Error;
|
||||
}
|
||||
*/
|
||||
|
||||
switch (ModbusAnalysisData.Func)
|
||||
{
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
{
|
||||
TempAddr = ModbusAnalysisData.StartAddress;
|
||||
SendStruct.SendBuffer[0] = ModbusAnalysisData.ID;
|
||||
SendStruct.SendBuffer[1] = ModbusAnalysisData.Func;
|
||||
SendStruct.SendBuffer[2] = 2 * ModbusAnalysisData.RegNumber;
|
||||
for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++)
|
||||
{
|
||||
TempData = ModbusCommunicationDataRead(TempAddr);
|
||||
SendStruct.SendBuffer[3 + 2 * inx] = (TempData >> 8) & 0xff;
|
||||
SendStruct.SendBuffer[4 + 2 * inx] = TempData & 0xff;
|
||||
TempAddr++;
|
||||
}
|
||||
Crc16 = ModbusCrc16(SendStruct.SendBuffer, 3 + SendStruct.SendBuffer[2]);
|
||||
SendStruct.SendBuffer[3 + SendStruct.SendBuffer[2]] = Crc16 & 0xff;
|
||||
SendStruct.SendBuffer[4 + SendStruct.SendBuffer[2]] = (Crc16 >> 8) & 0xff;
|
||||
SendStruct.Len = 5 + SendStruct.SendBuffer[2];
|
||||
}goto Success;
|
||||
/*特殊协议*/
|
||||
case 0x41:
|
||||
{
|
||||
TempAddr = ModbusAnalysisData.StartAddress;
|
||||
SendStruct.SendBuffer[0] = ModbusAnalysisData.ID;
|
||||
SendStruct.SendBuffer[1] = ModbusAnalysisData.Func;
|
||||
SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8;
|
||||
SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff;
|
||||
SendStruct.SendBuffer[4] = (2 * ModbusAnalysisData.RegNumber) >> 8;
|
||||
SendStruct.SendBuffer[5] = (2 * ModbusAnalysisData.RegNumber) & 0xff;
|
||||
for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++)
|
||||
{
|
||||
TempData = ModbusCommunicationDataRead(TempAddr);
|
||||
SendStruct.SendBuffer[6 + 2 * inx] = (TempData >> 8) & 0xff;
|
||||
SendStruct.SendBuffer[7 + 2 * inx] = TempData & 0xff;
|
||||
TempAddr++;
|
||||
}
|
||||
Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6 + 2 * ModbusAnalysisData.RegNumber);
|
||||
SendStruct.SendBuffer[6 + 2 * ModbusAnalysisData.RegNumber] = Crc16 & 0xff;
|
||||
SendStruct.SendBuffer[7 + 2 * ModbusAnalysisData.RegNumber] = (Crc16 >> 8) & 0xff;
|
||||
SendStruct.Len = 8 + 2 * ModbusAnalysisData.RegNumber;
|
||||
}goto Success;
|
||||
|
||||
case 0x06:
|
||||
{
|
||||
TempAddr = ModbusAnalysisData.StartAddress;
|
||||
TempData = (ModbusAnalysisData.wDataAddress[0] << 8) | ModbusAnalysisData.wDataAddress[1];
|
||||
ErrorCode = ModbusCommunicationDataWrite(TempAddr, TempData);
|
||||
if (ErrorCode)
|
||||
{
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SendStruct.Len = 8;
|
||||
SendStruct.SendBuffer[0] = ModbusAnalysisData.ID;
|
||||
SendStruct.SendBuffer[1] = ModbusAnalysisData.Func;
|
||||
SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8;
|
||||
SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff;
|
||||
SendStruct.SendBuffer[4] = ModbusAnalysisData.wDataAddress[0];
|
||||
SendStruct.SendBuffer[5] = ModbusAnalysisData.wDataAddress[1];
|
||||
Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6);
|
||||
SendStruct.SendBuffer[6] = Crc16 & 0xff;
|
||||
SendStruct.SendBuffer[7] = (Crc16 >> 8) & 0xff;
|
||||
}break;
|
||||
|
||||
case 0x10:
|
||||
{
|
||||
TempAddr = ModbusAnalysisData.StartAddress;
|
||||
for (inx = 0; inx < ModbusAnalysisData.RegNumber; inx++)
|
||||
{
|
||||
TempData = ModbusAnalysisData.wDataAddress[2 * inx];
|
||||
TempData = (TempData << 8) | ModbusAnalysisData.wDataAddress[2 * inx + 1];
|
||||
ErrorCode = ModbusCommunicationDataWrite(TempAddr, TempData);
|
||||
TempAddr++;
|
||||
if (ErrorCode)
|
||||
{
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
SendStruct.Len = 8;
|
||||
SendStruct.SendBuffer[0] = ModbusAnalysisData.ID;
|
||||
SendStruct.SendBuffer[1] = ModbusAnalysisData.Func;
|
||||
SendStruct.SendBuffer[2] = ModbusAnalysisData.StartAddress >> 8;
|
||||
SendStruct.SendBuffer[3] = ModbusAnalysisData.StartAddress & 0xff;
|
||||
SendStruct.SendBuffer[4] = ModbusAnalysisData.RegNumber >> 8;
|
||||
SendStruct.SendBuffer[5] = ModbusAnalysisData.RegNumber & 0xff;
|
||||
Crc16 = ModbusCrc16(SendStruct.SendBuffer, 6);
|
||||
SendStruct.SendBuffer[6] = Crc16 & 0xff;
|
||||
SendStruct.SendBuffer[7] = (Crc16 >> 8) & 0xff;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ErrorCode = ModbusErrorCode_IllegalFunction;
|
||||
}
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Success:
|
||||
ModbusCommunicationDataSend(SendStruct.SendBuffer, SendStruct.Len);
|
||||
return;
|
||||
|
||||
Error:
|
||||
SendStruct.Len = 5;
|
||||
SendStruct.SendBuffer[0] = ModbusAnalysisData.ID;
|
||||
SendStruct.SendBuffer[1] = ModbusAnalysisData.Func | 0x80;
|
||||
SendStruct.SendBuffer[2] = ErrorCode;
|
||||
Crc16 = ModbusCrc16(SendStruct.SendBuffer, 3);
|
||||
SendStruct.SendBuffer[3] = Crc16 & 0xff;
|
||||
SendStruct.SendBuffer[4] = (Crc16 >> 8) & 0xff;
|
||||
ModbusCommunicationDataSend(SendStruct.SendBuffer, SendStruct.Len);
|
||||
}
|
||||
|
||||
/*modbus接收到的u16转换为ascii的u16 实际为对调高低字节*/
|
||||
static u16 modbus_u16_to_ascii_u16(u16 modbus_u16)
|
||||
{
|
||||
return (modbus_u16 << 8) | (modbus_u16 >> 8);
|
||||
}
|
||||
|
||||
/*ascii的u16 转换为modbus u16发送 实际为对调高低字节*/
|
||||
static u16 ascii_u16_to_modbus_u16(u16 modbus_u16)
|
||||
{
|
||||
return (modbus_u16 << 8) | (modbus_u16 >> 8);
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* 函数: ModbusCommunicationDataWrite
|
||||
* 功能: Modbus写寄存器
|
||||
* 参数: Addr: 地址
|
||||
Value:数据
|
||||
* 返回: 无
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
static ModbusErrorCode_e ModbusCommunicationDataWrite(u16 Addr, u16 Value)
|
||||
{
|
||||
ModbusErrorCode_e ErrorCode;
|
||||
ErrorCode = ModbusErrorCode_Success;
|
||||
|
||||
switch(Addr)
|
||||
{
|
||||
/*SN*/
|
||||
case 12 ... 21:
|
||||
{
|
||||
Usr_Flash.FlashData.SN[Addr - 12] = Value;
|
||||
Usr_Flash.Write();
|
||||
}break;
|
||||
/*IP地址*/
|
||||
case 22 ... 25:
|
||||
{
|
||||
W5500.IP_Addr[Addr - 22] = Value;
|
||||
Usr_Flash.FlashData.IP_Addr[Addr - 22] = Value;
|
||||
}break;
|
||||
/*端口号*/
|
||||
case 26:
|
||||
{
|
||||
W5500.W5500_Class[0].ConfigData.Port[0] = Value >> 8;
|
||||
W5500.W5500_Class[0].ConfigData.Port[1] = Value & 0x00ff;
|
||||
Usr_Flash.FlashData.Port[0] = Value >> 8;
|
||||
Usr_Flash.FlashData.Port[1] = Value & 0x00ff;
|
||||
}break;
|
||||
/*子网掩码*/
|
||||
case 27 ... 30:
|
||||
{
|
||||
W5500.Sub_Mask[Addr - 27] = Value;
|
||||
Usr_Flash.FlashData.Sub_Mask[Addr - 27] = Value;
|
||||
}break;
|
||||
case 31:
|
||||
{
|
||||
HSMS.Flash_ConfigData.Device_Id = Value;
|
||||
Usr_Flash.FlashData.Devic_Id = Value;
|
||||
|
||||
}break;
|
||||
|
||||
/* 网关设置*/
|
||||
case 32 ... 35:
|
||||
{
|
||||
W5500.Gateway_IP[Addr - 32] = Value;
|
||||
Usr_Flash.FlashData.Gateway_IP[Addr - 32] = Value;
|
||||
Wdg.Feed();
|
||||
W5500.Init();
|
||||
Wdg.Feed();
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/*时间设置*/
|
||||
case 36:
|
||||
{
|
||||
DS1302.Time.Year = Value % 2000;
|
||||
}break;
|
||||
|
||||
case 37:
|
||||
{
|
||||
DS1302.Time.Month = Value;
|
||||
}break;
|
||||
|
||||
case 38:
|
||||
{
|
||||
DS1302.Time.Day = Value;
|
||||
}break;
|
||||
|
||||
case 39:
|
||||
{
|
||||
DS1302.Time.Hour = Value;
|
||||
}break;
|
||||
|
||||
case 40:
|
||||
{
|
||||
DS1302.Time.Minute = Value;
|
||||
}break;
|
||||
|
||||
case 41:
|
||||
{
|
||||
DS1302.Time.Second = Value;
|
||||
DS1302.Set(&DS1302.Time);
|
||||
}break;
|
||||
case 42 ... 45:
|
||||
{
|
||||
W5500_1.IP_Addr[Addr - 42] = Value;
|
||||
Usr_Flash.FlashData.IP_Addr_1[Addr - 42] = Value;
|
||||
}break;
|
||||
case 46:
|
||||
{
|
||||
W5500_1.W5500_Class[0].ConfigData.Port[0] = Value >> 8;
|
||||
W5500_1.W5500_Class[0].ConfigData.Port[1] = Value & 0x00ff;
|
||||
Usr_Flash.FlashData.Port_1[0] = Value >> 8;
|
||||
Usr_Flash.FlashData.Port_1[1] = Value & 0x00ff;
|
||||
}break;
|
||||
case 47 ... 50:
|
||||
{
|
||||
W5500_1.Sub_Mask[Addr - 47] = Value;
|
||||
Usr_Flash.FlashData.Sub_Mask_1[Addr - 47] = Value;
|
||||
}break;
|
||||
case 51 ... 54:
|
||||
{
|
||||
W5500_1.Gateway_IP[Addr - 51] = Value;
|
||||
Usr_Flash.FlashData.Gateway_IP_1[Addr - 51] = Value;
|
||||
Wdg.Feed();
|
||||
W5500_1.Init();
|
||||
Wdg.Feed();
|
||||
Usr_Flash.Write();
|
||||
}break;
|
||||
case 55 ... 58:
|
||||
{
|
||||
W5500_1.W5500_Class[0].ConfigData.DIP[Addr - 55] = Value;
|
||||
Usr_Flash.FlashData.IP_Addr_2[Addr - 55] = Value;
|
||||
}break;
|
||||
case 59:
|
||||
{
|
||||
W5500_1.W5500_Class[0].ConfigData.DPort[0] = Value >> 8;
|
||||
W5500_1.W5500_Class[0].ConfigData.DPort[1] = Value & 0x00ff;
|
||||
Usr_Flash.FlashData.Port_2[0] = Value >> 8;
|
||||
Usr_Flash.FlashData.Port_2[1] = Value & 0x00ff;
|
||||
Wdg.Feed();
|
||||
W5500_1.Init();
|
||||
Wdg.Feed();
|
||||
Usr_Flash.Write();
|
||||
}
|
||||
|
||||
|
||||
/* 设备 SN */
|
||||
case 100 ... 111:
|
||||
{
|
||||
Usr_Flash.FlashData.Device_SN[Addr - 100] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 机台和位置(Device_Model) */
|
||||
case 112 ... 123:
|
||||
{
|
||||
Usr_Flash.FlashData.Device_Model[Addr - 112] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 设备类型(Station_Type) */
|
||||
case 124 ... 135:
|
||||
{
|
||||
Usr_Flash.FlashData.Station_Type[Addr - 124] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 设备型号(Device_ID) */
|
||||
case 136 ... 147:
|
||||
{
|
||||
Usr_Flash.FlashData.Device_ID[Addr - 136] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 软件版本(Version) */
|
||||
case 148 ... 159:
|
||||
{
|
||||
Usr_Flash.FlashData.Version[Addr - 148] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 厂商名称(Manufacturer) */
|
||||
case 160 ... 171:
|
||||
{
|
||||
Usr_Flash.FlashData.Manufacturer[Addr - 160] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 机台名称(Station_Name) */
|
||||
case 172 ... 183:
|
||||
{
|
||||
Usr_Flash.FlashData.Station_Name[Addr - 172] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* 腔体名称(Chamber_Name) */
|
||||
case 184 ... 195:
|
||||
{
|
||||
Usr_Flash.FlashData.Chamber_Name[Addr - 184] = modbus_u16_to_ascii_u16(Value);
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* ========== 后续参数顺延 ========== */
|
||||
/* Alarm_info (20个) */
|
||||
case 196 ... 215:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_info[Addr - 196] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Data_ID1 */
|
||||
case 216:
|
||||
{
|
||||
Usr_Flash.FlashData.Data_ID1 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Collection_event_ID1 */
|
||||
case 217:
|
||||
{
|
||||
Usr_Flash.FlashData.Collection_event_ID1 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Report_ID1 */
|
||||
case 218:
|
||||
{
|
||||
Usr_Flash.FlashData.Report_ID1 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm_ID */
|
||||
case 219:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_ID = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm_Type (7个) */
|
||||
case 220 ... 226:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_Type[Addr - 220] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Begin_Warning (7个) */
|
||||
case 227 ... 233:
|
||||
{
|
||||
Usr_Flash.FlashData.Begin_Warning[Addr - 227] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* IDS (11个) */
|
||||
case 234 ... 244:
|
||||
{
|
||||
Usr_Flash.FlashData.IDS[Addr - 234] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Over_Trigger (9个) */
|
||||
case 245 ... 253:
|
||||
{
|
||||
Usr_Flash.FlashData.Over_Trigger[Addr - 245] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Equipment (5个) */
|
||||
case 254 ... 258:
|
||||
{
|
||||
Usr_Flash.FlashData.Equipment[Addr - 254] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* E9 (19个) */
|
||||
case 259 ... 277:
|
||||
{
|
||||
Usr_Flash.FlashData.E9[Addr - 259] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Device_Type */
|
||||
case 278:
|
||||
{
|
||||
Usr_Flash.FlashData.Device_Type = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Sensor */
|
||||
case 279:
|
||||
{
|
||||
Usr_Flash.FlashData.Sensor = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm_value */
|
||||
case 280:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_value = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm_ubit */
|
||||
case 281:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_ubit = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Start_Time (11个) */
|
||||
case 282 ... 292:
|
||||
{
|
||||
Usr_Flash.FlashData.Start_Time[Addr - 282] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm_Time (6个) */
|
||||
case 293 ... 298:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm_Time[Addr - 293] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Alarm (6个) */
|
||||
case 299 ... 304:
|
||||
{
|
||||
Usr_Flash.FlashData.Alarm[Addr - 299] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Data_ID2 */
|
||||
case 305:
|
||||
{
|
||||
Usr_Flash.FlashData.Data_ID2 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Collection_event_ID2 */
|
||||
case 306:
|
||||
{
|
||||
Usr_Flash.FlashData.Collection_event_ID2 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Report_ID2 */
|
||||
case 307:
|
||||
{
|
||||
Usr_Flash.FlashData.Report_ID2 = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Sub_Device_Type (2个) */
|
||||
case 308 ... 309:
|
||||
{
|
||||
Usr_Flash.FlashData.Sub_Device_Type[Addr - 308] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* Sub_Device_State (2个) */
|
||||
case 310 ... 311:
|
||||
{
|
||||
Usr_Flash.FlashData.Sub_Device_State[Addr - 310] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
/* State_Change_Time (2个) */
|
||||
case 312 ... 313:
|
||||
{
|
||||
Usr_Flash.FlashData.State_Change_Time[Addr - 312] = Value;
|
||||
Usr_Flash.Write();
|
||||
} break;
|
||||
|
||||
case 1000: // 测试开关
|
||||
{
|
||||
Usr_Flash.test = Value;
|
||||
Usr_Flash.Write();
|
||||
test_echo_switch(Usr_Flash.test);
|
||||
} break;
|
||||
}
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* 函数: ModbusCommunicationDataRead
|
||||
* 功能: Modbus读寄存器数据
|
||||
* 参数: Addr: 地址
|
||||
* 返回: 地址对应的数据
|
||||
* 描述: 无
|
||||
******************************************/
|
||||
static u16 ModbusCommunicationDataRead(u16 Addr)
|
||||
{
|
||||
u8 *p_u8Data;
|
||||
u16 Data;
|
||||
u16 *pData;
|
||||
|
||||
switch(Addr)
|
||||
{
|
||||
/*SV*/
|
||||
case 0 ... 11:
|
||||
{
|
||||
p_u8Data = &SwVersion[Addr * 2];
|
||||
Data = p_u8Data[1] | p_u8Data[0] << 8;
|
||||
}break;
|
||||
/*SN*/
|
||||
case 12 ... 21:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.SN[Addr - 12];
|
||||
}break;
|
||||
/*IP地址*/
|
||||
case 22 ... 25:
|
||||
{
|
||||
Data = W5500.IP_Addr[Addr - 22];
|
||||
}break;
|
||||
/*端口号*/
|
||||
case 26:
|
||||
{
|
||||
Data = W5500.W5500_Class[0].ConfigData.Port[0] << 8 | W5500.W5500_Class[0].ConfigData.Port[1];
|
||||
}break;
|
||||
/*子网掩码*/
|
||||
case 27 ... 30:
|
||||
{
|
||||
Data = W5500.Sub_Mask[Addr - 27];
|
||||
}break;
|
||||
/*SECS2协议设备ID*/
|
||||
case 31:
|
||||
{
|
||||
Data = HSMS.Flash_ConfigData.Device_Id;
|
||||
}break;
|
||||
|
||||
/* 网关*/
|
||||
case 32 ... 35:
|
||||
{
|
||||
Data = W5500.Gateway_IP[Addr - 32];
|
||||
} break;
|
||||
|
||||
/*时间*/
|
||||
case 36:
|
||||
{
|
||||
Data = (DS1302.Time.Year) + 2000;
|
||||
}break;
|
||||
case 37:
|
||||
{
|
||||
Data = DS1302.Time.Month;
|
||||
}break;
|
||||
case 38:
|
||||
{
|
||||
Data = DS1302.Time.Day;
|
||||
}break;
|
||||
case 39:
|
||||
{
|
||||
Data = DS1302.Time.Hour;
|
||||
}break;
|
||||
case 40:
|
||||
{
|
||||
Data = DS1302.Time.Minute;
|
||||
}break;
|
||||
case 41:
|
||||
{
|
||||
Data = DS1302.Time.Second;
|
||||
}break;
|
||||
case 42 ... 45:
|
||||
{
|
||||
Data = W5500_1.IP_Addr[Addr - 42];
|
||||
}break;
|
||||
case 46:
|
||||
{
|
||||
Data = W5500_1.W5500_Class[0].ConfigData.Port[0] << 8 | W5500_1.W5500_Class[0].ConfigData.Port[1];
|
||||
}break;
|
||||
case 47 ... 50:
|
||||
{
|
||||
Data = W5500_1.Sub_Mask[Addr - 47];
|
||||
}break;
|
||||
case 51 ... 54:
|
||||
{
|
||||
Data = W5500_1.Gateway_IP[Addr - 51];
|
||||
}break;
|
||||
case 55 ... 58:
|
||||
{
|
||||
Data = W5500_1.W5500_Class[0].ConfigData.DIP[Addr - 55];
|
||||
}break;
|
||||
case 59:
|
||||
{
|
||||
Data = W5500_1.W5500_Class[0].ConfigData.DPort[0] << 8 | W5500_1.W5500_Class[0].ConfigData.DPort[1];
|
||||
}break;
|
||||
|
||||
/* ========== 字符串字段(每个12个寄存器) ========== */
|
||||
/* 设备 SN */
|
||||
case 100 ... 111:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Device_SN[Addr - 100];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 机台和位置(Device_Model) */
|
||||
case 112 ... 123:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Device_Model[Addr - 112];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 设备类型(Station_Type) */
|
||||
case 124 ... 135:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Station_Type[Addr - 124];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 设备型号(Device_ID) */
|
||||
case 136 ... 147:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Device_ID[Addr - 136];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 软件版本(Version) */
|
||||
case 148 ... 159:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Version[Addr - 148];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 厂商名称(Manufacturer) */
|
||||
case 160 ... 171:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Manufacturer[Addr - 160];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 机台名称(Station_Name) */
|
||||
case 172 ... 183:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Station_Name[Addr - 172];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* 腔体名称(Chamber_Name) */
|
||||
case 184 ... 195:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Chamber_Name[Addr - 184];
|
||||
Data = ascii_u16_to_modbus_u16(Data);
|
||||
} break;
|
||||
|
||||
/* ========== 后续参数顺延 ========== */
|
||||
/* Alarm_info (20个) */
|
||||
case 196 ... 215:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_info[Addr - 196];
|
||||
} break;
|
||||
|
||||
/* Data_ID1 */
|
||||
case 216:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Data_ID1;
|
||||
} break;
|
||||
|
||||
/* Collection_event_ID1 */
|
||||
case 217:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Collection_event_ID1;
|
||||
} break;
|
||||
|
||||
/* Report_ID1 */
|
||||
case 218:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Report_ID1;
|
||||
} break;
|
||||
|
||||
/* Alarm_ID */
|
||||
case 219:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_ID;
|
||||
} break;
|
||||
|
||||
/* Alarm_Type (7个) */
|
||||
case 220 ... 226:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_Type[Addr - 220];
|
||||
} break;
|
||||
|
||||
/* Begin_Warning (7个) */
|
||||
case 227 ... 233:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Begin_Warning[Addr - 227];
|
||||
} break;
|
||||
|
||||
/* IDS (11个) */
|
||||
case 234 ... 244:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.IDS[Addr - 234];
|
||||
} break;
|
||||
|
||||
/* Over_Trigger (9个) */
|
||||
case 245 ... 253:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Over_Trigger[Addr - 245];
|
||||
} break;
|
||||
|
||||
/* Equipment (5个) */
|
||||
case 254 ... 258:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Equipment[Addr - 254];
|
||||
} break;
|
||||
|
||||
/* E9 (19个) */
|
||||
case 259 ... 277:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.E9[Addr - 259];
|
||||
} break;
|
||||
|
||||
/* Device_Type */
|
||||
case 278:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Device_Type;
|
||||
} break;
|
||||
|
||||
/* Sensor */
|
||||
case 279:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Sensor;
|
||||
} break;
|
||||
|
||||
/* Alarm_value */
|
||||
case 280:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_value;
|
||||
} break;
|
||||
|
||||
/* Alarm_ubit */
|
||||
case 281:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_ubit;
|
||||
} break;
|
||||
|
||||
/* Start_Time (11个) */
|
||||
case 282 ... 292:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Start_Time[Addr - 282];
|
||||
} break;
|
||||
|
||||
/* Alarm_Time (6个) */
|
||||
case 293 ... 298:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm_Time[Addr - 293];
|
||||
} break;
|
||||
|
||||
/* Alarm (6个) */
|
||||
case 299 ... 304:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Alarm[Addr - 299];
|
||||
} break;
|
||||
|
||||
/* Data_ID2 */
|
||||
case 305:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Data_ID2;
|
||||
} break;
|
||||
|
||||
/* Collection_event_ID2 */
|
||||
case 306:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Collection_event_ID2;
|
||||
} break;
|
||||
|
||||
/* Report_ID2 */
|
||||
case 307:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Report_ID2;
|
||||
} break;
|
||||
|
||||
/* Sub_Device_Type (2个) */
|
||||
case 308 ... 309:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Sub_Device_Type[Addr - 308];
|
||||
} break;
|
||||
|
||||
/* Sub_Device_State (2个) */
|
||||
case 310 ... 311:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.Sub_Device_State[Addr - 310];
|
||||
} break;
|
||||
|
||||
/* State_Change_Time (2个) */
|
||||
case 312 ... 313:
|
||||
{
|
||||
Data = Usr_Flash.FlashData.State_Change_Time[Addr - 312];
|
||||
} break;
|
||||
|
||||
case 1000:
|
||||
{
|
||||
Data = Usr_Flash.test;
|
||||
} break;
|
||||
|
||||
default:
|
||||
Data = 0;
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _PROTO_PARA_MODBUS_H_
|
||||
#define _PROTO_PARA_MODBUS_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "proto_Modbus.h"
|
||||
|
||||
extern proto_Modbus_t Para_Modbus;
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
#ifndef _PROTO_SECS2_H_
|
||||
#define _PROTO_SECS2_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "proto_HSMS.h"
|
||||
|
||||
#define PROTO_SECS2_S1F3 (0x0103) /*数据采集*/
|
||||
#define PROTO_SECS2_S2F49 (0x0231) /*设备状态远程控制*/
|
||||
#define PROTO_SECS2_S1F1 (0x0101) /*心跳*/
|
||||
#define PROTO_SECS2_S6F11 (0x060B) /*设备主动报警*/
|
||||
#define PROTO_SECS2_S6F12 (0x060C) /*确认报警*/
|
||||
#define PROTO_SECS2_S1F13 (0x010D) /*建立连接*/
|
||||
#define PROTO_SECS2_S2F31 (0x021F) /*时间设置*/
|
||||
|
||||
/*报警和状态哦改变是否需要响应*/
|
||||
#define PROTO_ALARM_CHANGE_RX_WAIT (1)
|
||||
#define PROTO_STATE_CHANGE_RX_WAIT (1)
|
||||
|
||||
/*数据类型*/
|
||||
#define PROTO_SECS2_DATA_TYPE_List 000/*八进制*/
|
||||
#define PROTO_SECS2_DATA_TYPE_Binary 010
|
||||
#define PROTO_SECS2_DATA_TYPE_Bool 011
|
||||
#define PROTO_SECS2_DATA_TYPE_ASCII 020
|
||||
#define PROTO_SECS2_DATA_TYPE_JIS_8 021
|
||||
#define PROTO_SECS2_DATA_TYPE_2Byte_char 022
|
||||
#define PROTO_SECS2_DATA_TYPE_8Byte_int 030
|
||||
#define PROTO_SECS2_DATA_TYPE_1Byte_int 031
|
||||
#define PROTO_SECS2_DATA_TYPE_2Byte_int 032
|
||||
#define PROTO_SECS2_DATA_TYPE_4Byte_int 034
|
||||
#define PROTO_SECS2_DATA_TYPE_8Byte_float 040
|
||||
#define PROTO_SECS2_DATA_TYPE_4Byte_float 044
|
||||
#define PROTO_SECS2_DATA_TYPE_8Byte_uint 050
|
||||
#define PROTO_SECS2_DATA_TYPE_1Byte_uint 051
|
||||
#define PROTO_SECS2_DATA_TYPE_2Byte_uint 052
|
||||
#define PROTO_SECS2_DATA_TYPE_4Byte_uint 054
|
||||
|
||||
|
||||
/*解析出来的消息数据*/
|
||||
typedef struct
|
||||
{
|
||||
void *pData; /*解析的数据首地址*/
|
||||
u8 w_bit; /*是否需要响应*/
|
||||
u8 DataType; /*数据类型*/
|
||||
u8 ByteLen; /*字节长度*/
|
||||
u8 DataNum; /*数据个数*/
|
||||
}proto_SECS2_MessageData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 state;
|
||||
u8 flag;
|
||||
u32 sys_count;
|
||||
u32 start_time;
|
||||
}proto_SECS2_Set_Ask_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sys_count;
|
||||
proto_SECS2_Set_Ask_t Set_Ask;
|
||||
void (*Rx_DataAnalysis)(proto_HSMS_Header_Data_t *,u8 *,u16);
|
||||
void (*Tx_Alarm_Task)(void);
|
||||
void (*Tx_Dev_State_Task)(void);
|
||||
void (*Tx_Set_Ask_Task)(void);
|
||||
}proto_SECS2_t;
|
||||
|
||||
extern proto_SECS2_t SECS2;
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "proto_Transform.h"
|
||||
#include "proto_CS200.h"
|
||||
#include "string.h"
|
||||
|
||||
|
||||
|
||||
void proto_Transform_Task(void)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _PROTO_TRANSFORM_H_
|
||||
#define _PROTO_TRANSFORM_H_
|
||||
|
||||
#include "main.h"
|
||||
u8 proto_AA55_to_Modbus_Unit(u8 AA55_Uint);
|
||||
u8 proto_Modbus_to_AA55_Unit(u8 Modbus_Uint);
|
||||
void proto_Transform_Task(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,420 @@
|
||||
#include "proto_modbus_tcp_master.h"
|
||||
#include "bsp_W5500_1.h"
|
||||
#include "string.h"
|
||||
|
||||
/* 响应超时时间(单位:毫秒) */
|
||||
#define RESP_TIMEOUT_MS 500
|
||||
|
||||
/* 静态函数声明 */
|
||||
static void modbus_tcp_send_read(u16 start, u16 num);
|
||||
static void modbus_tcp_parse_response(bsp_W5500_Class_t *pClass, u8 *data, u16 len);
|
||||
static void modbus_tcp_init_local(void);
|
||||
static void modbus_tcp_task(void);
|
||||
static void modbus_tcp_write_control(u16 bit_mask);
|
||||
|
||||
char *proto_modbus_master_alarm[24] = {
|
||||
"Alarm", /* 40002.00 一级报警 */
|
||||
"HH Inlet1 Pressure", /* 40002.01 进口压力1高高报警 */
|
||||
"HH Inlet2 Pressure", /* 40002.02 进口压力2高高报警 */
|
||||
"HH Inlet3 Pressure", /* 40002.03 进口压力3高高报警 */
|
||||
"HH Inlet4 Pressure", /* 40002.04 备口压力1高高报警 */
|
||||
"HH Inlet5 Pressure", /* 40002.05 备口压力2高高报警 */
|
||||
"HH Inlet6 Pressure", /* 40002.06 备口压力3高高报警 */
|
||||
"HH Reaction Chamber Temp.", /* 40002.07 反应腔温度高高报警 */
|
||||
"Drain Pump Alarm", /* 40003.00 排水泵异常报警 */
|
||||
"LL PCW Flow", /* 40003.01 PCW流量低低报警 */
|
||||
"LL Liquid Level", /* 40003.02 低低液位报警 */
|
||||
"HH Liquid Level", /* 40003.03 高高液位报警 */
|
||||
"EMO", /* 40003.04 EMO */
|
||||
"HH Exhuast Temp.", /* 40003.05 排气温度高高报警 */
|
||||
"L General Exhaust Pressure", /* 40003.06 一般排压力低报警 */
|
||||
"O3 HH", /* 40003.07 O3浓度高高报警 */
|
||||
"H Reaction Chamber Temp. Delay", /* 40003.08 反应腔温度高延时报警 */
|
||||
"Reaction Chamber Temp.Out", /* 40003.09 反应腔顶盖超温报警 */
|
||||
"HH Water Tank Temp.", /* 40003.10 水箱温度高高报警 */
|
||||
"Water Leakage", /* 40003.11 水箱漏液报警 */
|
||||
"Containment Leakage", /* 40003.12 围堰漏液报警 */
|
||||
"Smoke", /* 40003.13 烟雾报警 */
|
||||
"Heat Source Failure", /* 40003.14 热源失效报警 */
|
||||
"Circulation Pump Alarm" /* 40003.15 循环水泵异常报警 */
|
||||
};
|
||||
|
||||
char *proto_modbus_master_warning[64] = {
|
||||
"Inlet1 Pressure Broken", /* 40004.00 进口压力1断线警告 */
|
||||
"Inlet2 Pressure Broken", /* 40004.01 进口压力2断线警告 */
|
||||
"Inlet3 Pressure Broken", /* 40004.02 进口压力3断线警告 */
|
||||
"Inlet4 Pressure Broken", /* 40004.03 备口压力1断线警告 */
|
||||
"Inlet5 Pressure Broken", /* 40004.04 备口压力2断线警告 */
|
||||
"Inlet6 Pressure Broken", /* 40004.05 备口压力3断线警告 */
|
||||
"Outlet Pressure Broken", /* 40004.06 出口压力断线警告 */
|
||||
"Inlet Valve_1 Open Limit Warning", /* 40004.07 特气进口阀1开限位警告 */
|
||||
"Warning", /* 40004.08 二级警告 */
|
||||
"H Inlet1 Pressure", /* 40004.09 进口压力1高警告 */
|
||||
"H Inlet2 Pressure", /* 40004.10 进口压力2高警告 */
|
||||
"H Inlet3 Pressure", /* 40004.11 进口压力3高警告 */
|
||||
"H Inlet4 Pressure", /* 40004.12 备口压力1高警告 */
|
||||
"H Inlet5 Pressure", /* 40004.13 备口压力2高警告 */
|
||||
"H Inlet6 Pressure", /* 40004.14 备口压力3高警告 */
|
||||
"H Outlet Pressure", /* 40004.15 出口压力高警告 */
|
||||
"Inlet Valve_5 Close Limit Warning", /* 40005.00 特气进口阀4关限位警告 */
|
||||
"Inlet Valve_6 Open Limit Warning", /* 40005.01 特气进口阀5开限位警告 */
|
||||
"Inlet Valve_6 Close Limit Warning", /* 40005.02 特气进口阀6关限位警告 */
|
||||
"H water tank temp.", /* 40005.03 水箱温度高警告 */
|
||||
"H exhuast temp.", /* 40005.04 排气温度高警告 */
|
||||
"H reaction chamber temp.", /* 40005.05 反应腔温度高警告 */
|
||||
"L reaction chamber temp.", /* 40005.06 反应腔温度低警告 */
|
||||
"Water tank temp. Broken", /* 40005.07 水箱温度断线警告 */
|
||||
"Inlet Valve_1 Close Limit Warning", /* 40005.08 特气进口阀2开限位警告 */
|
||||
"Inlet Valve_2 Open Limit Warning", /* 40005.09 特气进口阀3开限位警告 */
|
||||
"Inlet Valve_2 Close Limit Warning", /* 40005.10 特气进口阀4开限位警告 */
|
||||
"Inlet Valve_3 Open Limit Warning", /* 40005.11 特气进口阀5开限位警告 */
|
||||
"Inlet Valve_3 Close Limit Warning", /* 40005.12 特气进口阀6开限位警告 */
|
||||
"Inlet Valve_4 Open Limit Warning", /* 40005.13 特气进口阀1关限位警告 */
|
||||
"Inlet Valve_4 Close Limit Warning", /* 40005.14 特气进口阀2关限位警告 */
|
||||
"Inlet Valve_5 Open Limit Warning", /* 40005.15 特气进口阀3关限位警告 */
|
||||
"PCW valve closed with flow", /* 40006.00 PCW阀关有流量警告 */
|
||||
"LSW valve closed with flow", /* 40006.01 CW阀关有流量警告 */
|
||||
"L torch Current", /* 40006.02 等离子电流低警告 */
|
||||
"H torch Current", /* 40006.03 等离子电流高警告 */
|
||||
"L torch Voltage", /* 40006.04 等离子电压低警告 */
|
||||
"H torch Voltage", /* 40006.05 等离子电压高警告 */
|
||||
"Torch current sensor Broken", /* 40006.06 等离子电流断线警告 */
|
||||
"Torch voltage sensor Broken", /* 40006.07 等离子电压断线警告 */
|
||||
"Exhuast temp. Broken", /* 40006.08 排气温度断线警告 */
|
||||
"Reaction chamber temp. Broken", /* 40006.09 反应腔温度断线警告 */
|
||||
"L CDA pressure", /* 40006.10 CDA压力低警告 */
|
||||
"L N2 pressure", /* 40006.11 N2压力低警告 */
|
||||
"L LSW flow", /* 40006.12 CW流量低警告 */
|
||||
"L PCW flow", /* 40006.13 PCW流量低警告 */
|
||||
"L cathode nitrogen flow", /* 40006.14 等离子N2流量低警告 */
|
||||
"H cathode nitrogen flow", /* 40006.15 等离子N2流量高警告 */
|
||||
"Inlet_5 H belt jacket temp.", /* 40007.00 备口2加热带温度高警告 */
|
||||
"Inlet_6 H belt jacket temp.", /* 40007.01 备口3加热带温度高警告 */
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"H Cabinet exhuast Temp.", /* 40007.08 一般排温度高警告 */
|
||||
"Cabinet exhuast Temp. Broken", /* 40007.09 一般排温度断线警告 */
|
||||
"Cabinet exhuast pressure Broken", /* 40007.10 一般排压力断线警告 */
|
||||
"Cabinet door open", /* 40007.11 机箱门打开警告 */
|
||||
"Inlet_1 H belt jacket temp.", /* 40007.12 入口1加热带温度高警告 */
|
||||
"Inlet_2 H belt jacket temp.", /* 40007.13 入口2加热带温度高警告 */
|
||||
"Inlet_3 H belt jacket temp.", /* 40007.14 入口3加热带温度高警告 */
|
||||
"Inlet_4 H belt jacket temp." /* 40007.15 备口1加热带温度高警告 */
|
||||
};
|
||||
|
||||
/* 全局实例对象 */
|
||||
proto_modbus_t modbus_tcp = {
|
||||
.req_state = 0,
|
||||
.last_req_time = 0,
|
||||
.retry_cnt = 0,
|
||||
.transaction_id = 0,
|
||||
.no_response_count = 0,
|
||||
.data = {0},
|
||||
.init = modbus_tcp_init_local,
|
||||
.task = modbus_tcp_task,
|
||||
.write = modbus_tcp_write_control,
|
||||
};
|
||||
|
||||
/* 内部指针简化访问 */
|
||||
static proto_modbus_t *pModbusTcp = &modbus_tcp;
|
||||
|
||||
/*******************************************************************************
|
||||
* 函数名 : modbus_tcp_init_local
|
||||
* 描述 : 初始化 Modbus TCP 主机:绑定接收回调,重置状态变量
|
||||
* 输入 : 无
|
||||
* 输出 : 无
|
||||
* 返回值 : 无
|
||||
* 说明 : 该函数通过 modbus_tcp.init 指针调用
|
||||
*******************************************************************************/
|
||||
static void modbus_tcp_init_local(void) {
|
||||
/* 将 W5500 第0个Socket的接收回调绑定到本模块的解析函数 */
|
||||
W5500_1.W5500_Class[0].Rx_DataAnalysis = modbus_tcp_parse_response;
|
||||
|
||||
pModbusTcp->transaction_id = 0;
|
||||
pModbusTcp->req_state = 0;
|
||||
pModbusTcp->last_req_time = 0;
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->write_pending = 0;
|
||||
memset(&pModbusTcp->data, 0, sizeof(pModbusTcp->data));/*清除设备数据*/
|
||||
memset(&pModbusTcp->alarm_ctx, 0, sizeof(pModbusTcp->alarm_ctx));/*清除时间*/
|
||||
memset(&pModbusTcp->status_ctx,0,sizeof(pModbusTcp->status_ctx));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 函数名 : modbus_tcp_send_read
|
||||
* 描述 : 发送 Modbus TCP 读保持寄存器请求(功能码0x03)
|
||||
* 输入 : start : 起始寄存器地址(16位)
|
||||
* num : 要读取的寄存器数量
|
||||
* 输出 : 无
|
||||
* 返回值 : 无
|
||||
* 说明 : 自动递增事务ID,通过 W5500 Socket 发送
|
||||
*******************************************************************************/
|
||||
static void modbus_tcp_send_read(u16 start, u16 num) {
|
||||
u8 req[12];
|
||||
|
||||
pModbusTcp->transaction_id++;
|
||||
req[0] = (pModbusTcp->transaction_id >> 8) & 0xFF; /* 事务ID高字节 */
|
||||
req[1] = pModbusTcp->transaction_id & 0xFF; /* 事务ID低字节 */
|
||||
req[2] = 0x00; req[3] = 0x00; /* 协议标识符,固定0x0000 */
|
||||
req[4] = 0x00; req[5] = 0x06; /* 后续字节数(固定6) */
|
||||
req[6] = MODBUS_TCP_DEFAULT_UNIT_ID; /* 单元标识符 */
|
||||
req[7] = 0x03; /* 功能码:读保持寄存器 */
|
||||
req[8] = (start >> 8) & 0xFF; /* 起始地址高字节 */
|
||||
req[9] = start & 0xFF; /* 起始地址低字节 */
|
||||
req[10] = (num >> 8) & 0xFF; /* 寄存器数量高字节 */
|
||||
req[11] = num & 0xFF; /* 寄存器数量低字节 */
|
||||
|
||||
/* 通过 W5500 的第0个Socket发送 */
|
||||
W5500_1.Socket_Send(&W5500_1.W5500_Class[0], req, 12);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 函数名 : modbus_tcp_send_write
|
||||
* 描述 : 发送 Modbus TCP 写寄存器请求
|
||||
* 输入 : start : 寄存器地址(16位)
|
||||
* n
|
||||
* 输出 : 无
|
||||
* 返回值 : 无
|
||||
* 说明 : 自动递增事务ID,通过 W5500 Socket 发送
|
||||
*******************************************************************************/
|
||||
static void modbus_tcp_send_write(u16 reg_addr, u16 value) {
|
||||
u8 req[12];
|
||||
|
||||
pModbusTcp->transaction_id++;
|
||||
pModbusTcp->write_tid = pModbusTcp->transaction_id;
|
||||
pModbusTcp->write_pending = 2;
|
||||
pModbusTcp->write_result = 0;
|
||||
|
||||
req[0] = (pModbusTcp->transaction_id >> 8) & 0xFF;
|
||||
req[1] = pModbusTcp->transaction_id & 0xFF;
|
||||
req[2] = 0x00; req[3] = 0x00; /* 协议标识符 */
|
||||
req[4] = 0x00; req[5] = 0x06; /* 后续字节数(固定6) */
|
||||
req[6] = MODBUS_TCP_DEFAULT_UNIT_ID;
|
||||
req[7] = 0x06; /* 功能码:写单个寄存器 */
|
||||
req[8] = (reg_addr >> 8) & 0xFF;
|
||||
req[9] = reg_addr & 0xFF;
|
||||
req[10] = (value >> 8) & 0xFF;
|
||||
req[11] = value & 0xFF;
|
||||
|
||||
W5500_1.Socket_Send(&W5500_1.W5500_Class[0], req, 12);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 函数名 : modbus_tcp_parse_response
|
||||
* 描述 : 解析 W5500 收到的 Modbus TCP 响应,根据当前请求状态存储数据
|
||||
* 输入 : pClass - W5500 端口类对象指针(未使用,匹配回调原型)
|
||||
* data - 接收到的数据缓冲区指针
|
||||
* len - 数据长度
|
||||
* 输出 : 无
|
||||
* 返回值 : 无
|
||||
* 说明 : 该函数由 W5500 的 Rx_DataAnalysis 回调调用
|
||||
*******************************************************************************/
|
||||
static void modbus_tcp_parse_response(bsp_W5500_Class_t *pClass, u8 *data, u16 len) {
|
||||
(void)pClass; /* 避免未使用参数警告 */
|
||||
|
||||
/* 最小长度检查:MBAP头(7) + 功能码(1) + 字节数(1) = 9 */
|
||||
if (len < 9) return;
|
||||
|
||||
u16 tid = (data[0] << 8) | data[1];
|
||||
if (tid != pModbusTcp->transaction_id) return; /* 事务ID不匹配则丢弃 */
|
||||
|
||||
if (data[2] != 0 || data[3] != 0) return; /* 协议标识符必须为0 */
|
||||
if (data[6] != MODBUS_TCP_DEFAULT_UNIT_ID) return;
|
||||
|
||||
if (data[7] == 0x83) { /* 异常响应(功能码+0x80) */
|
||||
pModbusTcp->req_state = 0; /* 放弃当前轮次 */
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---- 处理写单个寄存器响应 (0x06) ---- */
|
||||
if (data[7] == 0x06) {
|
||||
if (tid == pModbusTcp->write_tid) {
|
||||
pModbusTcp->write_pending = 1;
|
||||
pModbusTcp->write_result = 1; /* 成功 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* 异常响应(写操作异常) */
|
||||
if (data[7] == 0x86) { /* 0x06 + 0x80 */
|
||||
if (tid == pModbusTcp->write_tid) {
|
||||
pModbusTcp->write_pending = 3;
|
||||
pModbusTcp->write_result = 0; /* 失败 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[7] != 0x03) return; /* 非预期功能码 */
|
||||
|
||||
u8 byte_count = data[8];
|
||||
if (len < (9 + byte_count)) return;
|
||||
|
||||
/* 根据当前请求状态解析数据 */
|
||||
switch (pModbusTcp->req_state) {
|
||||
case 1: { /* 设备状态寄存器(40000~40007) */
|
||||
if (byte_count == 16) { /* 8个寄存器 × 2字节 */
|
||||
u8 *p = &data[9];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
pModbusTcp->data.reg_status[i] = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
}
|
||||
pModbusTcp->req_state = 2; /* 进入下一分组 */
|
||||
pModbusTcp->last_req_time = 0; /* 立即发送下一请求 */
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->no_response_count = 0;
|
||||
pModbusTcp->alarm_ctx.offline = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 2: { /* 浮点仪表寄存器(40050~40100) */
|
||||
if (byte_count == 104) { /* 26个浮点 × 4字节 = 104字节 */
|
||||
u8 *p = &data[9];
|
||||
for (int i = 0; i < 26; i++) {
|
||||
u32 tmp = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
pModbusTcp->data.float_values[i] = *((float*)&tmp);
|
||||
p += 4;
|
||||
}
|
||||
pModbusTcp->req_state = 3;
|
||||
pModbusTcp->last_req_time = 0;
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->no_response_count = 0;
|
||||
pModbusTcp->alarm_ctx.offline = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 3: { /* 整数仪表寄存器(40250~40252) */
|
||||
if (byte_count == 6) { /* 3个寄存器 × 2字节 */
|
||||
u8 *p = &data[9];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
pModbusTcp->data.int_values[i] = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
}
|
||||
pModbusTcp->req_state = 4;
|
||||
pModbusTcp->last_req_time = HAL_GetTick(); /* 记录完成时间*/
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->no_response_count = 0;
|
||||
pModbusTcp->alarm_ctx.offline = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 4: /*20253~20260代表sn*/
|
||||
{
|
||||
if(byte_count == 20) /*10个寄存器,20个字节*/
|
||||
{
|
||||
u8 *p = &data[9];
|
||||
u8 len = p[0];
|
||||
if (len > 20) len = 20;
|
||||
if (len > 0) {
|
||||
memcpy(pModbusTcp->data.sn_str, &p[1], len);
|
||||
pModbusTcp->data.sn_str[len] = '\0';
|
||||
} else {
|
||||
pModbusTcp->data.sn_str[0] = '\0';
|
||||
}
|
||||
// 存储原始寄存器值
|
||||
for (int i = 0; i < 10; i++) {
|
||||
pModbusTcp->data.sn[i] = (p[1 + i*2] << 8) | p[2 + i*2];
|
||||
}
|
||||
pModbusTcp->req_state = 0; /* 全部完成,回到空闲 */
|
||||
pModbusTcp->last_req_time = HAL_GetTick();
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->no_response_count = 0;
|
||||
pModbusTcp->alarm_ctx.offline = 0;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* 函数名 : modbus_tcp_task
|
||||
* 描述 : Modbus TCP 主机周期任务:由外部调度器每500ms调用一次。
|
||||
* 任务内部检查连接状态,空闲时立即发起第一个请求;
|
||||
* 等待响应时检查超时并重试或跳转至下一分组。
|
||||
* 输入 : 无
|
||||
* 输出 : 无
|
||||
* 返回值 : 无
|
||||
* 说明 : 该函数由 modbus_tcp.task 指针调用,外部调度周期决定轮询间隔
|
||||
*******************************************************************************/
|
||||
static void modbus_tcp_task(void) {
|
||||
/* 检查 W5500 第0个Socket的连接状态 */
|
||||
if (!(W5500_1.W5500_Class[0].Run_State & BSP_W5500_PORT_RUN_STATE_CONN)) {
|
||||
pModbusTcp->req_state = 0; /* 未连接则复位状态 */
|
||||
pModbusTcp->alarm_ctx.offline = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
u32 now = HAL_GetTick();
|
||||
|
||||
/* 空闲状态:直接发起第一个请求(设备状态) */
|
||||
if (pModbusTcp->req_state == 0) {
|
||||
modbus_tcp_send_read(MODBUS_REG_DEVICE_STATUS_START,
|
||||
MODBUS_REG_DEVICE_STATUS_NUM);
|
||||
pModbusTcp->req_state = 1;
|
||||
pModbusTcp->last_req_time = now;
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 等待响应状态:若超时则重试或跳过当前分组 */
|
||||
if (now - pModbusTcp->last_req_time >= RESP_TIMEOUT_MS) {
|
||||
pModbusTcp->retry_cnt++;
|
||||
if (pModbusTcp->retry_cnt < 4) {
|
||||
/* 重发当前分组的请求 */
|
||||
u16 start, num;
|
||||
switch (pModbusTcp->req_state) {
|
||||
case 1: start = MODBUS_REG_DEVICE_STATUS_START; num = MODBUS_REG_DEVICE_STATUS_NUM; break;
|
||||
case 2: start = MODBUS_REG_INSTRUMENT_FLOAT_START; num = MODBUS_REG_INSTRUMENT_FLOAT_NUM; break;
|
||||
case 3: start = MODBUS_REG_INSTRUMENT_INT_START; num = MODBUS_REG_INSTRUMENT_INT_NUM; break;
|
||||
case 4: start = MODBUS_REG_INSTRUMENT_SN_START; num = MODBUS_REG_INSTRUMENT_SN_NUM; break;
|
||||
default: return;
|
||||
}
|
||||
modbus_tcp_send_read(start, num);
|
||||
pModbusTcp->last_req_time = now;
|
||||
} else {
|
||||
/* 重试次数耗尽,强制进入下一分组或回到空闲 */
|
||||
pModbusTcp->retry_cnt = 0;
|
||||
pModbusTcp->no_response_count++;
|
||||
if (pModbusTcp->no_response_count >= 3) {
|
||||
pModbusTcp->alarm_ctx.offline = 1;
|
||||
}else
|
||||
{
|
||||
pModbusTcp->alarm_ctx.offline = 0;
|
||||
// pModbusTcp->no_response_count = 0;
|
||||
}
|
||||
if (pModbusTcp->req_state < 4) {
|
||||
pModbusTcp->req_state++; /* 跳至下一分组 */
|
||||
} else {
|
||||
pModbusTcp->req_state = 0; /* 所有分组完成,回到空闲 */
|
||||
}
|
||||
/* 将 last_req_time 置0,使得下一次调用时会立即进入超时分支,发送新分组 */
|
||||
pModbusTcp->last_req_time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*写入单个寄存器*/
|
||||
static void modbus_tcp_write_control(u16 bit_mask) {
|
||||
if (!(W5500_1.W5500_Class[0].Run_State & BSP_W5500_PORT_RUN_STATE_CONN)) {
|
||||
return; /* 未连接不操作 */
|
||||
}
|
||||
|
||||
// 读取当前寄存器值
|
||||
u16 current_val = pModbusTcp->data.reg_status[7];
|
||||
|
||||
// 清除所有控制位 (bit3~bit6)
|
||||
u16 clear_mask = CONTROL_BIT_START | CONTROL_BIT_STOP |
|
||||
CONTROL_BIT_IDLE_OPEN | CONTROL_BIT_IDLE_CLOSE;
|
||||
u16 new_val = current_val & ~clear_mask;
|
||||
|
||||
// 设置目标位
|
||||
new_val |= bit_mask;
|
||||
/* 发送写请求 */
|
||||
modbus_tcp_send_write(MODBUS_REG_CONTROL_ADDR, new_val);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#ifndef _PROTO_MODBUS_TCP_H_
|
||||
#define _PROTO_MODBUS_TCP_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "bsp_W5500_1.h"
|
||||
|
||||
/* 默认单元标识符(Unit ID),用于单设备连接 */
|
||||
#define MODBUS_TCP_DEFAULT_UNIT_ID (01)
|
||||
|
||||
/* 三个数据块的起始地址(偏移直接使用) */
|
||||
#define MODBUS_REG_DEVICE_STATUS_START 0x0000 /* 40000 */
|
||||
#define MODBUS_REG_INSTRUMENT_FLOAT_START 0x0032 /* 40050 */
|
||||
#define MODBUS_REG_INSTRUMENT_INT_START 0x00FA /* 40250 */
|
||||
#define MODBUS_REG_INSTRUMENT_SN_START 0x00FD /* 40253 */
|
||||
|
||||
/* 对应寄存器数量 */
|
||||
#define MODBUS_REG_DEVICE_STATUS_NUM 8 /* 40000~40007 */
|
||||
#define MODBUS_REG_INSTRUMENT_FLOAT_NUM 52 /* 40050~40100 */
|
||||
#define MODBUS_REG_INSTRUMENT_INT_NUM 3 /* 40250~40252 */
|
||||
#define MODBUS_REG_INSTRUMENT_SN_NUM 10 /* 40253~40262 */
|
||||
|
||||
/*设备控制*/
|
||||
#define DEVICE_START ("start") /*设备启动*/
|
||||
#define DEVICE_STOP ("stop") /*设备停止*/
|
||||
#define DEVICE_IDLE_OPEN ("idle_open") /*设备空闲停止*/
|
||||
#define DEVICE_IDLE_CLOSE ("idle_close") /*设备空闲停止*/
|
||||
|
||||
#define MODBUS_REG_CONTROL_ADDR 0x0007 /* 40007 */
|
||||
#define CONTROL_BIT_START (1 << 3) /* bit3 */
|
||||
#define CONTROL_BIT_STOP (1 << 4) /* bit4 */
|
||||
#define CONTROL_BIT_IDLE_OPEN (1 << 5) /* bit5 */
|
||||
#define CONTROL_BIT_IDLE_CLOSE (1 << 6) /* bit6 */
|
||||
|
||||
#define PROTO_MODBUS_DEVICE_STATUS_RUN (0x08) /*设备启动且没有PM和一级报警*/
|
||||
#define PROTO_MODBUS_DEVICE_STATUS_PM (0x01) /*设备处于PM*/
|
||||
#define PROTO_MODBUS_DEVICE_STATUS_ALARM /*设备处于一级报警*/
|
||||
#define PROTO_MODBUS_DEVICE_STATUS_IDLE (0x10) /*设备停止*/
|
||||
#define PROTO_MODBUS_DEVICE_STATUS_OFFLINE (5) /*设备离线*/
|
||||
|
||||
#define PROTO_MODBUS_MASTER_MODE_RUN 0 /*设备运行*/
|
||||
#define PROTO_MODBUS_MASTER_MODE_ALARM 1 /*设备报警*/
|
||||
#define PROTO_MODBUS_MASTER_MODE_PM 2
|
||||
#define PROTO_MODBUS_MASTER_MODE_IDLE 3 /*设备空闲/停止*/
|
||||
#define PROTO_MODBUS_MASTER_MODE_OFFLINE 4 /*设备离线*/
|
||||
#define PROTO_MODBUS_MASTER_MODE_ONLINE 5 /*设备在线*/
|
||||
|
||||
typedef struct {
|
||||
//报警开始标志
|
||||
u8 alarm;
|
||||
// 报警开始时间记录
|
||||
u32 alarm_start_sec[24];
|
||||
char alarm_start_str[24][17];
|
||||
// 警告开始时间记录
|
||||
u32 warning_start_sec[64];
|
||||
char warning_start_str[64][17];
|
||||
|
||||
// 上次状态缓存(用于变化检测)
|
||||
u64 alarm_status_last;
|
||||
u64 warning_status_last;
|
||||
|
||||
// 定时器 tick
|
||||
u32 alarm_task_tick;
|
||||
|
||||
//PM状态
|
||||
u8 pm_status;
|
||||
|
||||
// 离线相关
|
||||
u8 offline;
|
||||
u32 offline_start_sec;
|
||||
char offline_start_str[17];
|
||||
u8 last_offline_state;
|
||||
} modbus_alarm_context_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 device_status_last;
|
||||
u8 device_status;
|
||||
u32 status_task_tick;
|
||||
}modbus_device_context_t;
|
||||
|
||||
/* 数据结构:存储解析后的原始值 */
|
||||
typedef struct {
|
||||
u16 reg_status[8]; /* 40000~40007 原始值 */
|
||||
float float_values[26]; /* 由40050~40100组成26个浮点 */
|
||||
u16 int_values[3]; /* 40250~40252 */
|
||||
u16 sn[10]; /* 40253~40262第一个字节为长度舍弃*/
|
||||
char sn_str[21]; /* 解析后的 SN 字符串(含 '\0')*/
|
||||
} modbus_tcp_data_t;
|
||||
|
||||
/* 设备对象结构 */
|
||||
typedef struct {
|
||||
u8 req_state; /* 0=空闲,1=等待状态响应,2=等待浮点响应,3=等待整数响应 */
|
||||
u32 last_req_time;
|
||||
u8 retry_cnt; /*重试次数*/
|
||||
u16 transaction_id;
|
||||
u8 write_pending; /* 1=等待写响应 */
|
||||
u16 write_tid; /* 写操作的事务ID */
|
||||
u8 write_result; /* 0=失败/超时,1=成功 */
|
||||
u8 no_response_count; /*连续无响应分组计数*/
|
||||
|
||||
modbus_tcp_data_t data;
|
||||
modbus_alarm_context_t alarm_ctx;
|
||||
modbus_device_context_t status_ctx;
|
||||
void (*init)(void);
|
||||
void (*task)(void);
|
||||
void (*write)(u16);
|
||||
} proto_modbus_t;
|
||||
|
||||
|
||||
/* 位提取函数:从16位寄存器中提取第bit_pos位(0~15) */
|
||||
static inline u8 modbus_tcp_get_bit(u16 reg_value, u8 bit_pos) {
|
||||
return (reg_value >> bit_pos) & 0x01;
|
||||
}
|
||||
|
||||
extern proto_modbus_t modbus_tcp;
|
||||
extern char *proto_modbus_master_alarm[24];
|
||||
extern char *proto_modbus_master_warning[64];
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user