关于电力行业104规约解析--可变帧程序解析

来源:互联网 发布:网络授课平台招收教师 编辑:程序博客网 时间:2024/06/05 01:18

前面一节我们讲了固定帧:可变帧最大的区别在于数据不是连续的,都带地址信息,该地址信息就是点号。

 

//发送变化遥测数据,可变帧遥信
void CMainFrame::SendChangeYXData()
{
 //总遥信个数
 int iYXByteCout = dbm.yxcsum;
 //APDU个数
 int iAPDUCout = 0;
 //最后一帧APDU字节数
 int iLastAPDUCout = 0;
 //最大遥信字节数
 int iMaxYx = 60;
 //得到APDU个数
 iAPDUCout = iYXByteCout / iMaxYx;
 //得到最后一帧APDU字节数
 iLastAPDUCout = iYXByteCout % iMaxYx;
    //循环组APDU
 for(int w=0;w<iAPDUCout;w++)
 {
  memset(byteAPDUCYX,0,sizeof(byteAPDUCYX));//初始化
  //计算报头字节  
  /////////////////////////////////APCI//////////////////////////////////////////////////////
  byteAPDUCYX[0] =0x68;//报头字
  byteAPDUCYX[1] = 0xFA;//APDU长度250
   
  byteAPDUCYX[2] =0x02;//1 8位控制域 低位  00000010
  byteAPDUCYX[3] =0x00;//2 8位控制域 高位  00000000  
     //                                       0000000000000010 I格式发送帧计数
  byteAPDUCYX[4] =0x02;//3 8位控制域 低位    00000010
  byteAPDUCYX[5] =0x00;//4 8位控制域 高位    00000000
     //                                       0000000000000010 I格式接收帧计数
  /////////////////////////////////ASDU//////////////////////////////////////////////////////
  byteAPDUCYX[6] =0x01;//标识符 遥信
  //可变帧限定词                          01111111 第一位1表示连续,如果为0表示非连续
  byteAPDUCYX[7] = 0x3C;//计算**            1111111 127个数据
  //传送原因
  byteAPDUCYX[8] =0x14;//响应总召唤           传送原因
  byteAPDUCYX[9] =0x00;//响应总召唤           传送原因
       
  //计算公共地址 ASDU地址
  BYTE *pXXTDZ = new byte[2]; 
  memcpy(pXXTDZ, &dbm.r_yxc[w*iMaxYx].NU, 2);
  //给公共地址赋值
  byteAPDUCYX[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
  byteAPDUCYX[11] =pXXTDZ[1];
  //释放临存公共地址的空间
  free(pXXTDZ); 
  //信息体
  //如果SQ=0,表示非连续数据,一个三字节信息地址,一个一字节遥信数据
  //如果SQ=1,表示连续数据,用公用地址,然后连续一个字节遥信数据
  int iIndex = 0;//累加号
  for(int i=(w*iMaxYx);i<((w+1)*iMaxYx);i++)
  {
   BYTE *pXXTDZ1 = new byte[3]; 
   memcpy(pXXTDZ1, &dbm.r_yxc[w*iMaxYx].NU, 3);
   //给公共地址赋值
   byteAPDUCYX[12+iIndex+0] =pXXTDZ1[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
   byteAPDUCYX[12+iIndex+1] =pXXTDZ1[1];
   byteAPDUCYX[12+iIndex+2] =pXXTDZ1[2];
   byteAPDUCYX[12+iIndex+3] = (BYTE)dbm.r_yxc[i].val;
   free(pXXTDZ1);
   iIndex = iIndex+4;
  }
  //校验和CS
  byteAPDUCYX[12+iIndex] = 0xFA;
  //结束标识
  byteAPDUCYX[13+iIndex] = 0x16;
  //发送
  if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
  {      
   //SetSendBufData(byteAPDU,sizeof(byteAPDU));
   m_pMListenSocket->m_pClientSocket->SendTo(byteAPDUCYX,sizeof(byteAPDUCYX),atoi(strPort),strIP);
   Sleep(100);
  }
 }
 //最后一个APDU组包
    byteAPDUCYX[0] =0x68;//报头字
 //计算APDU长度
 int ilastLen = (iLastAPDUCout*4)+10;
 BYTE *pAPDULEN = new byte[1];
 memcpy(pAPDULEN, &ilastLen, 1);

 byteAPDUCYX[1] = pAPDULEN[0];//APDU长度250
   
 byteAPDUCYX[2] =0x02;//1 8位控制域 低位  00000010
 byteAPDUCYX[3] =0x00;//2 8位控制域 高位  00000000  
 //                                       0000000000000010 I格式发送帧计数
 byteAPDUCYX[4] =0x02;//3 8位控制域 低位    00000010
 byteAPDUCYX[5] =0x00;//4 8位控制域 高位    00000000
 //                                       0000000000000010 I格式接收帧计数
 /////////////////////////////////ASDU//////////////////////////////////////////////////////
 byteAPDUCYX[6] =0x01;//标识符 遥信
    //计算可变帧限定词
 BYTE *pAPDULEN_ = new byte[1];
 memcpy(pAPDULEN_, &iLastAPDUCout, 1);
 //可变帧限定词                                  01111111 第一位1表示连续,如果为0表示非连续
 byteAPDUCYX[7] = pAPDULEN_[0];//计算**            1111111 127个数据
 free(pAPDULEN_);
 //传送原因
 byteAPDUCYX[8] =0x14;//响应总召唤           传送原因
 byteAPDUCYX[9] =0x00;//响应总召唤           传送原因
  
    //计算公共地址 ASDU地址
 BYTE *pXXTDZ = new byte[2]; 
 memcpy(pXXTDZ, &dbm.r_yxc[iAPDUCout*iMaxYx].NU, 2);
 //给公共地址赋值
 byteAPDUCYX[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
 byteAPDUCYX[11] =pXXTDZ[1];
 //释放临存公共地址的空间
 free(pXXTDZ);
 int iIndex = 0;//顺序号
 for(int i=(iAPDUCout*iMaxYx);i<iYXByteCout;i++)
 {
  BYTE *pXXTDZ1 = new byte[3]; 
  memcpy(pXXTDZ1, &dbm.r_yxc[w*iMaxYx].NU, 3);
  //给公共地址赋值
  byteAPDUCYX[12+iIndex+0] =pXXTDZ1[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
  byteAPDUCYX[12+iIndex+1] =pXXTDZ1[1];
  byteAPDUCYX[12+iIndex+2] =pXXTDZ1[2];
  byteAPDUCYX[12+iIndex+3] = (BYTE)dbm.r_yxc[i].val;
  free(pXXTDZ1);
  iIndex = iIndex+4;
 }
 //校验和CS
    byteAPDUCYX[12+iIndex] = pAPDULEN[0];
 free(pAPDULEN);
 //结束标识
 byteAPDUCYX[13+iIndex] =0x16;
 //发送
 if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
 {
  //SetSendBufData(byteAPDU,sizeof(byteAPDU));
    m_pMListenSocket->m_pClientSocket->SendTo(byteAPDUCYX,(14+iLastAPDUCout*4),atoi(strPort),strIP);
  Sleep(100);
 }
}

 

原创粉丝点击