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

📄 scommtestdlg.cpp

📁 一个串口通信的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			continue;//跳出本次循环
		}
		//若输入的第一个字符(高半字节)为有效,则取下一个字节
		i++;
		if(i>=len)
			break;//若只有一个字节,则跳出
		lstr=str[i];//取16进制的低半字节
		//下面进行字符到16进制的转换
		hexdata=ConvertHexChar(hstr);
		lowhexdata=ConvertHexChar(lstr);
		if((hexdata==16)||(lowhexdata==16))//若有一个字节返回值为-1(再内存中以补码方式表示,所以为16)则跳出
			break;
		else
			hexdata=hexdata*16+lowhexdata;//计算16进制数的值
		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::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nIDEvent)
	{
	case 1:OnButtonManualsend();break;
	case ID_CLOCK_TIMER:GetCurrentTime();break;
	case ID_COUNT_TIMER:{
		m_hIconCounter=!m_hIconCounter;
		if(m_hIconCounter)
		{
			ChangeIcon(::AfxGetApp()->GetMainWnd(),(LPCTSTR)IDI_ICON1);break;
//			m_ctrlOpenOrClose.SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1));break;
//			ChangeIcon(m_ctrlOpenOrClose,(LPCTSTR)IDI_ICON1);break;
		}
		else
		{
			ChangeIcon(this,(LPCTSTR)IDI_ICON2);break;//此处this指针就等于::AfxGetApp()->GetMainWnd()
//			m_ctrlOpenOrClose.SetIcon(AfxGetApp()->LoadIcon(IDI_ICON2));break;
//			ChangeIcon(m_ctrlOpenOrClose,(LPCTSTR)IDI_ICON2);break;
		}
						}
	default :break;
	}
	
	
	CDialog::OnTimer(nIDEvent);
}

void CSCommTestDlg::OnCheckAutosend() 
{
	// TODO: Add your control notification handler code here
//	m_bAutoSend=!m_bAutoSend;	
//	if(m_bAutoSend)
	if(m_ctrlAutoSend.GetCheck())
	{
		SetTimer(1,m_iAutoSendTime,NULL);
	}
	else
	{
		KillTimer(1);
	}
	
}
void CSCommTestDlg::GetCurrentTime()
{
	CTime curTime=CTime::GetCurrentTime();
	m_strCurTime.Format("%02d:%02d:%02d",curTime.GetHour(),curTime.GetMinute(),curTime.GetSecond());
//%02d表示以十进制的方式显示,显示占用2位并且为右对齐,不足的位数用0填充
//	UpdateData(FALSE);//会更新整个对话框,引起一些毛病,不妥。
//	m_ctrlCurTime.SetWindowText(m_strCurTime);//作用同下	
    GetDlgItem(IDC_STATIC_TIMER)->SetWindowText(m_strCurTime);
}


void CSCommTestDlg::OnChangeEditAutosendtime() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	OnCheckAutosend();
}

void CSCommTestDlg::OnSelchangeComboComid() 
{
	// TODO: Add your control notification handler code here
	
	HICON hICON=AfxGetApp()->LoadIcon(IDI_ICON4);
	HICON hICON1=AfxGetApp()->LoadIcon(IDI_ICON3);
	int nIndex=m_ctrlComID.GetCurSel()+1;//得到当前被选择的串口
	switch(m_ctrlComID.GetCurSel())
	{
	case 0:m_strComID="COM1 ";break;
	case 1:m_strComID="COM2 ";break;
	case 2:m_strComID="COM3 ";break;
	case 3:m_strComID="COM4 ";break;
	}
	if(m_ctrlAutoSend.GetCheck())
	{
		MessageBox("正在自动发送,请先关闭自动发送!");
		m_ctrlComID.SetCurSel(m_iPrimComID);
		return;
	}

	ComID=nIndex;
	m_ctrlOpenOrClose.SetIcon(hICON1);
	if(ChangeComSet(ComID,m_strComPara))
	{
		m_ctrlOpenOrClose.SetIcon(hICON);
	m_strComStatus.Empty();
	m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
    GetDlgItem(IDC_BUTTON_CLOSECOM)->SetWindowText("关闭串口");
	m_iCloseComCounter=0;
	}
	return;
}

BOOL CSCommTestDlg::ChangeComSet(int comID, CString str)
{
	if(m_ctrlComm.GetPortOpen())//当前是否有打开的串口
		m_ctrlComm.SetPortOpen(FALSE);//有,则关闭当前串口

	/***判断所选的串口是否存在:**********/
	HANDLE m_hComm=CreateFile(m_strComID.Left(4),GENERIC_READ|GENERIC_WRITE,0,
		NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		MessageBox("没有发现此串口或已被占用!","SComDebugAssiant",MB_ICONSTOP|MB_OK);
		m_iCloseComCounter=1;
		CloseHandle(m_hComm);
		return FALSE;
	}
	CloseHandle(m_hComm);
    /****************************************/
	m_ctrlComm.SetCommPort(comID);//选择被选择的串口
	if(!m_ctrlComm.GetPortOpen())
	    m_ctrlComm.SetPortOpen(TRUE);
	else
		AfxMessageBox("不能打开串口");
	m_ctrlComm.SetSettings(str);//波特率为9600,无校验,8个数据位,1个停止位
	m_ctrlComm.SetInputMode(1);//1:表示以二进制方式检取数据
	m_ctrlComm.SetRThreshold(1);//参数1表示每当串口接收缓冲区中有>=1个字符时将引发一个接受数据的OnComm事件
	m_ctrlComm.SetInputLen(0);//设置当前接收缓冲区的数据长度为0
	m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
    return TRUE;
}

void CSCommTestDlg::OnSelchangeComboBitnumber() 
{
	// TODO: Add your control notification handler code here
	m_strComPara='\0';
//	MessageBox(m_strComPara);
	int nIndex=m_ctrlBitNumber.GetCurSel();
	switch(nIndex)
	{
	case 0:BitNumber="8,";break;
	case 1:BitNumber="7,";break;
	case 2:BitNumber="6,";break;
	default:MessageBox("位数无效");break;
	}
	m_strComPara=BoRate+XiaoYan+BitNumber+StopBit;
//	MessageBox("当前串口设置为:\n"+m_strComPara);
	if(m_iCloseComCounter==0)//串口已经打开
	{
		this->ChangeComSet(ComID,m_strComPara);	
		m_strComStatus.Empty();
	    m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	}
	else
	{m_strComStatus.Empty();
	m_strComStatus="STATUS:"+m_strComID+"CLOSED,"+m_strComPara;}
	GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
	return;
}

void CSCommTestDlg::OnSelchangeComboBorate() 
{
	// TODO: Add your control notification handler code here
	m_strComPara='\0';
	int nIndex=m_ctrlBoRate.GetCurSel();
	switch(nIndex)
	{
	case 0:BoRate="1200,";break;
	case 1:BoRate="2400,";break;
	case 2:BoRate="4800,";break;
	case 3:BoRate="9600,";break;
	case 4:BoRate="19200,";break;
	case 5:BoRate="38400,";break;
	default:MessageBox("波特率无效");break;
	}
	m_strComPara=BoRate+XiaoYan+BitNumber+StopBit;
//	MessageBox("当前串口设置为:\n"+m_strComPara);
	if(m_iCloseComCounter==0)//串口已经打开
	{
		this->ChangeComSet(ComID,m_strComPara);	
		m_strComStatus.Empty();
	    m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	}
	else
	{m_strComStatus.Empty();
	m_strComStatus="STATUS:"+m_strComID+"CLOSED,"+m_strComPara;}
	GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
	return;
}

void CSCommTestDlg::OnSelchangeComboStopbit() 
{
	// TODO: Add your control notification handler code here
	m_strComPara='\0';
	int nIndex=m_ctrlStopBit.GetCurSel();
	switch(nIndex)
	{
	case 0:StopBit="1";break;
	case 1:StopBit="2";break;
	default:MessageBox("停止位无效");break;
	}
	m_strComPara=BoRate+XiaoYan+BitNumber+StopBit;
//	MessageBox("当前串口设置为:\n"+m_strComPara);
	if(m_iCloseComCounter==0)//串口已经打开
	{
		this->ChangeComSet(ComID,m_strComPara);	
		m_strComStatus.Empty();
	    m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	}
	else
	{m_strComStatus.Empty();
	m_strComStatus="STATUS:"+m_strComID+"CLOSED,"+m_strComPara;}
	GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
	return;
}

void CSCommTestDlg::OnSelchangeComboXiaoyan() 
{
	// TODO: Add your control notification handler code here

	m_strComPara.Empty();//等同于m_strComPara='\0';
//	MessageBox(m_strComPara);
	int nIndex=m_ctrlXiaoYan.GetCurSel();
	switch(nIndex)
	{
	case 0:XiaoYan="N,";break;
	case 1:XiaoYan="O,";break;
	case 2:XiaoYan="E,";break;
	default:MessageBox("校验位无效");break;
	}
	m_strComPara=BoRate+XiaoYan+BitNumber+StopBit;
//	MessageBox("当前串口设置为:\n"+m_strComPara);
	if(m_iCloseComCounter==0)//串口已经打开
	{
		this->ChangeComSet(ComID,m_strComPara);	
		m_strComStatus.Empty();
	    m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	}
	else
	{m_strComStatus.Empty();
	m_strComStatus="STATUS:"+m_strComID+"CLOSED,"+m_strComPara;}
	GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
	return;
}

void CSCommTestDlg::OnDelRxdata() 
{
	// TODO: Add your control notification handler code here
	m_strRXData.Empty();
	m_ctrlRxDataIsFull.SetWindowText(m_strRXData);
}

void CSCommTestDlg::OnDelTxdata() 
{
	// TODO: Add your control notification handler code here
	m_strTXData.Empty();
	m_ctrlExchangeData.SetWindowText(m_strTXData);
}

void CSCommTestDlg::OnStopdisplay() 
{
	// TODO: Add your control notification handler code here
	m_iCounter=!m_iCounter;
	if(m_iCounter)
	{
		m_ctrlStopDisplay.SetWindowText("继续显示");
	}
	else
	{
		m_ctrlStopDisplay.SetWindowText("停止显示");
	}

}

void CSCommTestDlg::OnClosecom() 
{
	// TODO: Add your control notification handler code here
	HICON hICON=AfxGetApp()->LoadIcon(IDI_ICON4);
	HICON hICON1=AfxGetApp()->LoadIcon(IDI_ICON3);

	m_iCloseComCounter=!m_iCloseComCounter;
	if(m_iCloseComCounter)
	{
		if(!m_ctrlAutoSend.GetCheck())
		{
			m_ctrlComm.SetPortOpen(FALSE);//有,则关闭当前串口
		    m_ctrlOpenOrClose.SetIcon(hICON1);
//		    KillTimer(ID_COUNT_TIMER);
			m_strComStatus.Empty();
	        m_strComStatus="STATUS:"+m_strComID+"CLOSED,"+m_strComPara;
	        GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
		    m_ctrlCloseCom.SetWindowText("打开串口");
		}
		else
		{
			MessageBox("请先关闭自动发送!");
			m_iCloseComCounter=!m_iCloseComCounter;
			return;
		}
	}
	else
	{/***判断所选的串口是否存在:**********/
	HANDLE m_hComm=CreateFile(m_strComID.Left(4),GENERIC_READ|GENERIC_WRITE,0,
		NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		MessageBox("没有发现此串口或已被占用!","SComDebugAssiant",MB_ICONSTOP|MB_OK);
		m_iCloseComCounter=!m_iCloseComCounter;
		CloseHandle(m_hComm);
		return ;
	}
	CloseHandle(m_hComm);
    /****************************************/
		m_ctrlComm.SetPortOpen(TRUE);//无,则打开当前串口
		m_ctrlOpenOrClose.SetIcon(hICON);
//		SetTimer(ID_COUNT_TIMER,300,NULL);
		m_strComStatus.Empty();
	    m_strComStatus="STATUS:"+m_strComID+"OPENED,"+m_strComPara;
	    GetDlgItem(IDC_STATIC_COMSTATUS)->SetWindowText(m_strComStatus);
		m_ctrlCloseCom.SetWindowText("关闭串口");
	}
		
}

void CSCommTestDlg::OnCheckAutodel() 
{
	// TODO: Add your control notification handler code here
//	if(m_ctrlAutoDel.GetCheck())
//	{
//		if(m_ctrlRxDataIsFull.GetLineCount()>=10)
//		MessageBox("Choose");
//	}
//	else
//	    MessageBox("");
}

BOOL CSCommTestDlg::PreTranslateMessage(MSG* pMsg) //重载该函数,去掉程序对Esc键的默认处理
{//函数说明:
//	Used by class CWinApp to translate window messages 
//	before they are dispatched to theTranslateMessage andDispatchMessage Windows functions.
//	Return Value:Nonzero if the message was translated and should not be dispatched;
//	Return Value:0 if the message was not translated and should be dispatched.
//  pMsg:Points to a MSG structure that contains the message to process.


	// TODO: Add your specialized code here and/or call the base class
	if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE)
		return TRUE;
	switch(pMsg->message)
	{
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_MOUSEMOVE:
		m_ToolTips.RelayEvent(pMsg);
	break;
	}

	return CDialog::PreTranslateMessage(pMsg);
}



void CSCommTestDlg::ChangeIcon(CWnd ctrlHandle,LPCTSTR IconID)
{
	HICON hIconNew=AfxGetApp()->LoadIcon(IconID);
	ctrlHandle.SetIcon(hIconNew,0);

}



void CSCommTestDlg::ChangeIcon(CWnd *ctrlHandle, LPCTSTR IconID)
{
	HICON hIconNew=AfxGetApp()->LoadIcon(IconID);
	ctrlHandle->SetIcon(hIconNew,0);

}

void CSCommTestDlg::ChangeIcon(CStatic &ctrlHandle, LPCTSTR IconID)//此处必须用引用传递参数,因为CStatic本身时静态的
{                                                                  //或启用控件的Notify选项
	HICON hIconNew=AfxGetApp()->LoadIcon(IconID);
	ctrlHandle.SetIcon(hIconNew);

}

void CSCommTestDlg::OnChangeRxdata() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()

	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

⌨️ 快捷键说明

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