📄 my102class.cpp
字号:
// My102Class.cpp: implementation of the CMy102Class class.
//
//作者: 潘爱兵
//创建时间:2005-07-13
//地点: 河曲
//功能: 上海惠安MDS-100采集器的102规约的封装类
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "gkdlseries102.h"
#include "My102Class.h"
//PCOMM.h,PCOMM.lib,PCOMM.DLL
#include <Windows.h>
#include "PCOMM.H"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/*
port = 2; // port =2 means COM2
i = sio_open (port); // Port Control, enable the port
if (i == 0) {
sio_ioctl (port, baud, mode); // Port Control, set baud, parity
sio_write (port, "ABCDE", 5); // Output Data function
sio_read (port, ibuf, length); // Input Data function
}
sio_close (port); // Port Control, disable the port
*/
/*
//采集器地址
char address[] = "4B FE";
MDS-100采集器的102报文
报文一,10 49 4b fe 92 16 询问链路状态
报文二,10 40 4b fe 89 16 复位链路
报文三,68 0e 0e 68 73 4b fe 6a 01 06 4b fe oc 28 11 53 0a 04 1c 16 问有无class1数据
报文四,10 5a 4b fe a3 16 问class1数据,对激活确认
报文五,10 7a 4b fe c3 16 问class1数据
char buf11[] = "10 0B 4B FE 54 16 "; //链路好
char buf21[] = "10 00 4B FE 49 16 "; //复位成功
char buf31[] = "10 20 4B FE 69 16 "; //有数据
char buf32[] = "10 00 4B FE 49 16 "; //无数据
char buf41[] = "68 0E 0E 68 28 4B FE 6A 01 07 4B FE 0C ";//07:对激活确认
char buf51[] = "68 0E 0E 68 08 4B FE 6A 01 0A 4B FE 0C ";//0A:传输终止
//68 D2 D2 68 28 4B FE 02 1C 05 4B FE 0C //1C为电量个数
char buf52[] = "68 28 4B FE 02 "; //报文可确定部分
*/
/*电量返回值最大值为0xFFFFFFFF = 42 9496 7295
68 62 62 68 28 fd e1 02 0c 05 fd e1 0c
01 59 6d 00 00 00 1b 类型标识02 +地址fd e1 +积分方式0c +信息体地址01 +电能量59 6d 00 00 +公共时标1e 0b 35 06 04 = 31b 取1b为和校验
02 53 23 02 00 00 ce 类型标识02 +地址fd e1 +积分方式0c +信息体地址02 +电能量53 23 02 00 +公共时标1e 0b 35 06 04 = 2ce 取ce为和校验
03 88 54 01 00 00 34 类型标识02 +地址fd e1 +积分方式0c +信息体地址03 +电能量88 54 01 00 +公共时标1e 0b 35 06 04 = 334 取34为和校验
04 cc ce 00 00 00 f2
05 6d 6d 00 00 00 33
*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMy102Class::CMy102Class()
{
//COM是否成功打开
bCOMOpened = FALSE;
//采集器是否有问题
bCJQIsOk = TRUE;
bFCB = FALSE;
}
CMy102Class::~CMy102Class()
{
}
//功能:打开并设置串口,参数的详细情况请参见moxa的pcomm
//参数
//nPort 串口号 , 如COM2的串口号为2, COM3的串口号为3
//nBaud 波特率
//nBit 数据位
//nStop 停止位
//nParity 校验位
//返回值:
//0 打开并设置成功
//1 打开失败
//2 设置失败
int CMy102Class::OpenPort(int nPort, int nBaud, int nBit, int nStop, int nParity)
{
int ret = sio_open (nPort); /* Port Control, enable the port */
if (ret == SIO_OK)
{
ret = sio_ioctl (nPort, nBaud, nBit|nStop|nParity); /* Port Control, set baud, parity,如 P_NONE | BIT_8 | STOP_1*/
if(ret != SIO_OK)
return 2;
}
else
return 1;
return 0;
}
//功能:关闭串口
//参数
//nPort 串口号 , 如COM2的串口号为2, COM3的串口号为3
//返回值:
//0 关闭成功
//1 关闭失败
int CMy102Class::ClosePort(int nPort)
{
int ret = sio_close (nPort);
if(ret != SIO_OK)
return 1;
return 0;
}
//功能:发送数据请求,注意:防止出现报文不正确的情况
//参数:
//nPort 串口号
//index 要发送的报文的索引
//wBuf 往串口发送的请求报文
//返回值:
//0 写成功
//1 写失败
int CMy102Class::SendRequest(int nPort, int index, char*wBuf)
{
int sendedLen;
int sendingLen;
BYTE buf[30];
if(wBuf!=NULL)
{
sendedLen = sio_write (nPort, wBuf, strlen(wBuf)); /* Output Data function */
}
else
{
switch(index)
{
case 1: //报文1
{
buf[0] = 0x10;
buf[1] = 0x49;
buf[2] = 0x4B;
buf[3] = 0xFE;
buf[4] = 0x92;
buf[5] = 0x16;
sendingLen = 6;
break;
}
case 2: //报文2
{
buf[0] = 0x10;
buf[1] = 0x40;
buf[2] = 0x4B;
buf[3] = 0xFE;
buf[4] = 0x89;
buf[5] = 0x16;
sendingLen = 6;
break;
}
case 4: //报文4
{
buf[0] = 0x10;
buf[1] = 0x5A;
buf[2] = 0x4B;
buf[3] = 0xFE;
buf[4] = 0xA3;
buf[5] = 0x16;
sendingLen = 6;
break;
}
case 5: //报文5
{
buf[0] = 0x10;
buf[1] = 0x7A;
buf[2] = 0x4B;
buf[3] = 0xFE;
buf[4] = 0xC3;
buf[5] = 0x16;
sendingLen = 6;
break;
}
case 3: //报文3:实时报文 "68 0E 0E 68 73 4B FE 6A 01 06 4B FE 0C tm jy end"
{
CTime curTm = CTime::GetCurrentTime();
curTm -= CTimeSpan(0, 0, 15+curTm.GetMinute()%5, curTm.GetSecond());
int year, month, day, week, hour, minute;
BYTE dayByte;
BYTE sumByte;
//分
minute = curTm.GetMinute();
//时
hour = curTm.GetHour();
//日
//日期 = 星期几做为高3位 + 实际日期做为低五位
//如2004-10-29为星期五,那么
// 5= 10100000
// 29= 11101
// 10111101=0xbd
//curTm.GetDayOfWeek()值 星期几 这里高3位
//1 星期天 7
//2 星期一 1
//3 星期二 2
//4 星期三 3
//5 星期四 4
//6 星期五 5
//7 星期六 6
week = curTm.GetDayOfWeek()-1;
if(week==0)
week = 7;
day = curTm.GetDay();
dayByte = (week<<5) | day;
//月
month = curTm.GetMonth();
//年
year = curTm.GetYear()-2000;
//和校验位
sumByte = 0x73+ 0x4b+ 0xfe+ 0x6a+ 0x01+ 0x06+ 0x4b+ 0xfe+ 0x0c+ minute +hour + dayByte + month + year;
buf[0] = 0x68;
buf[1] = 0x0E;
buf[2] = 0x0E;
buf[3] = 0x68;
buf[4] = 0x73;
buf[5] = 0x4B;
buf[6] = 0xFE;
buf[7] = 0x6A;
buf[8] = 0x01;
buf[9] = 0x06;
buf[10] = 0x4B;
buf[11] = 0xFE;
buf[12] = 0x0C;
buf[13] = minute;
buf[14] = hour;
buf[15] = dayByte;
buf[16] = month;
buf[17] = year;
buf[18] = sumByte & 0x0FF;
buf[19] = 0x16;
sendingLen = 20;
break;
}
}
sendedLen = sio_write (nPort, (char*)buf, sendingLen); /* Output Data function */
}
if (sendedLen < 0)
return 1;
return 0;
}
//功能:接收数据
//参数:
//nPort 串口号
//retData 从串口接收的应答数据
//length 接收到的报文的长度
//返回值:
//0 读成功,有数据
//1 读失败
//2 无数据
int CMy102Class::ReceiveData(int nPort, BYTE*retData, int *length)
{
char rBuf[2005];
*length = sio_read(nPort, rBuf, 2000);
if(*length < 0)
return 1;
else if(*length == 0)
return 2;
memcpy(retData, rBuf, *length);
return 0;
}
//功能:判断 发送/回复 是否成功
//参数:
//nPort 串口号
//index 要发送的报文的索引
//sendBuf 发送报文
//nSleep 发送与接收数据的间隔
//revBuf 接收到的报文
//length 接收到的报文的长度
//返回值:
//0 发送,接收成功
//1 写失败
//2 读失败
//3 无数据
int CMy102Class::SendAndReceive(int nPort, int index, char*sendBuf, int nSleep, BYTE*revBuf, int *length)
{
/*测试专用
if(index==1)
{
BYTE retData1[6] = {0x10,0x0B,0x4B,0xFE,0x54,0x16};
*length = 6;
memcpy(revBuf, retData1, *length);
}
else if(index==2)
{
BYTE retData2[6] = {0x10,0x00,0x4B,0xFE,0x49,0x16};
*length = 6;
memcpy(revBuf, retData2, *length);
}
else if(index==3)
{
BYTE retData3[6] = {0x10,0x20,0x4B,0xFE,0x69,0x16};
*length = 6;
memcpy(revBuf, retData3, *length);
}
else if(index==4)
{
BYTE retData4[20] = {0x68,0x0E,0x0E,0x68,0x28,0x4B,0xFE,0x6A,0x01,0x07,0x4B,0xFE,0x0C,0x28,0x11,0x53,0x0A,0x04,0xD2,0x16};
//BYTE retData4[20] = {0x68,0x0E,0x0E,0x68,0x08,0x4B,0xFE,0x6A,0x01,0x0A,0x4B,0xFE,0x0C,0x28,0x11,0x53,0x0A,0x04,0xB5,0x16};
*length = 20;
memcpy(revBuf, retData4, *length);
}
else if(index==5)
{
BYTE retData5[216] = {0x68,0xD2,0xD2,0x68,0x28,0x4B,0xFE,0x02,0x1C,0x05,0x4B,0xFE,0x0C,
0x01,0x82,0x11,0x0F,0x00,0x00,0x89,
0x02,0x60,0x14,0x00,0x00,0x00,0x5C,
0x03,0x85,0x2C,0x02,0x00,0x00,0x9C,
0x04,0x23,0x16,0x00,0x00,0x00,0x23,
0x05,0x63,0x00,0x0F,0x00,0x00,0x5D,
0x06,0x0D,0x0C,0x00,0x00,0x00,0x05,
0x07,0xCF,0x1D,0x02,0x00,0x00,0xDB,
0x08,0x35,0x0B,0x00,0x00,0x00,0x2E,
0x09,0x2A,0x9C,0x0F,0x00,0x00,0xC4,
0x0A,0x74,0x0F,0x00,0x00,0x00,0x73,
0x0B,0x11,0x3C,0x02,0x00,0x00,0x40,
0x0C,0x81,0x0C,0x00,0x00,0x00,0x7F,
0x0D,0xD9,0x85,0x0F,0x00,0x00,0x60,
0x0E,0x8A,0x0C,0x00,0x00,0x00,0x8A,
0x0F,0xDE,0x2B,0x02,0x00,0x00,0x00,
0x10,0xC6,0x07,0x00,0x00,0x00,0xC3,
0x11,0xB5,0x01,0x01,0x00,0x00,0xAE,
0x12,0x0D,0x04,0x00,0x00,0x00,0x09,
0x13,0x28,0xB8,0x00,0x00,0x00,0xD9,
0x14,0x14,0x06,0x00,0x00,0x00,0x14,
0x15,0x3C,0x38,0x00,0x00,0x00,0x6F,
0x16,0x0A,0x26,0x00,0x00,0x00,0x2C,
0x17,0x57,0x1A,0x00,0x00,0x00,0x6E,
0x18,0x89,0x1A,0x00,0x00,0x00,0xA1,
0x1D,0xD0,0xEE,0x91,0x00,0x00,0x52,
0x1E,0x72,0x02,0x00,0x00,0x00,0x78,
0x1F,0x05,0x22,0x25,0x00,0x00,0x51,
0x20,0xAE,0x0C,0x00,0x00,0x00,0xC0,
0x0F,0x0A,0x6D,0x04,0x05,0x06,0x16};
*length = 216;
memcpy(revBuf, retData5, *length);
}
return 0;
*/
int ret;
ret = SendRequest(nPort, index, sendBuf);
if(ret == 1)
{
bCOMOpened = FALSE;
return 1;
}
Sleep(nSleep);
ret = ReceiveData(nPort, revBuf, length);
if(ret == 1)
{
bCOMOpened = FALSE;
return 2;
}
else if(ret == 2)
{
bCJQIsOk = FALSE;
return 3;
}
bCOMOpened = TRUE;
bCJQIsOk = TRUE;
return 0;
}
//功能:判断链路状态是否好
//发送,应答报文:
//问>10 49 4b fe 92 16 (询问链路状态,4b fe为设备地址device id,49+4b+fe=192,取92为和校验)
//回<10 0b 4b fe 54 16 (链路好)
//参数:
//retData 从串口接收到的数据
//返回值:
//0 链路状态好
//1 链路不通
int CMy102Class::NetworkIsOk(BYTE*retData)
{
if(retData[0]==0x10 && retData[1]==0x0B && retData[2]==0x4B &&
retData[3]==0xFE && retData[4]==0x54 && retData[5]==0x16)
{
bCJQIsOk = TRUE;
return 0;
}
else
{
bCJQIsOk = FALSE;
return 1;
}
}
//功能:判断复位是否成功
//发送,应答报文:
//问>10 40 4b fe 89 16 (复位链路,4b fe为设备地址device id,40+4b+fe=189,取89为和校验)
//回<10 00 4b fe 49 16 (链路复位成功,无class1数据)
//回<10 20 4b fe 69 16 (链路复位成功,有class1数据)
//参数:
//retData 从串口接收到的数据
//返回值:
//0 复位链路成功,有class1数据
//1 复位链路成功,无class1数据
//2 复位链路失败
int CMy102Class::RepositionIsSuccess(BYTE*retData)
{
if(retData[0]==0x10 && retData[1]==0x20 && retData[2]==0x4B &&
retData[3]==0xFE && retData[4]==0x69 && retData[5]==0x16)
{
bCJQIsOk = TRUE;
return 0;
}
else if(retData[0]==0x10 && retData[1]==0x00 && retData[2]==0x4B &&
retData[3]==0xFE && retData[4]==0x49 && retData[5]==0x16)
{
bCJQIsOk = TRUE;
return 1;
}
else
{
bCJQIsOk = FALSE;
return 2;
}
}
//功能:判断是否有class1数据
//发送,应答报文:
//问>68 0e 0e 68 73 4b fe 6a 01 06 4b fe 0c 00 09 5C 06 05 F2 16(问class1数据,73+4b+fe+6a+01+06+4b+fe+0c+ 00 + 09 + 5C + 06 + 05=3F2,取f2为和校验)
//回<10 00 4b fe 49 16 (无class1数据)
//回<10 20 4b fe 69 16 (有class1数据)
//参数:
//retData 从串口接收到的数据
//返回值:
//0 有class1数据
//1 无class1数据
//2 出错
int CMy102Class::HasClass1Data(BYTE*retData)
{
if(retData[0]==0x10 && retData[1]==0x20 && retData[2]==0x4B &&
retData[3]==0xFE && retData[4]==0x69 && retData[5]==0x16)
{
bCJQIsOk = TRUE;
return 0;
}
else if(retData[0]==0x10 && retData[1]==0x00 && retData[2]==0x4B &&
retData[3]==0xFE && retData[4]==0x49 && retData[5]==0x16)
{
bCJQIsOk = FALSE;
return 1;
}
else
{
bCJQIsOk = FALSE;
return 2;
}
}
//功能:判断问class1数据,是否对激活确认
//发送,应答报文:
//问>10 5a 4b fe a3 16(是否对激活确认,5a+4b+fe=1a3,取a3为和校验)
//回<68 0E 0E 68 28 4B FE 6A 01 07 4B FE 0C 28 11 53 0A 04 D2 16 (6A 01 07:对激活确认)
//参数:
//retData 从串口接收到的数据
//返回值:
//0 对激活确认
//1 出错
int CMy102Class::HasBeenActivated(BYTE*retData)
{
if(retData[3]==0x68 && retData[4]==0x28 && retData[5]==0x4B &&
retData[6]==0xFE && retData[7]==0x6A && retData[8]==0x01 &&
retData[9]==0x07 && retData[10]==0x4B && retData[11]==0xFE &&
retData[12]==0x0C)
{
bCJQIsOk = TRUE;
return 0;
}
else
{
bCJQIsOk = FALSE;
return 1;
}
}
//功能:判断问class1数据,是否传输终止
//发送,应答报文:
//问>10 5a 4b fe a3 16(是否传输终止,5a+4b+fe=1a3,取a3为和校验)
//问>10 7a 4b fe c3 16(是否传输终止,7a+4b+fe=1c3,取c3为和校验)
//回<68 0E 0E 68 08 4B FE 6A 01 0A 4B FE 0C 28 11 53 0A 04 B5 16(6A 01 0A:传输终止)
//参数:
//retData 从串口接收到的数据
//返回值:
//0 还有数据
//1 传输终止
//2 出错
int CMy102Class::TransfersFinished(BYTE*retData)
{
if(retData[3]==0x68 && retData[4]==0x28 && retData[5]==0x4B &&
retData[6]==0xFE && retData[7]==0x02 &&
retData[9]==0x05 && retData[10]==0x4B && retData[11]==0xFE &&
retData[12]==0x0C)
{
bCJQIsOk = TRUE;
return 0;
}
else if(retData[3]==0x68 && retData[4]==0x08 && retData[5]==0x4B &&
retData[6]==0xFE && retData[7]==0x6A && retData[8]==0x01 &&
retData[9]==0x0A && retData[10]==0x4B && retData[11]==0xFE &&
retData[12]==0x0C)
{
bCJQIsOk = TRUE;
return 1;
}
else
{
bCJQIsOk = FALSE;
return 2;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -