📄 functions.cpp
字号:
#include "zlp.h"
extern WORD CRC16(BYTE *puchMsg, WORD usDataLen);
//
local
void AddSOE(CSystemPara *sp, BYTE rtuno, int yxno, BYTE value, BYTE soetype)
{
FTEVENT Event;
FTEVENT *curEvent;
SYSTEMTIME time;
GetLocalTime(&time);
Event.cause = 1;
Event.type = soetype;
Event.state = value;
Event.yxno = yxno;
Event.rtuno = rtuno;
Event.day = (BYTE)time.wDay;;
Event.hour = (BYTE)time.wHour;
Event.minute = (BYTE)time.wMinute;
Event.seconds = (BYTE)time.wSecond;
Event.hundms = (BYTE)(time.wMilliseconds / 100);
Event.ms = (BYTE)(time.wMilliseconds % 100);
EnterCriticalSection(&sp->csEvent);
curEvent = sp->m_events->EventBuf + sp->m_events->EventNum;
memcpy(curEvent,&Event,sizeof(FTEVENT));
if(++sp->m_events->EventNum>=MAX_EVENT_NUM)
sp->m_events->EventNum = 0;
LeaveCriticalSection(&sp->csEvent);
}
//
local
BYTE GetYXType(int yxwno)
{
if( ( (yxwno>=42) && (yxwno<=57) ) ||
( (yxwno>=60) && (yxwno<=66) ) ||
(yxwno==8) ||
(yxwno==9) ||
(yxwno==17) ||
(yxwno==23) )
return 0; // YX
else
return 1; // Alarm
}
/******************************
iStrat - 起始遥信位
num - 要写的遥信位个数, <=8
source - 源字节
*******************************/
local
void CopyBitsToRtuYXW(RTU *rtu, int iStart, int num, BYTE source, CChannel *tempCh, CSystemPara *sp)
{
for(int yxno=iStart;yxno<iStart+num;yxno++)
{
BYTE yxwno = yxno / 16; // 该位所属的遥信字的序号
BYTE pos = yxno % 16; // 该位在所属遥信字中的位置
WORD oldYXW = rtu->YxwValue[yxwno]; // 目的遥信字
WORD mask1 = 1 << pos;
WORD mask2 = 1 << (yxno-iStart);
if( ( (oldYXW & mask1)>0 ) != ( (source & mask2)>0 ) )
{
BYTE value = (source & mask2)>0 ;
BYTE soetype = GetYXType(yxwno);
AddSOE(sp,tempCh->nRtuNo,yxno,value,soetype);
if( (source & mask2)>0 )
rtu->YxwValue[yxwno] += mask1;
else
rtu->YxwValue[yxwno] -= mask1;
}
}
}
// 组遥测量1报文
local
void MakeFrame_YC1(BYTE *buf,BYTE addr)
{
/* ADDR 03H 0000H 002CH CRC16
1byte 1byte 2byte 2byte 2byte */
buf[0] = addr;
buf[1] = 0x03;
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0x2C;
WORD crc = CRC16(buf, 6);
buf[6] = LOBYTE(crc);
buf[7] = HIBYTE(crc);
}
// 解遥测量1报文
local
BOOL Explain_YC1(BYTE *buf,RTU *rtu)
{
/* ADDR 03H 2CH DATA CRC16 8+49=57
1byte 1byte 1byte 44byte 2byte */
if( (buf[0]!=rtu->Addr) ||
(buf[1]!=0x03) ||
(buf[2]!=0x2C) )
return FALSE;
WORD crc = CRC16(buf, 47);
if(crc!=MAKEWORD(buf[47],buf[48]))
return FALSE;
for(int i=0;i<21;i++)
{
WORD value = MAKEWORD(buf[4+i*2],buf[3+i*2]);
if(buf[3+i*2]>0x80) // 负数
rtu->YcValue[i] = (~(value-0x8000)) + 1; // 补码
else // 正数
rtu->YcValue[i] = value;
}
//LOWORD
return TRUE;
}
// 组遥测量2报文
local
void MakeFrame_YC2(BYTE *buf,BYTE addr)
{
/* ADDR 04H 0000H 0028H CRC16
1byte 1byte 2byte 2byte 2byte */
buf[0] = addr;
buf[1] = 0x04;
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0x28;
WORD crc = CRC16(buf, 6);
buf[6] = LOBYTE(crc);
buf[7] = HIBYTE(crc);
}
// 解遥测量2报文
local
BOOL Explain_YC2(BYTE *buf,RTU *rtu)
{
/* ADDR 04H 28H DATA CRC16 8+45=53
1byte 1byte 1byte 40byte 2byte */
if( (buf[0]!=rtu->Addr) ||
(buf[1]!=0x04) ||
(buf[2]!=0x28) )
return FALSE;
WORD crc = CRC16(buf, 43);
if(crc!=MAKEWORD(buf[43],buf[44]))
return FALSE;
WORD value = MAKEWORD(buf[4],buf[3]);
if(buf[3]>0x80) // 负数
rtu->YcValue[21] = (~(value-0x8000)) + 1; // 补码
else // 正数
rtu->YcValue[21] = value;
return TRUE;
}
// 组遥测量3报文
local
void MakeFrame_YC3(BYTE *buf,BYTE addr)
{
/* ADDR 05H 0000H 0028H CRC16
1byte 1byte 2byte 2byte 2byte */
buf[0] = addr;
buf[1] = 0x05;
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0x28;
WORD crc = CRC16(buf, 6);
buf[6] = LOBYTE(crc);
buf[7] = HIBYTE(crc);
}
// 解遥测量3报文
local
BOOL Explain_YC3(BYTE *buf,RTU *rtu)
{
/* ADDR 05H 28H DATA CRC16 8+45=53
1byte 1byte 1byte 40byte 2byte */
if( (buf[0]!=rtu->Addr) ||
(buf[1]!=0x05) ||
(buf[2]!=0x28) )
return FALSE;
WORD crc = CRC16(buf, 43);
if(crc!=MAKEWORD(buf[43],buf[44]))
return FALSE;
WORD value = MAKEWORD(buf[4],buf[3]);
if(buf[3]>0x80) // 负数
rtu->YcValue[22] = (~(value-0x8000)) + 1; // 补码
else // 正数
rtu->YcValue[22] = value;
return TRUE;
}
// 组遥信报文
local
void MakeFrame_YX(BYTE *buf,BYTE addr)
{
/* ADDR 02H 0100H 0024H CRC16
1byte 1byte 2byte 2byte 2byte */
buf[0] = addr;
buf[1] = 0x02;
buf[2] = 0x01;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0x24;
WORD crc = CRC16(buf, 6);
buf[6] = LOBYTE(crc);
buf[7] = HIBYTE(crc);
}
// 解遥信报文
local
BOOL Explain_YX(BYTE *rcv,RTU *rtu,CChannel *tempCh,CSystemPara *sp)
{
/* ADDR 02H 24H DATA CRC16 8+41=49
1byte 1byte 1byte 36byte 2byte */
if( (rcv[0]!=rtu->Addr) ||
(rcv[1]!=0x02) ||
(rcv[2]!=0x24) )
return FALSE;
WORD crc = CRC16(rcv, 39);
if(crc!=MAKEWORD(rcv[39],rcv[40]))
return FALSE;
BYTE *buf = &rcv[2];
/* 字节1
Bit0 交流一路停电√ YX0
Bit1 交流一路欠压√ YX1
Bit2 交流一路过压√ YX2
Bit3 交流一路缺相√ YX3
Bit4 交流二路停电√ YX4
Bit5 交流二路欠压√ YX5
Bit6 交流二路过压√ YX6
Bit7 交流二路缺相√ YX7
*/ BYTE data = buf[1];
CopyBitsToRtuYXW(rtu,0,8,data,tempCh,sp);
/* 字节2
BIT0 交流一路状态(1工作,0备用)√ YX8 *
BIT1 交流二路状态(1工作,0备用)√ YX9 *
BIT2 交流防雷故障√ YX10
BIT3 交流开关量1故障\
BIT4 交流开关量2故障 \
BIT5 交流开关量3故障 > YX11
BIT6 交流开关量4故障 /
BIT7 交流开关量5故障/
*/ data = buf[2] & 0x07;
data += (buf[2] & 0xF8)?0x08:0 ;
CopyBitsToRtuYXW(rtu,8,4,data,tempCh,sp);
/* 字节3
BIT0 一段合母过压√ YX12
BIT1 一段合母欠压√ YX13
BIT2 一段控母过压√ YX14
BIT3 一段控母欠压√ YX15
BIT4 一组电池欠压√ YX16
BIT5 一组电池均充√ YX17 *
BIT6 /
BIT7 /
*/ data = buf[3] & 0x3F;
CopyBitsToRtuYXW(rtu,12,6,data,tempCh,sp);
/* 字节4
BIT0 二段合母过压√ YX18
BIT1 二段合母欠压√ YX19
BIT2 二段控母过压√ YX20
BIT3 二段控母欠压√ YX21
BIT4 二组电池欠压√ YX22
BIT5 二组电池均充√ YX23 *
BIT6 /
BIT7 /
*/ data = buf[4] & 0x3F;
CopyBitsToRtuYXW(rtu,18,6,data,tempCh,sp);
/* 字节5、字节6、字节7
控制开关01故障\
...... > YX24
控制开关24故障/
*/ data = ( buf[5] || buf[6] || buf[7] )?1:0 ;
CopyBitsToRtuYXW(rtu,24,1,data,tempCh,sp);
/* 字节8
BIT0 合闸开关01故障\
BIT1 合闸开关02故障 \
BIT2 合闸开关03故障 \
BIT3 合闸开关04故障 \ YX25
BIT4 合闸开关05故障 /
BIT5 合闸开关06故障 /
BIT6 合闸开关07故障 /
BIT7 合闸开关08故障/
*/ data = buf[8]?1:0 ;
CopyBitsToRtuYXW(rtu,25,1,data,tempCh,sp);
/* 字节9
BIT0 电池开关1故障√ YX26
BIT1 电池开关2故障√ YX27
BIT2 降压模块1故障√ YX28
BIT3 降压模块2故障√ YX29
BIT4 电池熔断器1故障√ YX30
BIT5 电池熔断器2故障√ YX31
BIT6 绝缘1故障√ YX32
BIT7 绝缘2故障√ YX33
*/ data = buf[9];
CopyBitsToRtuYXW(rtu,26,8,data,tempCh,sp);
/* 字节10
BIT0 交流通讯故障√ YX34
BIT1 直流通讯故障√ YX35
BIT2 开关量通讯故障√ YX36
BIT3 电池巡检1通讯故障√ YX37
BIT4 电池巡检2通讯故障√ YX38
BIT5 绝缘检测1通讯故障√ YX39
BIT6 绝缘检测2通讯故障√ YX40
BIT7 /
*/ data = buf[10] & 0x7F;
CopyBitsToRtuYXW(rtu,34,7,data,tempCh,sp);
/* 字节11、字节12
01模块通讯故障\
...... > YX41
16模块通讯故障/
*/ data = ( buf[11] || buf[12])?1:0 ;
CopyBitsToRtuYXW(rtu,41,1,data,tempCh,sp);
/* 字节13、字节14
01模块关机\
...... > YX42-YX57 *
16模块关机/
*/ CopyBitsToRtuYXW(rtu,42,8,buf[13],tempCh,sp);
CopyBitsToRtuYXW(rtu,50,8,buf[14],tempCh,sp);
/* 字节15、字节16
01模块故障\
...... > YX58
16模块故障/
*/ data = ( buf[15] || buf[16])?1:0 ;
CopyBitsToRtuYXW(rtu,58,1,data,tempCh,sp);
/* 字节17、字节18、字节19
一组电池01过高\
...... > YX59
一组电池19过高/
一组尾电池过压√ YX60
*/ data = ( buf[17] || buf[18] || ( buf[19] & 0x07 ) )?1:0 ;
data += (buf[19] & 0x08)?0x02:0 ;
CopyBitsToRtuYXW(rtu,59,2,data,tempCh,sp);
/* 字节20、字节21、字节22
一组电池01过低\
...... > YX61
一组电池19过低/
一组尾电池欠压√ YX62
*/ data = ( buf[20] || buf[21] || ( buf[22] & 0x07 ) )?1:0 ;
data += (buf[22] & 0x08)?0x02:0 ;
CopyBitsToRtuYXW(rtu,61,2,data,tempCh,sp);
/* 字节23、字节24、字节25
一组电池01超差\
...... > YX63
一组电池19超差/
*/ data = ( buf[23] || buf[24] || ( buf[25] & 0x07 ) )?1:0 ;
CopyBitsToRtuYXW(rtu,63,1,data,tempCh,sp);
/* 字节26、字节27、字节28
二组电池01过高\
...... > YX64
二组电池19过高/
二组尾电池过压√ YX65
*/ data = ( buf[26] || buf[27] || ( buf[28] & 0x07 ) )?1:0 ;
data += (buf[28] & 0x08)?0x02:0 ;
CopyBitsToRtuYXW(rtu,64,2,data,tempCh,sp);
/* 字节29、字节30、字节31
二组电池01过低\
...... > YX66
二组电池19过低/
二组尾电池欠压√ YX67
*/ data = ( buf[29] || buf[30] || ( buf[31] & 0x07 ) )?1:0 ;
data += (buf[31] & 0x08)?0x02:0 ;
CopyBitsToRtuYXW(rtu,66,2,data,tempCh,sp);
/* 字节32、字节33、字节34
二组电池01超差\
...... > YX68
二组电池19超差/
*/ data = ( buf[32] || buf[33] || ( buf[34] & 0x07 ) )?1:0 ;
CopyBitsToRtuYXW(rtu,68,1,data,tempCh,sp);
/* 字节35
Bit0 一段合母压差告警√ YX69 *
Bit1 一段控母压差告警√ YX70 *
Bit2 一段母线绝缘故障√ YX71 *
Bit3 / √ YX72(空) *
Bit4 二段合母压差告警√ YX73 *
Bit5 二段控母压差告警√ YX74 *
Bit6 二段母线绝缘故障√ YX75 *
Bit7 /
*/ data = buf[35];
CopyBitsToRtuYXW(rtu,69,7,data,tempCh,sp);
return TRUE;
}
// 组遥调报文
local
void MakeFrame_YT(BYTE *buf,BYTE addr,BYTE type,WORD value)
{
/* a:设置控母输出电压
ADDR 06H 4427H VALUE CRC16
1byte 1byte 2byte 2byte 2byte
b:设置均充电压
ADDR 06H 4443H VALUE CRC16
1byte 1byte 2byte 2byte 2byte
c:设置浮充电压
ADDR 06H 4448H VALUE CRC16
1byte 1byte 2byte 2byte 2byte */
buf[0] = addr;
buf[1] = 0x06;
buf[2] = 0x44;
buf[3] = type;
buf[4] = HIBYTE(value);
buf[5] = LOBYTE(value);
WORD crc = CRC16(buf, 6);
buf[6] = LOBYTE(crc);
buf[7] = HIBYTE(crc);
}
// 解遥调报文
local
BOOL Explain_YT(BYTE *buf,RTU *rtu)
{
/* ADDR 06H REG VALUE CRC16 8+8=16
1byte 1byte 2byte 2byte 2byte */
if( (buf[0]!=rtu->Addr) ||
(buf[1]!=0x06) ||
(buf[2]!=0x44) ||
(buf[3]!=rtu->YTRegLow) ||
(buf[4]!=rtu->YTValueHigh) ||
(buf[5]!=rtu->YTValueLow) )
return FALSE;
WORD crc = CRC16(buf, 6);
if(crc!=MAKEWORD(buf[6],buf[7]))
return FALSE;
return TRUE;
}
// 组遥控报文
local
void MakeFrame_YK(BYTE *buf,BYTE addr,BYTE ykno,BYTE value)
{
/* ADDR 0FH YKNO 0001H 01H VALUE CRC16
1byte 1byte 2byte 2byte 1byte 1byte 2byte */
buf[0] = addr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -