前言
最近依旧是开发规约解析工具的103篇,已经完成了通用分类服务部分的解析,现在着手开始搞扰动数据传输,也就是故障录波的传输。
在103故障录波(扰动数据)的报文中,数据是一个数据集一个数据集地存放,所以为了方便我们采用pData[offset]
这种方式来访问到每一个数据,用结构体TJC103_Wave
来定义数据集之前三行的其余字段部分,初步打算用结构体来访问其余字段部分,而用BYTE(unsigned char)
型的指针来访问数据集,因为涉及到偏移量,所以采用pData[offset]
这种方式来访问较为简单。
以下为部分代码实现:
//.h文件
//=========================新增103规约发送接收帧结构体=======================
typedef struct
{
BYTE bStart; //启动字符
BYTE bLength; //长度
BYTE bControl1;//控制域1
BYTE bControl2;//控制域2
BYTE bControl3;//控制域3
BYTE bControl4;//控制域4
BYTE bType; //类型标识
BYTE bQualifier;//结构限定词
BYTE bReason; //传送原因
BYTE bAddress; //公共地址
BYTE bFUN; //功能类型
BYTE bINF; //信息序号
BYTE bData;
BYTE bGenData; //从NGD开始
} TJC103RxdFm, TJC103TxdFm;
TJC103RxdFm m_pRxdFm_JC103; //存储报文的结构体
//故障录波数据准备好报文的应用服务数据格式
typedef struct
{
BYTE bNotUsed; //未用
BYTE bDataType; //数据类型
WORD wFaultNumber; //故障序号
WORD wPowerGrid; //电网故障序号(未用)
BYTE NOC; //模拟量路数
WORD NOE; //每路模拟量的点数
WORD INT; //非实际数
DWORD dwNotUsed; //没有使用,全部为零
WORD StartRecordWave; //启动与录波开始的间隔点数
WORD ExitRecordWave; //出口与录波开始的间隔周波数
WORD ReturnRecordWave; //返回与录波开始的间隔周波数
BYTE bData; //数据
} TJC103_Wave;
报文解析处理:
//.cpp文件
bool CXfloatDlg::Rxd68_JC103_Burst_Trans_Ready_26() //扰动数据传输准备就绪
{
TJC103_Wave* JC103_Wave = (TJC103_Wave*) & (m_pRxdFm_JC103->bData);
SetTop_JC103("扰动数据传输准备就绪");
qy.Format("%02X%s传送原因bReason:%s\r\n", m_pRxdFm_JC103->bReason, GetSpace(1), SETReason_JC103(m_pRxdFm_JC103->bReason));
m_result += qy;
qy.Format("%02X%s数据单元公共地址:%d\r\n", m_pRxdFm_JC103->bAddress, GetSpace(1), m_pRxdFm_JC103->bAddress);
m_result += qy;
qy.Format("%02X%s功能类型FUN:%d\r\n", m_pRxdFm_JC103->bFUN, GetSpace(1), m_pRxdFm_JC103->bFUN);
m_result += qy;
qy.Format("%02X%s信息序号INF:%d %s\r\n", m_pRxdFm_JC103->bINF, GetSpace(1), m_pRxdFm_JC103->bINF, GetINFstrign(m_pRxdFm_JC103->bINF));
m_result += qy;
qy.Format("%02X%s未用\r\n", JC103_Wave->dwNotUsed, GetSpace(1));
m_result += qy;
qy.Format("%02X%s数据类型:%d\r\n", JC103_Wave->bDataType, GetSpace(1), JC103_Wave->bDataType);
m_result += qy;
//其余字段...
BYTE* pData = &(JC103_Wave->bData);
while (1)
{
//循环输出数据部分..
pData[wOffset++];
//循环输出数据部分..
}
return TRUE;
}
其中最主要的代码便是这两行:
TJC103_Wave* JC103_Wave = (TJC103_Wave*) & (m_pRxdFm_JC103->bData);
BYTE* pData = &(JC103_Wave->bData);
我们收到的报文内容存放在m_pRxdFm_JC103
中,第一句将m_pRxdFm_JC103->bData
的地址赋值给JC103_Wave
,并且强制转换为TJC103_Wave
类型,以 TJC103_Wave
的方式来访问 m_pRxdFm_JC103->bData
的内容,并且可以通过JC103_Wave->bData
来访问到数据类型的值,通过&(JC103_Wave->bData)
来访问到其地址。
第二句则是将JC103_Wave->bData
的地址赋值给pData
,并且可以通过pData[0] 、pData[1]
来访问到后续的值。
例如报文:
68 0C 18 00 04 00 1A 81 1F 01 FF 00 00 01
由103规约可知,1A是类型标识是26,进入上面我们提到的Rxd68_JC103_Burst_Trans_Ready_26
函数,并且可以知道此时m_pRxdFm_JC103->bData
的值便是最后一个00,而最后的00 01其实在内存中就是紧跟在m_pRxdFm_JC103->bData
的值00之后的,所以我们这时可以通过JC103_Wave
来接管后面两个字节的监控,同时可以用JC103_Wave->bNotUsed
来访问到这个最后的00 ,用JC103_Wave->bDataType
访问到最后的01。
因为我们最后要操作数据,并且数据是一个数据集一个数据集地存放,所以我们需要通过pData[offset]
这种方式来访问到每一个数据,所以我们将JC103_Wave->bData
的地址在赋值给一个BYTE
型指针,这样我们就可以一个字节一个字节地访问到每一个数据了。