hur.cn - 华软网

 热门搜索

求串口数据接收方法

  作者:未知    来源:网络    更新时间:2011/9/26
使用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 来接收组合成完整的帧??

这里有一段代码

C++">
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 之类,
之后设置了一个全局变量来接收
代码改为如下
C++">
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);           //更新编辑框内容
}


谢谢
---华软 网友回答---
帧的判断一般要等数据接收完整,
---华软网友回复---
SetRThteshold(n);//参数n为当缓冲区接收到n个字符时产生OnComm事件
                    //参数为1时,表示缓冲区有一个字符就产生OnComm事件
---华软网友回复---
可以先把数据都读到自建缓存中。自己判断数据是否完整。。完整后在做分析
---华软网友回复---
建议楼主使用串口类来进行串口通信,那样可能会好控制一点,可以固定接收多少个字节返回,这样出错的几率就小的多了
---华软网友回复---
单片连续不停的发数据上来.....串口可以先把数据存储到缓冲区中..缓冲区的大小 可以根据实际定义
然后用一个线程判断缓冲中数据..包头,包尾,包大小是否正确..
---华软网友回复---
数据长度不知道,读进缓冲之后,会把下一帧的也读进来,
---华软网友回复---
还是用api了,用组件太麻烦      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。