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

📄 scommtestdlg.cpp

📁 非常实用的串口通信程序 并且在中间使用了托盘技术 (站长,源程序个数怎么计算啊,其实这里面含有两个源程序,一个是串口通信,一个是托盘程序 )
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -