有关MSComm控件,接收数据的问题?

bearRON 2010-07-26 09:27:43
目的:将接收到的数据保存在一个数组中,通过判断此数组的某个字节,选择相应的操作。
调试中用了下面这段经典的接收程序,在与下位机通信过程中,用串口助手发送接收没有问题,但用这段程序会出现个别字节接收错误的情况,不知道是为何?
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048];
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("%02X ",bt); //16进制显示
m_strRXData+=strtemp;
}
}
UpdateData(FALSE);
}

随后将触发事件这段程序修改了后,接收数据没错。但在调试中会弹出“Access violation ”的对话框,不知道为何?

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++) //将数组转换为Cstring型变量
{
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
receivebuf[i] = rxdata[k]; //将数据保存在receivebuf[]中
i++;
}
}

又修改了一下程序,用指针实现数据的保存,不会弹出“Access violation ”,但是接收到的数据receivebuf[i]会与rxdata[k]错位,又不知道是为何?所以在此请求帮助,望高人指点!在此谢过。

定义了一个unsigned char *preceive
初始化了preceive = receivebuf;
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);
*preceive = bt;
preceive++;
m_strRXData+=strtemp;
}
}

...全文
327 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
TBEA_gh 2010-08-25
  • 打赏
  • 举报
回复
m_ctrlComm.GetInput()每次只接受8个字符的数据
bearRON 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 maojian2011 的回复:]
现在你的问题是什么?
使用MSComm控件时,要注意控件属性的设置,尤其是OnComm事件的响应,通过SetRThreshold设置触发OnComm事件的具体条件,当接收缓冲区中达到RThreshold属性设置的字符门限,就触发OnComm事件(这个触发过程是操作系统帮助我们完成的),同时CommEvent属性值变为2,此事件将一直阻塞,直到通过GetInput读取InputLen属性设置的字符……
[/Quote]
InputLen这个属性一般初始化为 :m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlComm.SetRThreshold(1); 若接受一个字符就发生一次OnComm事件,那它读取多少个字符呢?0个字符还是读取所有接受到的字符。

bearRON 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 maojian2011 的回复:]
定义的缓冲区未初始化?是报错吗?
[/Quote]
用串口助手断点调试的时候,看到rxdata里面有121个烫!
ning0025 2010-08-01
  • 打赏
  • 举报
回复
121个“烫”,说是定义的缓冲区未初始化? 如何初始化哦?/////////////////这个是显示的问题吧
maojian2011 2010-08-01
  • 打赏
  • 举报
回复
现在你的问题是什么?
使用MSComm控件时,要注意控件属性的设置,尤其是OnComm事件的响应,通过SetRThreshold设置触发OnComm事件的具体条件,当接收缓冲区中达到RThreshold属性设置的字符门限,就触发OnComm事件(这个触发过程是操作系统帮助我们完成的),同时CommEvent属性值变为2,此事件将一直阻塞,直到通过GetInput读取InputLen属性设置的字符长度后,OnComm事件返回,若返回后缓冲区中的数据还满足条件,就会继续触发OnComm事件,直到条件不满足为止。这就是通信的机制。
你的问题可能主要是对交换数据的处理上。
MSComm控件使用GetInput和SetOutput这两个函数来实现接收和发送数据,并且GetInput的返回类型和SetOutput的参数都是VARIANT数据类型,所以需要对数据做一些变换。
maojian2011 2010-08-01
  • 打赏
  • 举报
回复
定义的缓冲区未初始化?是报错吗?
maojian2011 2010-08-01
  • 打赏
  • 举报
回复
你将接收的数据显示时,出现了121个“烫”?
bearRON 2010-07-31
  • 打赏
  • 举报
回复
在做单步调试的时候,发现rxdata[2048]里有121个“烫”,说是定义的缓冲区未初始化? 如何初始化哦?
bearRON 2010-07-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 peterdan 的回复:]
最好还是设置下触发OnComm事件的缓冲区字节数SetRThreshold(xx)
[/Quote]
在串口初始化里,已经设置了 m_ctrlComm.SetRThreshold(1);
peterdan 2010-07-30
  • 打赏
  • 举报
回复
最好还是设置下触发OnComm事件的缓冲区字节数SetRThreshold(xx)
melody1304 2010-07-28
  • 打赏
  • 举报
回复
m_ctrlComm.GetInput(); 前加sleep(100)试下
旋风 2010-07-26
  • 打赏
  • 举报
回复
好像可以设置等缓冲区字符大于40个字节再触发OnComm事件
bearRON 2010-07-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 m_tornado 的回复:]
你的len是怎么得到的?循环中的那个
觉得会不会是字符串访问达不到的数据才产生的Acess Violation~好比20个字符,你在程序中要获取第21个字符~
[/Quote]
len 是由 len=safearray_inp.GetOneDimSize(); 语句得到的。
你说的问题确实可能会发生。不过在调试的过程中,我又发现,本来固定好接受40个字节的数据,却接受到了41个,而且它接受的是分段接受,先接33个,后接7个。
m_tornado 2010-07-26
  • 打赏
  • 举报
回复
你的len是怎么得到的?循环中的那个
觉得会不会是字符串访问达不到的数据才产生的Acess Violation~好比20个字符,你在程序中要获取第21个字符~

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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