头文件中:
1,定义缓冲区数组。。
//char *Device_pCirBuf;//环形缓冲区 BYTE Device_pCirBuf[81];//环形缓冲区
cpp文件中
2,定义缓冲区接收长度,接收正确数据包定义,读指针(缓冲区头),写指针(缓冲区尾)
char Device_rightdata[38];//保存数据包 int Device_size=81;//缓冲区长度 int Device_startPos,Device_endPos;
3,打开串口的时候,缓冲区指针清零。
if(!m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(TRUE); //打开串口。 GetDlgItem(IDC_OPEN_SERIS)->SetWindowText("请关闭串口"); m_ctrlIconOpenoff.SetIcon(m_hIconOpen); //Device_pCirBuf = new char [Device_size]; //memset(Device_pCirBuf, 0, Device_size); Device_startPos=0,Device_endPos=0; }
4,串口接收1个字节就触发接收事件。
m_ctrlComm.SetRThreshold(1); //每当缓冲区有多余或等于1个字符(字节)时引发一个接收的OnComm事件
5,接收触发事件
void CDevicedlg::OnOnCommMscomm1() { // TODO: Add your control notification handler code here //UpdateData(TRUE); VARIANT variant_inp; COleSafeArray safearray_inp; LONG Device_len,Device_k; // 接收区 int slen=0,r_d_len=38; BYTE recvdata[512];//定义存放二进制数据的数组 CString str; if(m_ctrlComm.GetCommEvent() == 2) // 表示接收缓冲区内有字符 { // m_ctrlIconOpenoff.SetIcon(m_hIconOpen); variant_inp=m_ctrlComm.GetInput(); // /读串口输入缓冲区 //将VARAIANT变量赋值给COleSafeArray类的实例 safearray_inp=variant_inp; //使用COleSafeArray类的成员函数获取数据长度 Device_len=safearray_inp.GetOneDimSize(); //使用COleSafeArray类的成员函数将数据写入数组 for(Device_k=0;Device_k<Device_len;Device_k++) safearray_inp.GetElement(&Device_k,recvdata+Device_k); // 转换为BYTE数组 0-13 //从缓存取出,给新的字节型数组。 //根据长度来定义,新数组长度。 //写循环缓冲区 for (int i=0;i<Device_len;i++) { Device_pCirBuf[Device_endPos]=recvdata[i]; Device_endPos++;//新的endPos位置 //endPos 从0-80可以存81个字节,当值为81时,应该从0开始 if(Device_endPos==Device_size) Device_endPos=0; } //接收够了38个字节。 if ((slen=Device_endPos>Device_startPos ? Device_endPos-Device_startPos : 80-Device_startPos+1+Device_endPos)>r_d_len-1) { //找到帧头。 one: if (Device_pCirBuf[Device_startPos]==(BYTE)0xA5 && Device_pCirBuf[Device_startPos+1>80 ? 0 : Device_startPos+1]==(BYTE)0xA9) { //帧头对,则从帧头位置取38个字节的完整帧。 for (int i=0; i<r_d_len; i++ ) { //这个地方,缓存到80的时候,要变成0继续向38个字节的完整帧中写数据。 if (Device_startPos!=Device_size) { Device_rightdata[i]=Device_pCirBuf[Device_startPos]; Device_startPos++; } else { Device_startPos=0; Device_rightdata[i]=Device_pCirBuf[Device_startPos]; Device_startPos++; } } DataProcessing(); } else { //继续找帧头,可能找到80后还没找到帧尾,应该从0开始找 if (Device_startPos+1==81) { Device_startPos=0; } else { Device_startPos++; } goto one; } //取完xx个完整帧后,重定位下一次读缓存的位置 Device_startPos=Device_endPos; } } for (int i=0; i<512; i++ ) { recvdata[i]=0; } // m_ctrlIconOpenoff.SetIcon(m_hIconOff); UpdateData(false); }
6,正确数据包处理
DataProcessing void CDevicedlg::DataProcessing() { BYTE rebuff; int k, R_D_LEN=38; CString str; bool judge; BYTE judge_sum; switch((BYTE)Device_rightdata[5]) { case 2:// { rebuff=0; //rebuff=*(char *)(recvdata+2); for(k=2;k<R_D_LEN-2;k=k+1)//校验 { rebuff=rebuff^(*(char *)(Device_rightdata+k)); //str.Format(_T("%c"),bt) } judge_sum=*(char *)(Device_rightdata+R_D_LEN-2); //校验不正确,肯定就不解析数据了,应该继续获取数据。 if (judge_sum==rebuff) { judge=true; } else { judge=false; } if(judge) { //解包并显示,解析第7,8个字节。x10, 1 for(k=7;k<9;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); int bt=bt1*256+bt2; float bt0=(float)((float)bt/1000); //得到四位数 if (edit1==1) { m_u11=bt0; } if (edit2==1) { m_u12=bt0; } if (edit3==1) { m_u21=bt0; } if (edit4==1) { m_u22=bt0; } } //解析第9,10个字节 , x20 6 for(k=9;k<11;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); int bt=bt1*256+bt2; float bt0=(float)((float)bt/1000); //得到四位数 if (edit1==1) { m_u13=bt0; } if (edit2==1) { m_u14=bt0; } if (edit3==1) { m_u23=bt0; } if (edit4==1) { m_u24=bt0; } } //解析第11,12个字节。 x30 for(k=11;k<12;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); int bt=bt1*256+bt2; float bt0=(float)((float)bt/1000); //得到四位数 if (edit1==1) { m_u15=bt0; } if (edit2==1) { m_u16=bt0; } if (edit3==1) { m_u25=bt0; } if (edit4==1) { m_u26=bt0; } } } break; } case 3:// { rebuff=0; //rebuff=*(char *)(recvdata+2); for(k=2;k<R_D_LEN-2;k=k+1)//校验 { rebuff=rebuff^(*(char *)(Device_rightdata+k)); //str.Format(_T("%c"),bt) } //校验通过,解析数据 if( rebuff==*(char *)(Device_rightdata+R_D_LEN-2)) { //7 8 9是 a1解析3个字节 1 for(k=7;k<9;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_a1=(float)(bt/1000*(-1)); } else { m_set_a1=(float)(bt/1000); } //得到四位数 } //10 11 12 b1解析3个字节,2 for(k=10;k<12;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_b1=(float)(bt/1000*(-1)); } else { m_set_b1=(float)(bt/1000); } } //13 14 15 是 c1解析3个字节 for(k=13;k<15;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_c1=(float)(bt/1000*(-1)); } else { m_set_c1=(float)((float)bt/1000); } } //解析3个字节, for(k=16;k<18;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); // BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_a2=(float)(bt/1000*(-1)); } else { m_set_a2=(float)((float)bt/1000); } //得到四位数 } // for(k=19;k<21;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_b2=(float)(bt/1000*(-1)); } else { m_set_b2=(float)((float)bt/1000); } } // for(k=22;k<23;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_c2=(float)(bt/1000*(-1)); } else { m_set_c2=(float)((float)bt/1000); } } //7 for(k=25;k<27;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_a3=(float)(bt/1000*(-1)); } else { m_set_a3=(float)((float)bt/1000); } //得到四位数 } //30 31 32 ,8 for(k=28;k<30;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_b3=(float)(bt/1000*(-1)); } else { m_set_b3=(float)((float)bt/1000); } } // 33 34 35是休眠时间间隔 9 for(k=31;k<33;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); BYTE bt3=(*(char *)(Device_rightdata+k+1)); float bt=(float)(bt2*256+bt3); if ((*(char *)(Device_rightdata+k-1))==(char)0x80) { m_set_c3=(float)(bt/1000*(-1)); } else { m_set_c3=(float)((float)bt/1000); } } } break; } case 4:// { rebuff=0; //rebuff=*(char *)(recvdata+2); for(k=2;k<R_D_LEN-2;k=k+1)//校验 { rebuff=rebuff^(*(char *)(Device_rightdata+k)); //str.Format(_T("%c"),bt) } if( rebuff==*(char *)(Device_rightdata+R_D_LEN-2)) { // for(k=7;k<8;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); //int bt=bt1*256+bt2; //得到四位数 str.Format("%d", bt1); m_qianhao=(int)atoi(str); } // for(k=8;k<9;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); // int bt=bt1*256+bt2; //得到四位数 str.Format("%d", bt1); m_xianxing=(int)atoi(str); } //9、10 for(k=9;k<10;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_xiumian_s=(float)(bt/1000); } for(k=12;k<13;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_1=(float)(bt/1000); } for(k=14;k<15;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_6=(float)(bt/1000); } for(k=16;k<17;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_2=(float)(bt/1000); } for(k=18;k<19;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_5=(float)(bt/1000); } for(k=20;k<21;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_3=(float)(bt/1000); } for(k=22;k<23;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); float bt=(float)(bt1*256+bt2); //得到四位数 m_y3_4=(float)(bt/1000); } } break; } case 5:// { AfxMessageBox("正确!"); break; } case 6:// { CByteArray m_Array; m_Array.RemoveAll(); m_Array.SetSize(8); m_Array.SetAt(0,0xA5); m_Array.SetAt(1,0xA6); m_Array.SetAt(2,0x08); m_Array.SetAt(3,0xF5); // m_Array.SetAt(4,0xF6); // m_Array.SetAt(5,0x09); m_Array.SetAt(6,0x02); m_Array.SetAt(7,0xAD); m_ctrlComm.SetOutput(COleVariant(m_Array)); break; } case 7:// { float bt=0; rebuff=0; //rebuff=*(char *)(recvdata+2); for(k=2;k<R_D_LEN-2;k=k+1)//校验,k<36 (36)是校验位,所以计算的时候2到35, { rebuff=rebuff^((BYTE)(Device_rightdata[k])); //str.Format(_T("%c"),bt) } if( rebuff==((BYTE)(Device_rightdata[36]))) { //7是ID for(k=7;k<8;k=k+2) { BYTE bt1=(*(char *)(Device_rightdata+k-1)); BYTE bt2=(*(char *)(Device_rightdata+k)); bt=(float)(bt1*256+bt2); //得到四位数 bt=(float)(bt/1000); if(disp_u1==1) { m_u11=bt; } if(disp_u2==1) { m_u12=bt; } if(disp_u3==1) { m_u13=bt; } if(disp_u4==1) { m_u14=bt; } if(disp_u5==1) { m_u15=bt; } if(disp_u6==1) { m_u16=bt; } if(disp_u7==1) { m_u21=bt; } if(disp_u8==1) { m_u22=bt; } if(disp_u9==1) { m_u23=bt; } if(disp_u10==1) { m_u24=bt; } if(disp_u11==1) { m_u25=bt; } if(disp_u12==1) { m_u26=bt; } disp_u1=0; disp_u2=0; disp_u3=0; disp_u4=0; disp_u5=0; disp_u6=0; disp_u7=0; disp_u8=0; disp_u9=0; disp_u10=0; disp_u11=0; disp_u12=0; } } break; } default: break; } UpdateData(false); }
7,关闭串口的时候,指针清零。
if(m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(FALSE); GetDlgItem(IDC_OPEN_SERIS)->SetWindowText("请打开串口"); m_ctrlIconOpenoff.SetIcon(m_hIconOff); //delete []Device_pCirBuf;//删除数组pCirBuf指针对象, //Device_pCirBuf = NULL;//初始化为 空指针, Device_startPos=0; Device_endPos=0; return; }
8,退出按钮,设置缓冲区指针清零。
void CDevicedlg::OnClose() { // TODO: Add your control notification handler code here //MessageBox(TEXT("是否确认删除?"),TEXT("Warning!!"),4); //AfxMessageBox("确定退出吗?","设备管理",MB_OKCANCEL) int ret=AfxMessageBox("确定退出吗?",MB_OKCANCEL); if(IDOK==ret) { //清除数据,避免bug。 m_k6=0; m_k5=0; m_k4=0; m_k3=0; m_k2=0; m_k1=0; UpdateData(false); if(m_ctrlComm.GetPortOpen()) { // CByteArray m_Array; // m_Array.RemoveAll(); // m_Array.SetSize(8); // m_Array.SetAt(0,0xA5); // m_Array.SetAt(1,0xA6); // m_Array.SetAt(2,0x08); // m_Array.SetAt(3,0xF5); //钳子 // m_Array.SetAt(4,0xF6); //线型 // m_Array.SetAt(5,0x0A); // m_Array.SetAt(6,0x01); // m_Array.SetAt(7,0xAD); // m_ctrlComm.SetOutput(COleVariant(m_Array)); m_ctrlComm.SetPortOpen(FALSE); if (Device_pCirBuf) { //delete []Device_pCirBuf;//删除数组pCirBuf指针对象 //Device_pCirBuf = NULL;//初始化为空指针 Device_startPos=0; Device_endPos=0; } } CDialog::OnOK(); } else if(IDCANCEL==ret) { return; } }
退出该对话框:
//退出软件 void CMyDlg::OnOK() { // TODO: Add extra validation here //停止定时 KillTimer(1); //关闭串口 if(m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(FALSE); //缓冲区指针清零 if (Device_pCirBuf)//可以吗,内存还有吗 { Device_startPos=0; Device_endPos=0; } } CDialog::OnOK(); }
void CDevicedlg::OnClose()
{
// TODO: Add your control notification handler code here
//MessageBox(TEXT("是否确认删除?"),TEXT("Warning!!"),4);
//AfxMessageBox("确定退出吗?","设备管理",MB_OKCANCEL)
int ret=AfxMessageBox("确定退出吗?",MB_OKCANCEL);
if(IDOK==ret)
{
//清除数据,避免bug。
m_k6=0;
m_k5=0;
m_k4=0;
m_k3=0;
m_k2=0;
m_k1=0;
UpdateData(false);
if(m_ctrlComm.GetPortOpen())
{
// CByteArray m_Array;
// m_Array.RemoveAll();
// m_Array.SetSize(8);
// m_Array.SetAt(0,0xA5);
// m_Array.SetAt(1,0xA6);
// m_Array.SetAt(2,0x08);
// m_Array.SetAt(3,0xF5); //钳子
// m_Array.SetAt(4,0xF6); //线型
// m_Array.SetAt(5,0x0A);
// m_Array.SetAt(6,0x01);
// m_Array.SetAt(7,0xAD);
// m_ctrlComm.SetOutput(COleVariant(m_Array));
m_ctrlComm.SetPortOpen(FALSE);
if (Device_pCirBuf)
{
//delete []Device_pCirBuf;//删除数组pCirBuf指针对象
//Device_pCirBuf = NULL;//初始化为空指针
Device_startPos=0;
Device_endPos=0;
}
}
CDialog::OnOK();
}
else if(IDCANCEL==ret)
{
return;
}
}