/******************** (C) COPYRIGHT 2009 FXXC E-TECH LIMITED********************
* File Name : Porcess.c
* Author : Deng Jian
* Version : V1.0.0
* Last Modify : 07/10/2009
* Description :
* ------------------------------------------------------------------------------
* Modification history
* 2009-07-10 Created by Deng Jian
* 2009-07-18 Tested by Deng Jian
* ------------------------------------------------------------------------------
********************************************************************************/
#include "plc.h"
#include "led.h"
#include "flag.h"
#include "misc.h"
#include "timer.h"
#include "meter.h"
#include "dlt698.h"
unsigned char buf9010[14] = {0x68, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0x68, 0x01, 0x02, 0x43, 0xC3, 0xD5, 0x16};
//////////////////////////////////////////////////////////////////////////////////begin of Dennis Ding
unsigned int g_autoreport_timer;
unsigned int meterNumberNoReply;
unsigned char len_flag=0;
unsigned char send_time=0;
unsigned char g_upload_buf[10];
void UploadMeterAddress(void)
{
unsigned int i;
g_upload_buf[0] = 1;//数量
for (i=0;i<6;i++)
{
g_upload_buf[i+1] = currentMeter.address[i];//地址,低字节在前
}
g_upload_buf[7] = 1;//规约类型
g_upload_buf[8] = modemParam.currentCount % 256;
g_upload_buf[9] = modemParam.currentCount / 256;
DLTUpload(2,g_upload_buf,10);
}
unsigned int calccrc(unsigned char crcbuf,unsigned int crc)
{
unsigned char i;
crc=crc ^ crcbuf;
for(i=0;i<8;i++)
{
unsigned char chk;
chk=crc&1;
crc=crc>>1;
crc=crc&0x7fff;
if (chk==1)
crc=crc^0xa001;
crc=crc&0xffff;
}
return crc;
}
unsigned int chkcrc(unsigned char *buf,unsigned char len)
{
unsigned char hi,lo;
unsigned int i;
unsigned int crc;
crc=0xFFFF;
for (i=0;i<len;i++)
{
crc=calccrc(*buf,crc);
buf++;
}
hi=crc%256;
lo=crc/256;
crc=(hi<<8)|lo;
return crc;
}
void xiaoyan(unsigned char hh) //根据中继级数计算抄表帧的检验和 LGD 注释
{
unsigned char r;
unsigned char sumh,suml;
unsigned char len;
unsigned int CRC;
r=hh;
switch(r)
{
case 0:
//len = 13;
len = PLCTxBuf[1] + 2;
CRC = chkcrc(PLCTxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
PLCTxBuf[len] = suml;
PLCTxBuf[len + 1] = sumh;
break;
case 1:
len = PLCTxBuf[1] + 2;
CRC = chkcrc(PLCTxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
PLCTxBuf[len] = suml;
PLCTxBuf[len + 1] = sumh;
break;
case 2:
len = PLCTxBuf[1] + 2;
CRC = chkcrc(PLCTxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
PLCTxBuf[len] = suml;
PLCTxBuf[len + 1] = sumh;
break;
case 3:
len = PLCTxBuf[1] + 2;
CRC = chkcrc(PLCTxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
PLCTxBuf[len] = suml;
PLCTxBuf[len + 1] = sumh;
break;
case 4:
case 5:
case 6:
case 7:
len = PLCTxBuf[1] + 2;
CRC = chkcrc(PLCTxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
PLCTxBuf[len] = suml;
PLCTxBuf[len + 1] = sumh;
break;
}
return;
}
unsigned char jiancha(void)
{
unsigned int CRC;
//unsigned char t;
//unsigned long cc;
unsigned char suml,sumh;
unsigned char sp1,len;
//unsigned char di0,di1;
unsigned char cccc,dddd;
unsigned char illegal;
illegal = 0;//假设收到的载波帧是合法的。
//检查收到的载波帧,确定是否合法
sp1 = PLCRxBuf[1];
if (sp1 > 100)
{
//总长度非法
illegal = 1;
}
len = sp1 + 2;
CRC = chkcrc(PLCRxBuf,len);
sumh = CRC;
CRC = CRC >> 8;
suml = CRC;
if((suml != PLCRxBuf[len])||(sumh != PLCRxBuf[len+1]))
{
//校验没通过
illegal = 2;
}
cccc = PLCRxBuf[9];
cccc = cccc & 0xC0;
if(cccc == 0xC0) //否定帧
{
//是否定帧
//但可以做中继 ???????????????没记录抄到,就是没抄到,没记入补抄数组,也不会补抄。??????
//但如果发生复位,重新组织补抄,就可能会重抄。
illegal = 3;
}
cccc = PLCRxBuf[0];
cccc = cccc & 0x07;
dddd = PLCTxBuf[0] & 0x07;
if(dddd != cccc)
{
//中继级数非法
illegal = 4;
}
cccc = PLCRxBuf[0];
cccc = cccc & 0x08;
if(cccc != 0)
{
//上行帧方向标志非法
illegal = 5;
}
cccc = PLCRxBuf[0];
cccc = cccc & 0x10;
if(cccc == 0x10)
{
//有源地址
if(PLCRxBuf[2] != 0xBB) illegal = 6;
if(PLCRxBuf[3] != 0xBB) illegal = 6;
if(PLCRxBuf[4] != 0xBB) illegal = 6;
if(PLCRxBuf[5] != 0xBB) illegal = 6;
if(PLCRxBuf[6] != 0xBB) illegal = 6;
if(PLCRxBuf[7] != 0xBB) illegal = 6;
}
else
{
//无源地址
if(PLCRxBuf[2] != PLCTxBuf[2]) illegal = 7;
if(PLCRxBuf[3] != PLCTxBuf[3]) illegal = 7;
if(PLCRxBuf[4] != PLCTxBuf[4]) illegal = 7;
if(PLCRxBuf[5] != PLCTxBuf[5]) illegal = 7;
if(PLCRxBuf[6] != PLCTxBuf[6]) illegal = 7;
if(PLCRxBuf[7] != PLCTxBuf[7]) illegal = 7;
}
/////////////////////////////////////////
//如何判断集中器地址和电表地址?????????????????????????????????
return illegal;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//N12格式,自动上报命令,已经增加中继功能和BT2延时控制.
void AutoReport_send(unsigned char send_type,unsigned char send_time,unsigned char addr_temp,unsigned char addr_num,unsigned char addr_num_s)
{
//send_type为命令类型,addr_temp为通配符地址范围即A0H,auto_meter_num为中继表测量点号和auto_meter.meter_num相同,
//addr_num电表数量, addr_num_s 抄表序号,send_time启动轮次
unsigned short len=0;
unsigned short m=0;
unsigned char relay_depth=0;
unsigned char l_ff_buf[11]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x09,0xaf};
//DLTDeny(83);
relay_depth = routeMeter.flag & METER_DEPTH_MASK;
//IO.TRACE("发送载波类型%x,中继深度%x,启动轮次=%x",send_type,relay_depth,send_time);
if (relay_depth > 7)
{
relay_depth=0;
}
if((send_type!=1)&&(send_type!=3))//不是停止命令,不是直抄通配命令,可以组中继
{
//IO.TRACE("发送类型%x,中继深度%x,中继表号%x,",send_type,relay_depth,auto_meter_num);
unsigned char i;
for(i=1;i<=relay_depth;i++)//relay_depth深度为0不会进入
{
PLCTxBuf[7+i*6-5] = routeMeter.route[(i-1)*6];
PLCTxBuf[7+i*6-4] = routeMeter.route[(i-1)*6+1];
PLCTxBuf[7+i*6-3] = routeMeter.route[(i-1)*6+2];
PLCTxBuf[7+i*6-2] = routeMeter.route[(i-1)*6+3];
PLCTxBuf[7+i*6-1] = routeMeter.route[(i-1)*6+4];
PLCTxBuf[7+i*6] = routeMeter.route[(i-1)*6+5]; //表号,低字在前
//IO.TRACE("中继深度%x",relay_depth);
}
}
//IO.TRACE("开始发送类型%x",send_type);
switch(send_type)
{
case 1: //通配地址搜索帧,参考第5页
//IO.TRACE("直抄搜索方式,通配符%x",addr_temp);
PLCTxBuf[0] = 0xD8;
PLCTxBuf[1] = 0x14;
PLCTxBuf[2] = 0xBB;
PLCTxBuf[3] = 0xBB;
PLCTxBuf[4] = 0xBB;
PLCTxBuf[5] = 0xBB;
PLCTxBuf[6] = 0xBB;
PLCTxBuf[7] = 0xBB;
PLCTxBuf[8] = addr_temp;///////////////////////////////////////////////////////////////////////////////////////////////////////
PLCTxBuf[9] = 0xAA;
PLCTxBuf[10] = 0xAA;
PLCTxBuf[11] = 0xAA;
PLCTxBuf[12] = 0xAA;
PLCTxBuf[13] = 0xAA;
PLCTxBuf[14] = 0x68;
PLCTxBuf[15] = 0x1e;
PLCTxBuf[16] = 0x05;
PLCTxBuf[17] = (0x34+(send_time<<4));//////////////////////////////////////////////////////////////////////////////////////////
PLCTxBuf[18] = 0x33;
PLCTxBuf[19] = 0x34;
PLCTxBuf[20] = 0x42; //BT2时间需要确定
PLCTxBuf[21] = 0x33;
break;
case 2://启动从站Q地址�