📄 scommtestdlg.cpp
字号:
CString ss;
ss.Format("%d,%s,%d,%d",9600,"N",8,1);
m_CtrlComm.SetSettings(ss);
m_ComCombo.SetCurSel(0);
m_BaudRateCombo.SetCurSel(1);
m_StopBitsCombo.SetCurSel(0);
m_ParityCombo.SetCurSel(0);
m_DataBitsCombo.SetCurSel(0);
}
//由于这个转换函数的格式限制,在发送框中的十六制字符应该每两个字符之间插入一个空隔
//如:A1 23 45 0B 00 29
//CByteArray是一个动态字节数组
int CSCommTestDlg::String2Hex(CString str,CByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen=0;
int len=str.GetLength();
senddata.SetSize(len/2);
for(int i=0;i<len;i++)
{
char lstr,hstr=str[i];
if(hstr==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
lstr=str[i];
hexdata=ConvertHexChar(hstr);
lowhexdata=ConvertHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else
hexdata=hexdata*16+lowhexdata;
i++;
senddata[hexdatalen]=(char)hexdata;
hexdatalen++;
}
senddata.SetSize(hexdatalen);
return hexdatalen;
}
char CSCommTestDlg::ConvertHexChar(char ch)
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
return ch-'A'+10;
else if((ch>='a')&&(ch<='f'))
return ch-'a'+10;
else return (-1);
}
void CSCommTestDlg::OnClearRecord()
{
// TODO: Add your control notification handler code here
m_ClearRecord.SetSel(0,m_ClearRecord.GetLimitText(),FALSE);
m_ClearRecord.Clear();
m_StrRXData.Empty();//清空
UpdateData(FALSE);
}
void CSCommTestDlg::PLC2PCDataHandle()
{
//创建内存映射文件;
//串行口这一块的进程的映射文件,并非主进程的内存映射文件
HANDLE hmemoshare;
ControlData* lpcontroldata;
hmemoshare=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,
PAGE_READWRITE,0,0x1000,"ControlDataFile");
if(hmemoshare==NULL)
{
MessageBox("创建内存映射文件失败");
}
lpcontroldata=(ControlData*)MapViewOfFile(hmemoshare,FILE_MAP_ALL_ACCESS,0,0,0);
if(lpcontroldata==NULL)
{
MessageBox("创建内存映射文件视图失败");
}
//前3步检查收到的数据放到ConvetData()中去了;
//4、提炼命令中的速度值
CString strspeed;
int nspeed;
strspeed=Binary2Decimal(m_strDataDemand.Right(4));// Changing to (str)decimal
nspeed=atoi(strspeed.GetBuffer(0)); //changing from strdecimal to int decimal
//以后具体程序再改具体速度!!!
switch(nspeed)
{
case 0:
lpcontroldata->RXData.fSpeed=0;
break;
case 1:
lpcontroldata->RXData.fSpeed=101;
break;
case 2:
lpcontroldata->RXData.fSpeed=102;
break;
case 3:
lpcontroldata->RXData.fSpeed=103;
break;
case 4:
lpcontroldata->RXData.fSpeed=104;
break;
case 5:
lpcontroldata->RXData.fSpeed=105;
break;
case 6:
lpcontroldata->RXData.fSpeed=106;
break;
case 7:
lpcontroldata->RXData.fSpeed=107;
break;
case 8:
lpcontroldata->RXData.fSpeed=108;
break;
case 9:
lpcontroldata->RXData.fSpeed=109;
break;
case 10:
lpcontroldata->RXData.fSpeed=110;
break;
case 11:
lpcontroldata->RXData.fSpeed=111;
break;
case 12:
lpcontroldata->RXData.fSpeed=112;
break;
case 13:
lpcontroldata->RXData.fSpeed=113;
break;
case 14:
lpcontroldata->RXData.fSpeed=114;
break;
case 15:
lpcontroldata->RXData.fSpeed=115;
break;
default:
lpcontroldata->RXData.fSpeed=116;
break;
}
CString temps21;
temps21.Format("%f",lpcontroldata->RXData.fSpeed);
//5、最后开始把数据写进内存映射文件
CString temps22,temps23;
temps22.Format("%s",m_strDataDemand.Left(1));
int itemps22=atoi(Binary2Decimal(temps22).GetBuffer(0));
lpcontroldata->RXData.bShutterOpen=itemps22;//m_strDataDemand[7];
temps23.Format("%s",m_strDataDemand.Mid(1,1));
int itemps23=atoi(Binary2Decimal(temps23).GetBuffer(0));
lpcontroldata->RXData.bDataError=itemps23;//m_strDataDemand[6];
lpcontroldata->RXData.bNewData=1;//表明有新数据收到,让主程序取
m_ControlData.RXData.bDataError=lpcontroldata->RXData.bDataError;
m_ControlData.RXData.bNewData=lpcontroldata->RXData.bNewData;
m_ControlData.RXData.bShutterOpen=lpcontroldata->RXData.bShutterOpen;
m_ControlData.RXData.fSpeed=lpcontroldata->RXData.fSpeed;
//m_ControlData.RXData=lpcontroldata->RXData;
//7、更新内存映射文件
UnmapViewOfFile(lpcontroldata);
m_RXDataFlag=false;
}
void CSCommTestDlg::PC2PLCDataHandle(ControlData* lpcontroldata)
{
//1、先打开一个内存映射文件,获得指针,读出数据
//已放在ReadMemoryFile中处理;
//******************************************************************
//待会搬到PLC2PCDataControl末尾中去,因为调程序用,因为数据还没准备好
//******************************************************************
//lpcontroldata->SXData=m_ControlData.SXData;//initializing
CString strSXDataLength,strSXDataDemand;
CString temps61;
temps61.Format("%d",lpcontroldata->SXData.nCTCount);
//2、把数值先赋给m_strData系列
//m_strDataDemand:命令字节
CString temps14,temps15,temps16,temps161;//temps14="000000000";
temps14=Byte2CString(lpcontroldata->SXData.bShutterOpen);//00000000或者00000001
if(lpcontroldata->SXData.nCTCount!=0)
temps15="1";// 表示有点传输(CString)Byte 01000000
else
temps15="0";
if(lpcontroldata->SXData.nCTCount>0)
temps161.Format("%d",lpcontroldata->SXData.nCTCount-1);//注意:这里是0000代表1个CT点//1111--〉16
else
temps16="00000000";
temps16=ChangetoByteLength(Decimal2Binary(temps161),8);//nCTCount是BYTE型,取后4位
strSXDataDemand=temps14.Right(1)+temps15+"0"+"0"+temps16.Right(4);
//***********************************************
//m_SXDataAgain要求对方重发的命令,那我在发新数据时,
//就没有必要要求对方重发了。故一直为零
//***********************************************
CString temps17,temps18[20];
//*************************************
//为了Mid(),一定要赋初值
//************************************
for(int n=0;n<20;n++)
temps18[n]="00000000000000000000000000000000";//
if(lpcontroldata->SXData.nCTCount>16)
{
lpcontroldata->SXData.nCTCount=16;
}
int ncheck11;
CString temps51,temps52;
ncheck11=
atoi(Binary2Decimal("00000011").GetBuffer(0))
^atoi(Binary2Decimal(strSXDataDemand).GetBuffer(0));//首先转换成CString的int型--〉int
temps51.Format("%d",ncheck11);
temps52=ChangetoByteLength(Decimal2Binary(temps51),8);
//**************************************************************************************
//**************************************************************************************
//注意:最后nCTPos[]需要换算,刘老师是以什么单位存的,还需要换算成0.1mm单位的数据,才能用
//**************************************************************************************
//**************************************************************************************
CString temps180;
//得到nCTCount为0的命令串;//因为只发3个字节
if(lpcontroldata->SXData.nCTCount==0)
m_SXDataAgainByte="00000011"+strSXDataDemand+temps52;
//换算nCTPos[];
for(int i=0;i<lpcontroldata->SXData.nCTCount;i++)//为零就不执行这个循环了
{
// First,把(DWORD)nCTPos[i]转换成CString
temps17.Format("%d",lpcontroldata->SXData.nCTPos[i]);// Changing to (CString)int;
temps18[i]=Decimal2Binary(temps17);// Changing to (CString)Binary
temps18[i]=ChangetoByteLength(temps18[i],32);// Changing to 32bits data;
temps180.Format("%s\n长度为:%d",temps18[i],temps18[i].GetLength());
}
//strSXDataLength:7个字节?非也,有几个CT点,是一次性发!!!!!!!!
CString temps100;
temps100.Format("%d",lpcontroldata->SXData.nCTCount*4+3);//总共的字节数;
strSXDataLength=Decimal2Binary(temps100);//转换成二进制
strSXDataLength=ChangetoByteLength(strSXDataLength,8);//补齐8bits
//m_strDataChecksum:校验和
CString temps19,temps20;
int check1[20],checksum=0;
//先计算各个CT点*内*的校验和,放在check[20]里,再计算CT点*间*的校验和-->checksum;
for(int l=0;l<lpcontroldata->SXData.nCTCount;l++)
{
check1[l]=
atoi(Binary2Decimal(temps18[l].Left(8)).GetBuffer(0))
^atoi(Binary2Decimal(temps18[l].Mid(8,8)).GetBuffer(0))
^atoi(Binary2Decimal(temps18[l].Mid(16,8)).GetBuffer(0))
^atoi(Binary2Decimal(temps18[l].Right(8)).GetBuffer(0));
checksum=checksum^check1[l];
}
//得到最后的校验和---〉temps20
int check=atoi(Binary2Decimal(strSXDataLength).GetBuffer(0))
^atoi(Binary2Decimal(strSXDataDemand).GetBuffer(0))
^checksum;
temps19.Format("%d",check);//int--->(CString)int
temps19=Decimal2Binary(temps19);// Changing to (CString)Binary
temps20=ChangetoByteLength(temps19,8);//supplement bit up to 8 bits;
//计算有CT点时的命令字符串;
CString strtemp102,strtemp101;
strtemp102="";
for(int g=0;g<lpcontroldata->SXData.nCTCount;g++)
strtemp102=strtemp102+temps18[g];//先组合命令串
strtemp101=strSXDataLength+strSXDataDemand+strtemp102+temps20;
//3、最后组合成一个字符串数据,准备好了数据,一次性发!!!!!!!!!
if(lpcontroldata->SXData.nCTCount==0)
m_CtrlComm.SetOutput(COleVariant(m_SXDataAgainByte));
else
m_CtrlComm.SetOutput(COleVariant(strtemp101));
//4、取完数据,必须最后重新置零!!!***************
lpcontroldata->SXData.bNewData=0;
//5、保持本地的变量指针与内存映射文件的指针一致
m_ControlData.SXData=lpcontroldata->SXData;
//6、更新内存映射文件
UnmapViewOfFile(lpcontroldata);
}
//函数:二进制转换到十进制
CString CSCommTestDlg::Binary2Decimal(CString strBinary)
{
int nLength=strBinary.GetLength();
char* Binary=new char[nLength];
Binary=strBinary.GetBuffer(0);
int nDecimal=0;
for(int i=0;i<nLength;i++)
{
char h=Binary[nLength-1-i];
char str[1];
str[0]=h;
int j=atoi(str);
for(int k=0;k<i;k++)
{
j=j*2;
}
nDecimal+=j;
}
CString strDecimal;
strDecimal.Format("%d",nDecimal);
return strDecimal;
}
//函数:从十进制转换到二进制
CString CSCommTestDlg::Decimal2Binary(CString strDecimal)
{
int nDecimal=atoi(strDecimal.GetBuffer(0));
int nYushu;//余数
int nShang;//商
CString strBinary="";
char buff[2];
CString str="";
BOOL bContinue=TRUE;
while(bContinue)
{
nYushu=nDecimal%2;
nShang=nDecimal/2;
sprintf(buff,"%d",nYushu);
str=strBinary;
strBinary.Format("%s%s",buff,str);
nDecimal=nShang;
if(nShang==0)
bContinue=FALSE;
}
return strBinary;
}
//把二进制数增长到字节长度;
CString CSCommTestDlg::ChangetoByteLength(CString str,int nLength)
{
int nstrLength;
nstrLength=str.GetLength();
if(nLength<nstrLength)
MessageBox("数据有误,超出字节的长度");
else
for (int i=0; i<nLength-nstrLength;i++)
{
str="0"+str;
}
return(str);
}
//将比特类型转换到CString类型;
CString CSCommTestDlg::Byte2CString(BYTE bt)
{
CString str1,str2;
str1.Format("%d",bt);// First changing to (CString)int type
str1=Decimal2Binary(str1);// Second changing to (CString)Binary type;
str2=ChangetoByteLength(str1,8);// Third changing to the length of a Byte
return(str2);
}
//将数据流分割成相应的字节
void CSCommTestDlg::ConvertData()
{
if(m_StrRXData1=="")
{
m_RXDataFlag=false;
}
else
{
m_strDataLength=m_StrRXData1.Left(8);
m_strDataDemand=m_StrRXData1.Mid(8,8);
m_strDataChecksum=m_StrRXData1.Right(8);
}
}
//对接收到的数据进行检查
void CSCommTestDlg::CheckRXData()
{
CString CheckChar;
int count=0;
int bitscount=0;
count=m_StrRXData1.GetLength();
//1、验证长度;
if(m_StrRXData1.GetLength()!=8&&m_StrRXData1.GetLength()!=16&&m_StrRXData1.GetLength()!=24)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -