📄 porttrans.cpp
字号:
// ComTrans.cpp: implementation of the CPortTrans class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PortTrans.h"
#include "stdio.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPortTrans ::CPortTrans ()
{
m_bOpenFlag = false;
m_iComName = 2;
m_iBaudRate = 9600;
m_iParity = 2;
m_iByteSize = 7;
m_iStopBits = 0;
m_iTimeCount = 5;
m_pEQData = "";
m_iEquipmentAddress = 0;
m_fEQcommdata = 0.00;
m_fSVData = 0.00;
m_fPVData = 0.00;
m_iErrorNumber = 0;
memset(m_pErrorData,0,sizeof(m_pErrorData));
strcpy(m_pErrorData,"正常");
}
CPortTrans ::~CPortTrans ()
{
}
float CPortTrans ::GetEquipmentData()
{
//返回设备通用数据
return m_fEQcommdata;
}
float CPortTrans ::GetSVData()
{
//返回SV数据
return m_fSVData ;
}
float CPortTrans ::GetPVData()
{
//返回PV数据
return m_fPVData ;
}
char * CPortTrans ::GetLastErrorText()
{
//返回错误代码
return m_pErrorData;
}
/*
思路:转换地址-构造命令-操作串口
*/
bool CPortTrans ::SendGetSVCommand(const int EquipmentAddress)
{
//转换串口地址
m_iEquipmentAddress = EquipmentAddress;
char * strAddress = ConvertAdress(EquipmentAddress);
//构造串口命令
char strCommand [64];
memset(strCommand,0,sizeof(strCommand));
strcpy(strCommand,"\x04");
strcat(strCommand,strAddress);
strcat(strCommand,"\x53\x4c\x05");
//操作串口
if (OperateCom(strCommand))
{
//整理采集到的数据
if (CheckComData(false,EquipmentAddress))
{
m_fSVData = TransGetData();
return true;
}
else
{
//进行错误处理
memset(strCommand,0,sizeof(strCommand));
strcpy(strCommand,"获取sv失败");
SetErrorData(DATA_GET_ERROR,strCommand,EquipmentAddress);
return false;
}
}
return false;
}
/*
思路:转换地址-构造命令-操作串口
*/
bool CPortTrans ::SendGetPVCommand(const int EquipmentAddress)
{
//转换串口地址
m_iEquipmentAddress = EquipmentAddress;
char * strAddress = ConvertAdress(EquipmentAddress);
//构造串口命令
char strCommand [64];
memset(strCommand,0,sizeof(strCommand));
strcpy(strCommand,"\x04");
strcat(strCommand,strAddress);
strcat(strCommand,"\x50\x56\x05");
//操作串口
if (OperateCom(strCommand))
{
if (CheckComData(false,EquipmentAddress))
{
m_fPVData = TransGetData();
return true;
}
else
{
//出错处理
memset(strCommand,0,sizeof(strCommand));
strcpy(strCommand,"获取pv失败");
SetErrorData(DATA_GET_ERROR,strCommand,EquipmentAddress);
return false;
}
}
return false;
}
/*
思路:转换地址-构造命令-操作串口
*/
bool CPortTrans ::SetEquipmentData(const int EquipmentAddress, const int Pro, const int Setvalue)
{
//临时字符串,用于计算ETX
char pB[15];
memset(pB,0,sizeof(pB));
//转换地址
m_iEquipmentAddress = EquipmentAddress;
char strAddress[10];
memset(strAddress,0,sizeof(strAddress));
strcpy(strAddress,ConvertAdress(EquipmentAddress ));
//转换设定值
char * strData = ConvertData(Setvalue);
//构造串口命令
//尾部
char strCommend[1];
//头部
char * strCommandStart = "\x04";
//命令字符串
char strLinkCommand[64];
//命令
char *strCommand;
//命令名
char *strCommandName;
//根据Pro选择属性字符串
switch(Pro) {
case 0:
//设定值
strCommand = "\x53\x4C";
strCommandName = "设定值";
break;
case 1:
//al1报警值
strCommand ="\x48\x41";
strCommandName = "al1报警值";
break;
case 2:
//al2报警值
strCommand = "\x4c\x41";
strCommandName = "al2报警值";
break;
default:
//没有符合条件命令
SetErrorData(DATA_SET_ERROR,"没有找到设置命令",EquipmentAddress);
return false;
}
//构造串口命令
memset(strLinkCommand,0,sizeof(strLinkCommand));
strcpy(strLinkCommand,strCommandStart);
strcat(strLinkCommand,strAddress);
strcat(strLinkCommand,"\x02");
//
strcpy(pB,strCommand);
strcat(pB,strData);
strcat(pB,"\x03");
//
memset(strCommend,0,sizeof(strCommend));
sprintf(strCommend,"%c",GetBCC(pB,strlen(pB)));
//
strcat(strLinkCommand,pB);
strcat(strLinkCommand,strCommend);
//操作串口
if (OperateCom(strLinkCommand,true))
{
//判断是否操作成功
if (CheckComData(true,EquipmentAddress)) return true;
else
{
//错误处理
memset(strLinkCommand,0,sizeof(strLinkCommand));
strcpy(strLinkCommand,"设置设备");
strcat(strLinkCommand,strCommandName);
strcat(strLinkCommand,"失败");
SetErrorData(DATA_SET_ERROR,strLinkCommand,EquipmentAddress);
}
}
return false;
}
/*
思路:转换地址-构造命令-操作串口
*/
bool CPortTrans ::SendEquipmentCommand(const int EquipmentAddress, const int CommandID)
{
//转换地址信息
m_iEquipmentAddress = EquipmentAddress;
char * strAddress=ConvertAdress(EquipmentAddress );
//尾部
char * strCommend= "\x05";
//头部
char * strCommandStart = "\x04";
//合成的命令字符串
char strLinkCommand[64];
//命令
char * strCommand;
//命令名称
char *strCommandName;
//根据CommandID选择命令字符串
switch(CommandID) {
case 0:
//温度
strCommand = "\x50\x56";
strCommandName = "当前温度";
break;
case 1:
//设定值
strCommand= "\x53\x4c";
strCommandName = "当前设定值";
break;
case 2:
//输出功率
strCommand = "\x4f\x50";
strCommandName = "输出功率";
break;
case 3:
//al1报警值
strCommand = "\x48\x41";
strCommandName = "al1报警值";
break;
case 4:
//al2报警值
strCommand = "\x4c\x41";
strCommandName = "al2报警值";
break;
default:
SetErrorData(DATA_GET_ERROR,"没有找到设备命令",EquipmentAddress);
return false;
}
//构造串口命令
memset(strLinkCommand,0,sizeof(strLinkCommand));
strcpy(strLinkCommand,strCommandStart);
strcat(strLinkCommand,strAddress);
strcat(strLinkCommand,strCommand);
strcat(strLinkCommand,strCommend);
//操作串口
if (OperateCom(strLinkCommand))
{
if (CheckComData(false,EquipmentAddress))
{
m_fEQcommdata = TransGetData();
return true;
}
else
{
//错误处理
memset(strLinkCommand,0,sizeof(strLinkCommand));
strcpy(strLinkCommand,"获取设备");
strcat(strLinkCommand,strCommandName);
strcat(strLinkCommand,"失败");
SetErrorData(DATA_GET_ERROR,strLinkCommand,EquipmentAddress);
return false;
}
}
return false;
}
int CPortTrans ::GetComSet(const int Pro)
{
int iReturn;
//根据Pro选择相应的串口属性
switch(Pro)
{
//进行数据类型转换。但是没有找到库文件
case 0 :
//串口名
iReturn = m_iComName ;
break;
case 1 :
//波特率
iReturn = m_iBaudRate;
break;
case 2 :
//数据宽度
iReturn = m_iByteSize;
break;
case 3:
//奇偶校验
iReturn = m_iParity ;
break;
case 4:
//停止位
iReturn = m_iStopBits;
break;
default:
SetErrorData(COM_GET_ERROR,"没有找到串口属性");
iReturn = -100;
}
return iReturn ;
}
bool CPortTrans ::SetCom(const int Pro, int Value)
{
//根据Pro选择相应的设置属性
switch(Pro)
{
case 0 :
//串口名
m_iComName =Value;
break;
case 1 :
//波特率
m_iBaudRate = Value;
break;
case 2 :
//数据宽度
m_iByteSize = Value;
break;
case 3:
//奇偶校验
m_iParity = Value;
break;
case 4:
//停止位
m_iStopBits = Value;
break;
default:
SetErrorData(COM_SET_ERROR,"没有找到串口属性");
return false;
}
return OpenCom();
}
bool CPortTrans ::CloseCom()
{
bool Flag = CloseHandle(m_Handle);
if (Flag)
m_bOpenFlag = false;
else
SetErrorData(COM_SET_ERROR,"com口关闭错误");
return Flag;
}
bool CPortTrans ::OpenCom()
{
//如果串口已经打开,先关闭
if (m_bOpenFlag) CloseCom();
//转换串口名
char Comnamebuffer[6];
char Numberbuffer[2];
char *name = "com";
memset(Comnamebuffer,0,sizeof(Comnamebuffer));
memset(Numberbuffer,0,sizeof(Numberbuffer));
itoa(m_iComName,Numberbuffer,10);
strcpy(Comnamebuffer,name);
strcat(Comnamebuffer,Numberbuffer);
//设置参数
COMMTIMEOUTS timeouts = { // 串口超时控制参数
100, // 读字符间隔超时时间: 100 ms
1, // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
500, // 基本的(额外的)读超时时间: 500 ms
1, // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
100}; // 基本的(额外的)写超时时间: 100 ms
//打开串口
m_Handle = CreateFile(Comnamebuffer, // 串口名称或设备路径
GENERIC_READ | GENERIC_WRITE, // 读写方式
0, // 共享方式:独占
NULL, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 异步通信
NULL); // 不需参照模板文件
if(m_Handle == INVALID_HANDLE_VALUE)
{
SetErrorData(COM_SET_ERROR,"串口初始化失败");
m_bOpenFlag = false;
return FALSE;
}// 打开串口失败
//设置串口属性
GetCommState(m_Handle, &m_Dcb); // 取DCB
m_Dcb.BaudRate = m_iBaudRate;
m_Dcb.ByteSize = m_iByteSize;
m_Dcb.Parity = m_iParity;
m_Dcb.StopBits = m_iStopBits;
if(!SetCommState(m_Handle, &m_Dcb))
{
SetErrorData(COM_SET_ERROR,"串口设置失败,请检查串口参数");
return false;
}// 设置DCB
GetCommState(m_Handle, &m_Dcb);
SetupComm(m_Handle, 4096, 1024); // 设置输入输出缓冲区大小
SetCommTimeouts(m_Handle, &timeouts); // 设置超时
m_bOpenFlag = true;
return TRUE;
}
bool CPortTrans ::InitComExt(int nCom, int nBaudRate, int nParity,
int nByteSize, int nStopBits,int nTimeout)
{
//设置串口
m_iComName = nCom;
//设置波特率
m_iBaudRate = nBaudRate;
//设置奇偶校验
m_iParity = nParity ;
//设置数据宽度
m_iByteSize = nByteSize ;
//设置停止位
m_iStopBits = nStopBits ;
//设置连接超时时间
m_iTimeCount = nTimeout;
return OpenCom();
}
void CPortTrans ::WritToCom(char *pData, int nLength)
{
// 串口发出的数据长度
DWORD dwNumWrite;
WriteFile(m_Handle, pData, (DWORD)nLength, &dwNumWrite, NULL);
}
void CPortTrans ::ReadFromCom(char *pData, int nLength)
{
// 串口收到的数据长度
DWORD dwNumRead;
ReadFile(m_Handle, pData, (DWORD)nLength, &dwNumRead, NULL);
}
/*
思路与算法:
定义两个字符串和两个个int变量,用来存储转换后的十位和个位
*/
char * CPortTrans ::ConvertAdress(int address)
{
//转换用数据,转换设备地址,
char sShiwei[10],sGewei[10],sData[30];
int iShiwei,iGewei;
//转换算法
//如果地址是0
if (address ==0)
{
itoa(0,sShiwei,10);
itoa(0,sGewei,10);
}
else
{
//取address的十位
iShiwei = address/10;
//将十位转换成字符
itoa(iShiwei,sShiwei,10);
//取address的个位
iGewei = address%10;
//将个位转换成字符
itoa(iGewei,sGewei,10);
}
//构造命令用字符串
memset(sData,0,sizeof(sData));
//十位重复复制
strcpy(sData,sShiwei);
strcat(sData,sShiwei);
//个位重复复制
strcat(sData,sGewei);
strcat(sData,sGewei);
//返回地址
return sData;
}
char * CPortTrans ::ConvertData(long data)
{
char pData[20];
memset(pData,0,sizeof(pData));
sprintf(pData,"%d",data);
return pData;
}
bool CPortTrans::CheckComData(bool bCheckSet,int nEquipmentAddress)
{
//判断设置是否成功 06h为成功,其他为失败
if (bCheckSet)
{
if (strcmp(m_pEQData,"\x06") ==0)
return true;
else
if (strcmp(m_pEQData,"\x15") == 0)
SetErrorData(DATA_SET_ERROR,"设置设备属性错误",nEquipmentAddress);
return false;
}
//判断数据是否有效,
//负数判断为字符串' - '
//进行bcc校验
char pTempBuffer[15];
memset(pTempBuffer,0,sizeof(pTempBuffer));
strncpy(pTempBuffer,(m_pEQData+1),8);
char a = m_pEQData[9];
int ct = strlen(m_pEQData);
if(GetBCC(pTempBuffer,strlen(pTempBuffer))!=a)
{
SetErrorData(DATA_GET_ERROR,"数据校验错误",nEquipmentAddress);
return false;
}
//
for (int i = 3;i<8;i++)
{
//如果是空格 . 和-负号就不做判断
if (m_pEQData[i]== ' '||m_pEQData[i]== '.'||m_pEQData[i]== '-')continue;
//判断是否十0-9
if (m_pEQData[i]<48||m_pEQData[i]>57)
return false;
}
return true;
}
float CPortTrans::TransGetData()
{
//根据type转换得到的设备数据
char pData[6];
memset(pData,0,sizeof(pData));
strncpy(pData,(m_pEQData+3),5);
return atof(pData);
}
bool CPortTrans::OperateCom(char *pstrCommand,bool bSetFlag)
{
//读写串口 ,判断连接情况
int iTemp = m_iTimeCount;
memset(m_pBuffer,0,sizeof(m_pBuffer));
WritToCom(pstrCommand,strlen(pstrCommand));
Sleep(10);
ReadFromCom (m_pBuffer,sizeof(m_pBuffer));
//如果没有数据返回,测试连接
while (strcmp(m_pBuffer,"")==0)
{
if (m_iTimeCount == 0)
{
SetErrorData(COM_LINK_ERROR,"没有数据返回,连接超时,请检查网络,");
return false;
}
else
{
WritToCom(pstrCommand,strlen(pstrCommand));
Sleep(10);
ReadFromCom (m_pBuffer,sizeof(m_pBuffer));
m_iTimeCount --;
continue;
}
}
m_iTimeCount = iTemp;
m_pEQData = m_pBuffer;
return true;
}
int CPortTrans::GetLastErrorNumber()
{
return m_iErrorNumber;
}
void CPortTrans::SetErrorData(int ErrorNumber, char *ErrorString,int EquipmentAddress)
{
//临时变量用来存储转换后的数据
char strEnumber[5];
//构造错误字符串
memset(strEnumber,0,sizeof(strEnumber));
memset(m_pErrorData,0,sizeof(m_pErrorData));
strcpy(m_pErrorData,"\n串口错误: ");
strcat(m_pErrorData,ErrorString);
strcat(m_pErrorData,"\n机器地址: ");
sprintf(strEnumber,"%d",EquipmentAddress);
strcat(m_pErrorData,strEnumber);
m_iErrorNumber = ErrorNumber;
}
bool CPortTrans::GetComState()
{
return m_bOpenFlag;
}
char CPortTrans::GetBCC(char *pchars, int nLenth)
{
char tempchar = pchars[0];
for (int i = 0;i<nLenth-1;i++)
{
tempchar = tempchar^pchars[i+1];
}
return tempchar;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -