TA的每日心情 | 开心 2020-6-4 18:11 |
---|
签到天数: 75 天 连续签到: 1 天 [LV.6]常住居民II
|
本帖最后由 zt1234 于 2018-6-6 10:04 编辑
DTU用于实现电网保护,下面挂很多FTU,通过网线或串口线与维护机通信进行配置监视等,通过网口或串口与管理部分通信接收监控,所以串口应用比较多,一般应该有双网口。试用的板子只有一个网口,也是设计 测试阶段,就采用一个WIFI模块实现了另一个网口。
DTU需要通过IEC101协议与维护计算机通信,获取对各种FTU和线损模块的配置和测控信息。配置信息包括各个模块的链路地址、遥信、遥控、遥测、电量、SOE等容量、国标地址和名称、定值区号、动作参数等。程序设计的核心是IEC101协议的实现,该协议定义的数据帧结构如下
一个与维护机通信的例程如下
//DTU接收主站报文
void SlaveRec(BYTE recByte)
{
switch (m_SReadState)
{
case StartByte:
m_SRecByte[0] = recByte;
if (m_SRecByte[0] == 0x10)m_SReadState = CtrlByte;
else if (m_SRecByte[0] == 0x68)m_SReadState = Num_68H_1;
break;
//=========== 启动字符为68H ==========//
case Num_68H_1:
m_SRecByte[1] = recByte;
m_SReadState = Num_68H_2;
break;
case Num_68H_2:
m_SRecByte[2] = recByte;
if (m_SRecByte[2] == m_SRecByte[1])
m_SReadState = Start_68H_2;
else
m_SReadState = StartByte;
break;
case Start_68H_2:
m_SRecByte[3] = recByte;
if (m_SRecByte[3] == 0x68)
{
m_MsgIndex = 0;
m_SReadState = Msg_68H;
}
else
m_SReadState = StartByte;
break;
case Msg_68H:
m_SRecByte[4+m_MsgIndex] = recByte;
if (m_MsgIndex < (m_SRecByte[1]-1)) // 如读取的字节数小于信息字节数,则继续读取
m_MsgIndex++;
else
{
m_SReadState = Check_68H;
m_MsgIndex = 0;
}
break;
case Check_68H:
m_SRecByte[4+m_SRecByte[1]] = recByte;
BYTE tembyte;
tembyte = GetAddByte(m_SRecByte,m_SRecByte[1],4);
if (m_SRecByte[4+m_SRecByte[1]] == tembyte)
m_SReadState = End_68H;
else
m_SReadState = StartByte;
break;
case End_68H: //启动字符为68H的报文接收完毕,解包
m_SRecByte[5+m_SRecByte[1]] = recByte;
if (m_SRecByte[5+m_SRecByte[1]] == 0X16 &&
m_SRecByte[5] == m_Addr)
SUnPack_Start68H(); //解包
m_SReadState = StartByte;
break;
///////////////////////////////////////////////
default:
m_SReadState = StartByte; //重新从地址码读取
break;
}
}
|
|