串口调试助手代码分析3-30(2)

2019-02-21 00:03

}

9、手动发送处理

在ClassWizard中为手动发送按钮IDC_BUTTON_MANUALSEND添加单击处理函数(或直接在对话框模板中双击该控件),在OnButtonManualsend()t添加如下代码:

long TX_count=0;

void CSCOMMDlg::OnButtonManualsend() {

// TODO: Add your control notification handler code here

if(m_Port.m_hComm==NULL)//发送时要检验串口是否打开,否则会出错 { m_ctrlAutoSend.SetCheck(0); AfxMessageBox(\串口没有打开,请打开串口\ return; } else { UpdateData(TRUE); if(m_ctrlHexSend.GetCheck())//发送十六进制数据 { char data[512]; int len=Str2Hex(m_strSendData,data); m_Port.WriteToPort(data,len); TX_count+=(long)((m_strSendData.GetLength()+1)/3);

//计数发送的十六进制数据,注意这里的计算方法,

//只有严格按照规则输入才能正确计算 //m_Port.WriteToPort(hexdata); } else //发送ASCII文本 { m_Port.WriteToPort((LPCTSTR)m_strSendData); //发送数据 TX_count+=m_strSendData.GetLength(); //发送计数 } CString strTemp; strTemp.Format(\ m_ctrlTXCount.SetWindowText(strTemp);//显示计数 } }

10、自动发送处理

自动发送时,需要用到定时器。打开ClassWizard,为CSCOMMDlg类添加WM_TIMER消息处理函数OnTimer(UINT nIDEvent)。需要注意的是,在VC6.0中,每个定时器都有自己的ID号,所有定时器处理均要在该函数中,因

此,必须事先为相应的定时器设置ID号,OnTimer(UINT nIDEvent)函数则根据调用的nIDEvent值来确定是哪个定时器的定时时间到,再做相应的处理。 void CSCOMMDlg::OnTimer(UINT nIDEvent) {

// TODO: Add your message handler code here and/or call default CString strStatus; switch(nIDEvent) {

case 1://定时器ID=1为自动发送时间到 OnButtonManualsend();//调用手动发送处理函数 break;

case 2://其他定时器 m_ctrlSavePath.SetWindowText(m_strCurPath); KillTimer(2); break; case 3: m_ctrlManualSend.EnableWindow(TRUE); m_ctrlAutoSend.EnableWindow(TRUE); m_ctrlSendFile.EnableWindow(TRUE); m_strSendFilePathName=m_strTempSendFilePathName;

m_ctrlEditSendFile.SetWindowText(m_strSendFilePathName);//m_strSendFilePathName KillTimer(3); if(!(m_ctrlAutoSend.GetCheck())) { if (m_Port.InitPort(this, m_nCom, m_nBaud,m_cParity,m_nDatabits,m_nStopbits,m_dwCommEvents,512)) { m_Port.StartMonitoring(); strStatus.Format(\:COM%d OPENED,%d,%c,%d,%d\m_nBaud,m_cParity,m_nDatabits,m_nStopbits); m_ctrlIconOpenoff.SetIcon(m_hIconRed); } else { AfxMessageBox(\ m_ctrlIconOpenoff.SetIcon(m_hIconOff); } m_ctrlPortStatus.SetWindowText(strStatus); } break;

case 4: m_animIcon.ShowNextImage(); break; default: break; }

CDialog::OnTimer(nIDEvent); }

我们再来看看如何设置定时器1,在ClassWizar 中,为自动发送选项IDC_CHECK_AUTOSEND 添加响应函数OnCheckAutosend(),或者在对话框模板中直接双击该控件。在OnCheckAutosend()中添加如下代码: void CSCOMMDlg::OnCheckAutosend() {

// TODO: Add your control notification handler code here m_bAutoSend=!m_bAutoSend; //标志是否打开自动发送 if(m_bAutoSend) { if(m_Port.m_hComm==NULL) { m_bAutoSend=!m_bAutoSend; m_ctrlAutoSend.SetCheck(0); AfxMessageBox(\串口没有打开,请打开串口\ return; } else SetTimer(1,m_nCycleTime,NULL); //设置定时器1,启动 }

Else //如果自动发送标志没有打开 { KillTimer(1); //关掉定时器1 } }

在自动发送时,如果输入 编辑框中的内容改变时,要及时将串口发送的内容改变,在ClassWizar中编辑框IDC_EDIT_SEND添加响应函数。 void CSCOMMDlg::OnChangeEditSend() {

// 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); }

同样,当自动发送周期改变后,也需要将发送周期更新,但实际的发送周期需要重新用SetTimer()函数对定时器的定时间进行设置,在这个程序里,必须先关闭串口的“自动发送”然后再打开,新设的自动发送周期才能生效。 void CSCOMMDlg::OnChangeEditCycletime() {

// 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

CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT_CYCLETIME); CString strText;

pEdit->GetWindowText(strText); m_nCycleTime=atoi(strText); }

11、接收处理及十六进制显示

接收处理均在串口事件消息处理函数OnCommunication(WPARAM ch, LPARAM port)函数中实现。其中,十六进制的接收显示时并不像发送那样麻烦,只要将数据直接以十六进制打印输出就可以了,注意中间插入一个空格。 LONG CSCOMMDlg::OnCommunication(WPARAM ch, LPARAM port) {

if (port <= 0 || port > 4) return -1;

rxdatacount++; //接收的字节计数 CString strTemp;

strTemp.Format(\ strTemp=\

m_ctrlRXCOUNT.SetWindowText(strTemp); //显示接收计数

if(m_bStopDispRXData) //如果选择了“停止显示”接收数据,则返回 return -1; //注意,这种情况下,计数仍在继续,只是不显示 //若设置了“自动清空”,则达到50行后,自动清空接收编辑框中显示的数据

if((m_ctrlAutoClear.GetCheck())&&(m_ctrlReceiveData.GetLineCount()>=50)) { m_ReceiveData.Empty(); UpdateData(FALSE); }

//如果没有“自动清空”,数据行达到400后,也自动清空

//因为数据过多,影响接收速度,显示是最费CPU时间的操作 if(m_ctrlReceiveData.GetLineCount()>400) { m_ReceiveData.Empty(); m_ReceiveData=\Length of the Text is too long, Emptied Automaticly!!!***\\r\\n\ UpdateData(FALSE); }

//如果选择了\十六进制显示\,则显示十六进制值 CString str;

if(m_ctrlHexReceieve.GetCheck()) str.Format(\ else str.Format(\

//以下是将接收的字符加在字符串的最后,这里费时很多 //但考虑到数据需要保存成文件,所以没有用List Control int nLen=m_ctrlReceiveData.GetWindowTextLength(); m_ctrlReceiveData.SetSel(nLen, nLen); m_ctrlReceiveData.ReplaceSel(str); nLen+=str.GetLength();

m_ReceiveData+=str; return 0; }

以下是“清空接收区”和“停止/继续显示”两个按钮的单击响应函数。 //清空接收区

void CSCOMMDlg::OnButtonClearReciArea() {

// TODO: Add your control notification handler code here m_ReceiveData.Empty(); UpdateData(FALSE); }

//停止/继续显示接收数据

void CSCOMMDlg::OnButtonStopdisp() {

// TODO: Add your control notification handler code here m_bStopDispRXData=!m_bStopDispRXData; if(m_bStopDispRXData) m_ctrlStopDisp.SetWindowText(\继续显示\ else

}

m_ctrlStopDisp.SetWindowText(\停止显示\


串口调试助手代码分析3-30(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2012年中考政治命题趋势与对策

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: