13.11.2 发送数据操作的控制功能(1)
数据的发送操作分为两种:自动发送和手动发送。手动发送是用户单击"发送数据"按钮后将发送数据框中的数据发送到串口的操作。自动发送是调试器自动每隔一定时间间隔将发送框中的数据发送到串口的操作。
(1)自动发送。自动发送数据为用户提供了更多的方便,且可以控制发送数据的时间间隔,有效地提高了工作效率。自动发送由发送区域内的"自动发送"复选按钮来控制。为这个按钮添加一个鼠标单击处理函数OnCheckauto()。在该函数中,判断当前的自动发送状态。如果已经处于自动发送状态,则停止自动发送,否则开始自动发送。函数实现如下:
- 01 void CComElvesDlg::OnCheckauto()
- 02 {
- 03 if(!m_bOpened)
- 04 { //串口尚未打开
- 05 MessageBox("请先打开串口!");
- 06 UpdateData(false);
- 07 return;
- 08 }
- 09 m_bAuto = !m_bAuto;
- 10 if(m_bAuto)
- 11 { //开始自动发送
- 12 GetDlgItem(IDC_SEND)->SetWindowText("停止");
- 13 SetTimer(1,m_uTime,NULL);
- 14 }
- 15 else
- 16 {
- 17 //停止自动发送
- 18 GetDlgItem(IDC_SEND)->SetWindowText("发送");
- 19 KillTimer(1);
- 20 }
- 21 }
【代码解析】
第3~8行判断当前串口是否已经打开,如果尚未打开则提示用户打开串口。第9行将自动发送状态置反。第10行判断当前的状态,如果处于非自动发送状态,则在第12行将"发送"按钮改为"停止"按钮,并在第13行开启定时器1。否则在第18行将"停止"按钮改为"发送"按钮,并在第19行停止定时器1。
由此可见,自动发送的关键便是定时器处理函数OnTimer(),该函数在设置的时间间隔为被触发向串口发送数据,函数实现如下:
- 01 void CComElvesDlg::OnTimer(UINT nIDEvent)
- 02 {
- 03 UpdateData(true); //获取发送数据
- 04 SaveSMod(); //保存发送数据
- 05 switch(nIDEvent) //定时器类型
- 06 {
- 07 case 1: //自动发送数据
- 08 if(m_bSHex)
- 09 { //十六进制
- 10 char data[512];
- 11 int len=StrToHex(m_sData,data);
- 12 m_Port.WriteToPort(data,len); //发送数据
- 13 m_SCount+=(long)((m_sData.GetLength()+1)/2);
- 14 }
- 15 else
- 16 { //字符串
- 17 m_Port.WriteToPort((LPCTSTR)m_sData); //发送数据
- 18 m_SCount+=m_sData.GetLength();
- 19 }
- 20 CString strTemp;
- 21 strTemp.Format("TX:%d",m_SCount);
- 22 m_ctrlSCount.SetWindowText(strTemp); //发送数据计数更新
- 23 break;
- 24 }
- 25 CDialog::OnTimer(nIDEvent);
- 26 }
【代码解析】
第3行获取当前发送编辑框中的数据。第4行将数据保存到情景模式变量中。第8行判断当前发送数据的格式。如果为十六进制数据格式,则在第11行将所有要发送的数据转化成十六进制,然后在第12行将转化后的数据发送到串口,并更新发送数据计数变量;否则在第17行将数据直接发送到串口,并在第18行更新发送数据计数变量。最后在第20~22行将更新后的发送数据计数变量显示到状态栏中。
在第11行的StrToHex()函数是一个自定义变量,它实现了将CString型变量转化成十六进制数值并保存到字符数组中的功能,实现如下:
- 01 int CComElvesDlg::StrToHex(CString str, char *data)
- 02 {
- 03 int t,t1;
- 04 int rlen=0,len=str.GetLength(); //字符串的长度
- 05 if(len/2 != 0) //字符串中的字符是否为偶数个数
- 06 {
- 07 str += '0'; //凑偶数
- 08 len += 1; //长度加1
- 09 }
- 10 for(int i=0;i<len;) //遍历字符串中的字符
- 11 {
- 12 char l,h=str[i];
- 13 if(h==' ') //是否为空格
- 14 {
- 15 i++;
- 16 continue;
- 17 }
- 18 i++;
- 19 if(i>=len) //转化完毕
- 20 break;
- 21 l=str[i]; //获取字符
- 22 t=HexChar(h); //字符对应的值
- 23 t1=HexChar(l);
- 24 if((t==16)||(t1==16)) //非十六进制
- 25 break;
- 26 else
- 27 tt=t*16+t1;
- 28 i++;
- 29 data[rlen]=(char)t; //保存数据
- 30 rlen++;
- 31 }
- 32 return rlen;
- 33 }