求串口数据接收算法

听海拉拉 2011-09-26 12:15:01
使用mscomm接收来自单片机的数据,本来发的是8字节的数据,表头帧格式为:
(0)0xDD (1)0x22 (2)0xlen(长度)(3)0x设备ID (4)0x指令 (5)ox数据一 (6) 0x数据二 (7)0x校验

单片机发是一起发8字节,但pc收到的,有可能很多组合,如 1 2 3 2 或 2 2 4 或 2 3 3,
怎么设计算法,根据固定的oxdd ox22 还有长度oxlen 来接收组合成完整的帧??

这里有一段代码


void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k<len;k++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); 字符送入临时变量strtemp存放
m_strRXData+=strtemp; //加入接收编辑框对应字符串
}
}
UpdateData(FALSE); //更新编辑框内容
}





如以上代码,暂且设当有字符进缓冲来,就出发函数OnComm,每次接收的字节,很少是8个的,都是 1 2 3 4 5 6 之类,
之后设置了一个全局变量来接收
把代码改为如下

int com_index = 0;
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k<len;k++) //将数组转换为Cstring型变量
{
BYTE bt=*(char*)(rxdata+k); //字符型

strtemp.Format("%c",bt); 字符送入临时变量strtemp存放
m_strRXData+=strtemp; //加入接收编辑框对应字符串
}
for( int l = 0; l < len; l++)
{
if( 0xDD == rxdata[l])
{
com_index = 0; //就是将扫描接收到的字节里面有没有0xDD,有就将其存入全局数组中
//即,0xDD就是帧头,下次再到达的数据,就累积填到oxdd后面,之后再判断
//oxdd后面是否为0x22,如果是,将继续接收,再根据oxlen字节后面再接收len字节

DataRX[com_index + l] = rxdata[l];// DataRX为全局BYTE数组,con_index 为int全局
com_index++;
}
if(0xDD == DataRX[0]) //这步判断,如果有东西填进了datarx且DataRX[0]为oxdd,则继续接收
{

DataRX[com_index + l] = rxdata[l];//注意,这里的len是数据到来的长度,可能是1 2 3 4 5 6 7 中的任意一个
}

//如果上面的达成了,那DataRX数组,里面至少 0 1 位置至少为DataRX[0] = 0xDD ;DataRX[1]= 0x22
//接下来就是要判断数组DataRX[2]位置有没有填进0xlen,即长度,(只有0x04,0x05两种情况)
//有的话,根据0xlen信息,继续读取长度为0xlen个字节,但到这里,有点思路混乱,也感觉上面的那些步骤也不够好
//所以请教大家给点建议,怎么接收好,com_index什么时候致零号,还有就是不管是0xlen是0x04或0x05都不丢帧。

}


}
UpdateData(FALSE); //更新编辑框内容
}


谢谢
...全文
108 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧