⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 functions.cpp

📁 modbus通讯原代码工程程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -