?? df_103.c
字號:
/****************************************************************************/
/* */
/* 版權 (c) 2000-2010 國電南京自動化股份有限公司 */
/* */
/****************************************************************************/
/****************************************************************************/
/* 文件名 */
/* */
/* DF_103.c 1.00 */
/* */
/* 概述: */
/* */
/* 轉接東方電子1700系統 */
/* */
/* 保護:PSL600,PST1200,PSL640及系列 */
/* */
/* 任務:保護事件,告警事件,軟壓板,遙測,遙信,定值上送,遠方投退壓板 */
/* 遠方修改定值,遙控跳合閘,通訊對時,遠方復歸保護信號 */
/* */
/* 上行報文: */
/* 保護事件,告警事件,遙信-----ASDU1 */
/* 軟壓板-----------------------ASDU1(總查詢,或壓板變位遙信) */
/* 總查詢結束-------------------ASDU8 */
/* 遙測-------------------------ASDU9(越限上送) */
/* 回答出廠信息-----------------ASDU5 */
/* 定值上送---------------------ASDU10(通用分類服務) */
/* 描述-------------------------ASDU10 */
/* 下行報文: */
/* 通訊對時---------------------ASDU6 */
/* 總查-------------------------ASDU8 */
/* 遠方復歸保護信號-------------ASDU20 */
/* 遠方投退壓板-----------------ASDU10 */
/* 遠方遙控跳合閘---------------ASDU10 */
/* 遠方修改定值-----------------ASDU10 */
/* 讀取(定值、壓板狀態、遙信)---ASDU21 */
/* XM修改: */
/* 1 遙測按高13位傳 */
/* 2 二級數據送遙信SOE,壓板SOE,及全遙測 */
/* 3 一級數據送全遙信,保護事件,告警的SOE */
/****************************************************************************/
#include "typedef.h"
#include "generic.h"
#include "inforec.h"
#include "dev_mng.h"
#include "DF_103.h"
//#include "telnet.h"
//#include "cs8900.h"
//#include "target"
//REM ZJH 2002/11/7
//#define UART_RCV_SIZE 250
//ADD ZJH 2002/11/7
#define UART_RCV_SIZE 300
//END ZJH 2001/11/7
static WORD flag[DEV_TYPE];
static BYTE scn;
BYTE sbuf[UART_PACKET_SIZE];
//REM ZJH 2002/11/7
//BYTE last_cmd;
//WORD last_id;
BYTE last_cmd[DEV_TYPE];
WORD last_id[DEV_TYPE];
//END ZJH 2001/11/7
WORD tot_leng;
BYTE dznumber;
BYTE list_num;
BYTE count,ACD;
T_SET rsetbuf;
T_SET wsetbuf;
T_LIST list;
T_MEASURE measure;
T_SFC sfc[DEV_TYPE];
T_DI di[DEV_TYPE];
T_ANALOG_ENTRY *p_analog_list;
T_SET_ENTRY *p_set_list;
T_SFC_ENTRY *p_sfc_list;
extern T_IED g_ied_list[];
extern WORD g_ied_num;
/* 串口設置 */
extern BYTE uart_port;
/* 數據庫句柄 */
static HANDLE hand;
/* 串口任務 */
static BYTE STACK_SERIAL[0x2000];
static NU_TASK nuTask_Serial;
/* 數據接受處理函數 */
void Serial_Interpret(const BYTE* rbuf,BYTE uart_port)
{
BYTE byDevAddr;
BYTE i;
WORD Dev_Num;
Dev_Num = Get_Device_Number();
for (i = 1;i <= Dev_Num;i++)
{
byDevAddr = ID_to_Addr(i);
switch (rbuf[0])
{
case FRAME_T_CON:
if (rbuf[2] == byDevAddr)
{
Ack_Staid(rbuf,byDevAddr,uart_port);
return;
}
break;
case FRAME_T_VOL:
if (rbuf[5] == byDevAddr || rbuf[5] == 0xff)
{
Ack_Changeable(rbuf,byDevAddr,uart_port);
return;
}
break;
default:
return;
}
}
}
//可變幀長報文的處理
void Ack_Changeable(const BYTE* rbuf,BYTE byDevAddr,BYTE uart_port)
{
switch(rbuf[6])
{
case 0x06:
ASDU06(rbuf,byDevAddr,uart_port);//對時
return ;
case 0x07:
ASDU07(rbuf,byDevAddr,uart_port);//總查詢
return ;
case 0x0a:
ASDU10(rbuf,byDevAddr,uart_port);//通用分類數據
return ;
case 0x14:
ASDU20(rbuf,byDevAddr,uart_port);//一般命令(復歸保護信號)
return;
case 0x15:
ASDU21(rbuf,byDevAddr,uart_port);//通用分類命令
return ;
default:
return ;
}
}
//固定幀長報文的處理
void Ack_Staid(const BYTE* rbuf,BYTE byDevAddr,BYTE uart_port)
{
BYTE *crc;
BYTE *apack;
BYTE dev_fun;
T_EVENT pEvent;
T_DIC pDIC;
T_DATE t_date;
T_SFCC pSFCC;
BOOL bDI,bEvent,bMeasure,bAlarm,bSFCC;
WORD wLen;
WORD ngd;
WORD dev_id;
dev_id = Addr_to_ID(byDevAddr);
//REM ZJH 2002/11/7
//if (rbuf[1] == last_cmd && dev_id == last_id)
if (rbuf[1] == last_cmd[dev_id-1] && dev_id == last_id[dev_id-1])
//END ZJH 2002/11/7
{
//將上次報文重發
wLen = tot_leng;
UART_Write(uart_port,sbuf,wLen);
return;
}
//REM ZJH 2002/11/7
// last_cmd = rbuf[1];
// last_id = dev_id;
last_cmd[dev_id-1] = rbuf[1];
last_id[dev_id-1] = dev_id;
//END ZJH 2002/11/7
switch(rbuf[1]&0x0f)
{
case 0x00:
//復位通信單元
memset(sbuf, 0, UART_RCV_SIZE);
//REM ZJH 2002/11/7
// flag = FLAG_RESET_CU;
flag[dev_id-1] = FLAG_RESET_CU;
//END ZJH 2002/11/7
sbuf[0] = 0x10;
sbuf[1] = 0x20;
sbuf[2] = byDevAddr;
wLen = 2;
sbuf[3] = Makecrc(&sbuf[1],wLen);
sbuf[4] = 0x16;
wLen = 5;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
break;
case 0x07:
//復位幀計數位
flag[dev_id-1] = FLAG_RESET_FCB;
sbuf[0] = 0x10;
sbuf[1] = 0x20;
sbuf[2] = byDevAddr;
wLen = 2;
sbuf[3] = Makecrc(&sbuf[1],wLen);
sbuf[4] = 0x16;
wLen = 5;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
break;
case 0x0a:
if (flag[dev_id-1] == FLAG_RESET_CU)
{
//回答復位通信單元報文
ASDU05(rbuf,byDevAddr,uart_port);
flag[dev_id-1] = FLAG_POWER_ON;
return;
}
if (flag [dev_id-1]== FLAG_RESET_FCB)
{
//回答復位幀計數報文
ASDU05(rbuf,byDevAddr,uart_port);
flag[dev_id-1]= FLAG_POWER_ON;
return;
}
if (flag[dev_id-1] == FLAG_POWER_ON)
{
ASDU05(rbuf,byDevAddr,uart_port);
flag[dev_id-1] = 0x00;
return;
}
//檢查是否總查詢發生
if (flag[dev_id-1] == FLAG_POLLING)
{
//REM ZJH 2002/11/7
//asdu40回答全遙信
ASDU40(rbuf,byDevAddr,uart_port);
flag[dev_id-1] = FLAG_POLLING_OK;
//ASDU01(rbuf,byDevAddr,uart_port);
//END ZJH 2002/11/7
return;
}
if (flag[dev_id-1] == FLAG_POLLING_OK)
{
ACD=0;
bDI = INF_Search_Dic(hand,dev_id);
bEvent = INF_Search_Event(hand,dev_id);
bAlarm = INF_Search_Alarm(hand,dev_id);
bSFCC = INF_Search_SFCC(hand,dev_id);
if (bDI||bSFCC||bEvent||bAlarm) ACD=0x20;
//檢查是否有保護事件發生
bEvent = INF_Search_Event(hand,dev_id);
if (bEvent)
{
INF_Get_Event(hand,dev_id,&pEvent);
apack = sbuf;
*apack++ = 0x68;
*apack++;
*apack++;
*apack++ = 0x68;
crc = apack;
bEvent = INF_Search_Event(hand,dev_id);
*apack++ = 0x08|ACD;
*apack++ = byDevAddr;
*apack++ = 0x01;
*apack++ = 0x81;
*apack++ = 1;
*apack++ = byDevAddr;
*apack++ = Get_Fun(dev_id);
*apack++ = (BYTE)pEvent.e_code + EVT_BEGIN;//條目號
*apack++ = (BYTE)pEvent.e_state + 1;
*apack++ = (BYTE) pEvent.e_date.msec;
*apack++ = (BYTE) (pEvent.e_date.msec >> 8);
*apack++ = pEvent.e_date.minute;
*apack++ = pEvent.e_date.hour;
*apack++ = 0;
wLen = apack - crc;
sbuf[1] = (BYTE)wLen;
sbuf[2] = (BYTE)wLen;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//檢查是否有保護告警事件發生
bAlarm = INF_Search_Alarm(hand,dev_id);
if (bAlarm)
{
INF_Get_Alarm(hand,dev_id,&pEvent);
apack = sbuf;
*apack++ = 0x68;
*apack++;
*apack++;
*apack++ = 0x68;
crc = apack;
*apack++ = 0x08|ACD;
*apack++ = byDevAddr;
*apack++ = 0x01;
*apack++ = 0x81;
*apack++ = 1;
*apack++ = byDevAddr;
*apack++ = Get_Fun(dev_id);//Fun
switch(*(apack-1)) //廣東鐘村特別修改pst1260
{
case 194:
if(((BYTE)pEvent.e_code>=0x14)&&((BYTE)pEvent.e_code<=0x18))
*apack++ = (BYTE)pEvent.e_code- 0x14;
else
*apack++ = (BYTE)pEvent.e_code + ALA_BEGIN;//條目號
break;
case 195:
if((BYTE)pEvent.e_code>=0x1f)
*apack++ = (BYTE)pEvent.e_code - 0x1f;
else
*apack++ = (BYTE)pEvent.e_code + ALA_BEGIN;//條目號
break;
case 196:
if((BYTE)pEvent.e_code>=0x1f)
*apack++ = (BYTE)pEvent.e_code - 0x1f;
else
*apack++ = (BYTE)pEvent.e_code + ALA_BEGIN;//條目號
break;
default:
*apack++ = (BYTE)pEvent.e_code + ALA_BEGIN;//條目號
break;
}
*apack++ = (BYTE)pEvent.e_state + 1;
*apack++ = (BYTE) pEvent.e_date.msec;
*apack++ = (BYTE) (pEvent.e_date.msec >> 8);
*apack++ = pEvent.e_date.minute;
*apack++ = pEvent.e_date.hour;
*apack++ = 0;
wLen = apack - crc;
sbuf[1] = (BYTE)wLen;
sbuf[2] = (BYTE)wLen;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//回答無所響應數據報文
if(bEvent||bAlarm)
{
apack = sbuf;
*apack++ = 0x10;
crc = apack;
*apack++ = 0x09|ACD;
*apack++ = byDevAddr;
*apack++ = Makecrc(crc,2);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
{
ASDU40(rbuf,byDevAddr,uart_port);
return;
}
}
//總查詢的終止
if (flag[dev_id-1] == FLAG_POLLING_END)
{
ASDU08(rbuf,byDevAddr,uart_port);
return;
}
//傳送描述表
if (flag[dev_id-1] == FLAG_READ_LIST)
{
BYTE i;
BYTE ginl;
BYTE data_leng;
apack = sbuf;
*apack++ = 0x68;
apack++;
apack++;
*apack++ = 0x68;
crc = apack;
*apack++ = 0x28;
*apack++ = byDevAddr;
*apack++ = 0x0a;
*apack++ = 0x81;
*apack++ = 0x2a;
*apack++ = byDevAddr;
*apack++ = 0xfe;
*apack++ = 0xf1;
*apack++ = 0x00;
data_leng = 0x0a;
*apack++ = (BYTE)list.l_size;
switch(list.l_type)
{
case LIST_T_ANALOG:
// p_analog_list = (T_ANALOG_ENTRY *) list.l_ptr;
ginl = 0x01;
break;
case LIST_T_SET:
// p_set_list = (T_SET_ENTRY *) list.l_ptr;
ginl = 0x04;
break;
case LIST_T_SFC:
// p_sfc_list = (T_SFC_ENTRY *) list.l_ptr;
ginl = 0x06;
break;
}
i = 0;
while(i < 10)
{
if(list_num < list.l_size)
{
*apack++ = ginl;
*apack++ = list_num + 1;
*apack++ = 10;
*apack++ = 1;
*apack++ = 16;
*apack++ = 1;
data_leng += 6;
if(list.l_type == LIST_T_ANALOG)
{
memcpy(apack, p_analog_list->name,16);
apack += 16;
data_leng += 16;
list_num ++;
p_analog_list++;
}
if(list.l_type == LIST_T_SET)
{
memcpy(apack, p_set_list->name,16);
apack += 16;
data_leng += 16;
list_num ++;
p_set_list++;
}
if(list.l_type == LIST_T_SFC)
{
memcpy(apack, p_sfc_list->name,16);
apack += 16;
data_leng += 16;
list_num ++;
p_sfc_list++;
}
i++;
}
else
break;
}
//超過10項分幀發送
sbuf[1] = data_leng;
sbuf[2] = data_leng;
if (list_num != list.l_size)
{
sbuf[13] = (i | 0x80);
sbuf[4] = 0x28;
}
else
{
sbuf[13] = (i | 0x00);
sbuf[4] = 0x08;
flag[dev_id-1] = 0;
}
wLen = data_leng;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = data_leng + 6;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//是否傳送遙信量
if(flag[dev_id-1] == FLAG_READ_DI)
{
BYTE i;
flag[dev_id-1] = 0x00;
apack = sbuf;
*apack++ = 0x68;
apack++;
apack++;
*apack++ = 0x68;
crc = apack;
*apack++ = 0x08;
*apack++ = byDevAddr;
*apack++ = 0x0a;
*apack++ = 0x81;
*apack++ = 0x2a;
*apack++ = byDevAddr;
*apack++ = 0xFE;
*apack++ = 0xf1;
*apack++ = 0x00;
*apack++ = (BYTE) di[dev_id-1].di_num;
for(i = 0;i< (di[dev_id-1].di_num + 31)/32;i++)
{
*apack++ = 0x07;//遙信組
*apack++ = i + 1;
*apack++ = 1;
*apack++ = 7;
*apack++ = 4;
*apack++ = 1;
*apack++ = *((BYTE *)&di[dev_id-1].di_val[i] + 3);
*apack++ = *((BYTE *)&di[dev_id-1].di_val[i] + 2);
*apack++ = *((BYTE *)&di[dev_id-1].di_val[i] + 1);
*apack++ = *((BYTE *)&di[dev_id-1].di_val[i]);
}
wLen = apack - crc;
sbuf[1] = wLen + 2;
sbuf[2] = wLen + 2;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//是否要傳送遙測值
if(flag[dev_id-1] == FLAG_READ_MEASURE)
{
BYTE i;
flag[dev_id-1] = 0x00;
apack = sbuf;
*apack++ = 0x68;
apack++;
apack++;
*apack++ = 0x68;
crc = apack;
*apack++ = 0x08;
*apack++ = byDevAddr;
*apack++ = 0x0a;
*apack++ = 0x81;
*apack++ = 0x2a;
*apack++ = byDevAddr;
*apack++ = 0xFE;
*apack++ = 0xf1;
*apack++ = 0x00;
*apack++ = (BYTE) measure.ms_num;
for(i = 0;i< measure.ms_num;i++)
{
*apack++ = 0x01;//遙測組
*apack++ = i + 1;
*apack++ = 1;
*apack++ = 7;
*apack++ = 2;
*apack++ = 1;
*apack++ = LOBYTE(measure.ms_val[i]<<3); //高13位
*apack++ = HIBYTE(measure.ms_val[i]<<3);
}
wLen = apack - crc;
sbuf[1] = wLen + 2;
sbuf[2] = wLen + 2;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//檢查是否要傳送軟壓板
if(flag[dev_id-1] == FLAG_READ_SFC)
{
BYTE i;
flag[dev_id-1] = 0x00;
apack = sbuf;
*apack++ = 0x68;
apack++;
apack++;
*apack++ = 0x68;
crc = apack;
*apack++ = 0x08;
*apack++ = byDevAddr;
*apack++ = 0x0a;
*apack++ = 0x81;
*apack++ = 0x2a;
*apack++ = byDevAddr;
*apack++ = 0xFE;
*apack++ = 0xf1;
*apack++ = 0x00;
*apack++ = (BYTE) sfc[dev_id-1].sfc_num;
for(i = 0;i< sfc[dev_id-1].sfc_num;i++)
{
*apack++ = 0x06;//壓板組
*apack++ = i + 1;
*apack++ = 1;
*apack++ = 10;
*apack++ = 1;
*apack++ = 1;
*apack++ =((BYTE) (sfc[dev_id-1].sfc_val[0] >> i)&0x00000001) + 1;
if(i == 31)
{
sfc[dev_id-1].sfc_val[0] = sfc[dev_id-1].sfc_val[1];
}
}
wLen = apack - crc;
*apack++ = Makecrc(crc,wLen);
*apack++ = 0x16;
wLen = apack - sbuf;
tot_leng = wLen;
UART_Write(uart_port,sbuf,wLen);
return;
}
//檢查是否要傳送保護定值 asdu10
if (flag[dev_id-1] == FLAG_READ_SET)
{
BYTE data_leng,i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -