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

📄 serialporttestdlg.cpp

📁 基于VC++的,多个串口的,带通讯协议的应用程序,两个通讯口,可分别接受,发送协议数据包.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					{
						m_strPortRXData2.Empty();
					}
					else  //校验计算正确则处理数据
					{
						CString strSwitchSetData;
						strSwitchSetData = m_strPortRXData2.Mid(1,9);
						//以下设置信号灯状态
						for(int i=0;i<9;i++)
						{
							if(strSwitchSetData.Mid(i,1)=="1")
								SetSwitchStatus(i+1,TRUE);
							else
								SetSwitchStatus(i+1,FALSE);
						}
						//以下取出位置与速度数据
						CString strTemp;
						strTemp = m_strPortRXData2.Mid(10,5);
						char *temp=(char*)((LPCTSTR)strTemp);
						char tbuf[4];
						tbuf[0]=temp[0]; tbuf[1]=temp[1]; tbuf[2]=0;
						m_unEditPosition2 = atoi(tbuf);  //得到位置状态值
						tbuf[0]=temp[2]; tbuf[1]=temp[3]; 
						tbuf[2]=temp[4]; tbuf[3]=0;
						m_unEditVelocity2 = atoi(tbuf);  //得到速度值
						//将接收到的数据包内容显示
						m_strEditDispData2 = "接收到NMEA数据包:"+m_strPortRXData2;
						//下面准备发送"简单自定义通信协议"数据包
						unsigned char ucChar[4];
						//首字节
						ucChar[0]=0x80;   //首字节最高位置1
						if(strSwitchSetData.Mid(0,1)=="1")  // 开关1状态
							ucChar[0] |= 0x40;            //0100 0000 
						else
							ucChar[0] &= 0xBF;	          //1011 1111				
						if(strSwitchSetData.Mid(1,1)=="1")  // 开关2状态
							ucChar[0] |= 0x20;            //0010 0000 
						else
							ucChar[0] &= 0xDF;	          //1101 1111
						if(m_unEditPosition2>31)      //对位置值进行限值
							m_unEditPosition2=31;
						ucChar[0] &= 0xE0;    //将首字节的低5位置0
						ucChar[0] += m_unEditPosition2; //再加上位置值
						ucChar[3] = ucChar[0];    //同时计算校验值
						//第二字节
						unsigned char ucTemp=0x40;
						for(i=0; i<7; i++)
						{
							if(strSwitchSetData.Mid(2+i,1)=="1")  
								ucChar[1] |= ucTemp;             
							else
								ucChar[1] &= (~ucTemp);
							ucTemp >>= 1;
						}
						ucChar[1] &= 0x7F; //前面做了那么多运算,用这条语句保证一下最高位为0
						ucChar[3] ^= ucChar[1];   //计算校验值
						//第三字节
						if(m_unEditVelocity2>120)
							m_unEditVelocity2=120;
						ucChar[2] = m_unEditVelocity2;
						ucChar[3] ^= ucChar[2];   //计算校验值
						//第四字节
						ucChar[3] &= 0x7F;
						//把"简单自定义通信协议"数据包发送出去
						if(m_bSerialPortOpened2)
							m_SerialPort2.WriteToPort(ucChar,4);
						//同时把发送的内容显示
						CString strTemp1;
						strTemp=   _T("发送的内容为: ");
						for(int j=0;j<4;j++)
						{
							strTemp1.Format("0x%02X",ucChar[j]);
							strTemp +=  strTemp1 + ",";
						}
						m_strEditDispData2 += strTemp;
					
						UpdateData(FALSE);
					}
					m_strChecksum2.Empty();
				}
				//从'*'后收,flag=2,1次减1操作,正好将数据包的校验值保存在m_strChecksum中
				flag--;  
			}
			else
				checksum=checksum^ch;  //当flag<=0时,计算校验值
			break;
		}
	}

	return 0;
}

void CSerialPortTestDlg::OnButtonOpen() 
{
	// TODO: Add your control notification handler code here
	int nPort=m_ctrlComboComPort.GetCurSel()+1; //得到串口号,想想为什么要加1
	if(m_SerialPort.InitPort(this, nPort, 9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
	{
		m_SerialPort.StartMonitoring();
		m_bSerialPortOpened=TRUE;
		m_unPort=nPort;
	}
	else
	{
		AfxMessageBox("没有发现此串口或被占用");
		m_bSerialPortOpened=FALSE;
	}
	GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bSerialPortOpened);
	GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_bSerialPortOpened);
}

void CSerialPortTestDlg::OnButtonClose() 
{
	// TODO: Add your control notification handler code here
	m_SerialPort.ClosePort();//关闭串口
    m_bSerialPortOpened=FALSE;
	GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bSerialPortOpened);
	GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_bSerialPortOpened);	
}

void CSerialPortTestDlg::OnButtonSend() 
{
	// TODO: Add your control notification handler code here
	if(!m_bSerialPortOpened) //检查串口是否打开
	{
		AfxMessageBox("串口没有打开");
		return; 
	}
	UpdateData(TRUE); //读入编辑框中的数据
	CString strSend=""; //要发送的NEMA字符串
	//以下读入9个开关的设置状态
	for(int i=1;i<=9;i++)
	{
		if(GetSwitchStatus(i))
			strSend+='1';
		else
			strSend+='0';
	}
	CString strTemp;
	strTemp.Format("%02d",m_unEditPosition);
	strSend+=strTemp;
	strTemp.Format("%03d",m_unEditVelocity);
	strSend+=strTemp;
	SendNMEAData(strSend);
}


//该函数用于设置开关的信号灯状态,如开关5开启,
//可设置为 SetSwitchStatus(5,TRUE);
void CSerialPortTestDlg::SetSwitchStatus(UINT unSwtich,BOOL bStatus)
{
	if(bStatus)
	{
		switch(unSwtich) {
		case 1: 
			m_ctrlStaticIconS1.SetIcon(m_hIconRed);
			break;
		case 2: 
			m_ctrlStaticIconS2.SetIcon(m_hIconRed);
			break;
		case 3: 
			m_ctrlStaticIconS3.SetIcon(m_hIconRed);
			break;
		case 4: 
			m_ctrlStaticIconS4.SetIcon(m_hIconRed);
			break;
		case 5: 
			m_ctrlStaticIconS5.SetIcon(m_hIconRed);
			break;
		case 6: 
			m_ctrlStaticIconS6.SetIcon(m_hIconRed);
			break;
		case 7: 
			m_ctrlStaticIconS7.SetIcon(m_hIconRed);
			break;
		case 8: 
			m_ctrlStaticIconS8.SetIcon(m_hIconRed);
			break;
		case 9: 
			m_ctrlStaticIconS9.SetIcon(m_hIconRed);
			break;
		default:
			break;
		}
	}
	else
	{
		switch(unSwtich) {
		case 1: 
			m_ctrlStaticIconS1.SetIcon(m_hIconOff);
			break;
		case 2: 
			m_ctrlStaticIconS2.SetIcon(m_hIconOff);
			break;
		case 3: 
			m_ctrlStaticIconS3.SetIcon(m_hIconOff);
			break;
		case 4: 
			m_ctrlStaticIconS4.SetIcon(m_hIconOff);
			break;
		case 5: 
			m_ctrlStaticIconS5.SetIcon(m_hIconOff);
			break;
		case 6: 
			m_ctrlStaticIconS6.SetIcon(m_hIconOff);
			break;
		case 7: 
			m_ctrlStaticIconS7.SetIcon(m_hIconOff);
			break;
		case 8: 
			m_ctrlStaticIconS8.SetIcon(m_hIconOff);
			break;
		case 9: 
			m_ctrlStaticIconS9.SetIcon(m_hIconOff);
			break;
		default:
			break;
		}
	}
}


//该函数用于得到设置的开关状态值
BOOL CSerialPortTestDlg::GetSwitchStatus(UINT unSwitch)
{
	BOOL bStatus=FALSE;
	switch(unSwitch) {
	case 1:
		bStatus = m_ctrlCheckSwitch1.GetCheck();
		break;
	case 2:
		bStatus = m_ctrlCheckSwitch2.GetCheck();
		break;
	case 3:
		bStatus = m_ctrlCheckSwitch3.GetCheck();
		break;
	case 4:
		bStatus = m_ctrlCheckSwitch4.GetCheck();
		break;
	case 5:
		bStatus = m_ctrlCheckSwitch5.GetCheck();
		break;
	case 6:
		bStatus = m_ctrlCheckSwitch6.GetCheck();
		break;
	case 7:
		bStatus = m_ctrlCheckSwitch7.GetCheck();
		break;
	case 8:
		bStatus = m_ctrlCheckSwitch8.GetCheck();
		break;
	case 9:
		bStatus = m_ctrlCheckSwitch9.GetCheck();
		break;
	default:
		break;
	}
	return bStatus;
}

void CSerialPortTestDlg::OnButtonOpen2() 
{
	// TODO: Add your control notification handler code here
	int nPort=m_ctrlComboComPort2.GetCurSel()+1; //得到串口号
	if(m_SerialPort2.InitPort(this, nPort, 9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
	{
		m_SerialPort2.StartMonitoring();
		m_bSerialPortOpened2=TRUE;
		m_unPort2=nPort;   //记录打开的串口号
	}
	else
	{
		AfxMessageBox("没有发现此串口或被占用");
		m_bSerialPortOpened2=FALSE;
	}
	GetDlgItem(IDC_BUTTON_OPEN2)->EnableWindow(!m_bSerialPortOpened2);
	GetDlgItem(IDC_BUTTON_CLOSE2)->EnableWindow(m_bSerialPortOpened2);
}

void CSerialPortTestDlg::OnButtonClose2() 
{
	// TODO: Add your control notification handler code here
	m_SerialPort2.ClosePort();//关闭串口2
    m_bSerialPortOpened2=FALSE;
	GetDlgItem(IDC_BUTTON_OPEN2)->EnableWindow(!m_bSerialPortOpened2);
	GetDlgItem(IDC_BUTTON_CLOSE2)->EnableWindow(m_bSerialPortOpened2);
}

//用于将字符串打包成NMEA通信协议包
void CSerialPortTestDlg::SendNMEAData(CString &strData)
{
	char checksum=0,cr=13,ln=10;
    char c1,c2; //2个 半Bype 校验值 
	for(int i=0;i<strData.GetLength();i++)
		checksum = checksum^strData[i];
    c2=checksum & 0x0F;	c1=((checksum >> 4) & 0x0F);
    if (c1 < 10) c1+= '0';	else c1 += 'A' - 10;
    if (c2 < 10) c2+= '0';	else c2 += 'A' - 10;
	CString strNMEAData;
	//加上包头,尾和校验值和回车换行符
	strNMEAData='$'+strData+"*"+c1+c2+cr+ln; 
	//以下几行程序关不通用,在自己的程序中注意修改
	m_SerialPort.WriteToPort((LPCTSTR)strNMEAData);
	m_strEditSendMsg.Format("发送的数据包为:%s",strNMEAData);
	UpdateData(FALSE);  //在发送显示编辑框中显示发送的数据包
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -