串口问题:接收到字符的总是比我发的少1,而最后发的那个字符则会触发新的一次中断

slimfeng 2007-02-12 01:21:07
if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{
strRXData=_T("");
variant_inp=m_ctrlComm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
.................
}
其中len=safearray_inp.GetOneDimSize();接收到字符的总是比我发的少1,而我最后发的那个字符则会触发新的一次中断,不知道是怎么回事?本来是一个字符串现在给分成了两次处理
串口初始化步骤如下:
m_ctrlComm.SetPortOpen(FALSE);
m_ctrlComm.SetCommPort(1); //选择COM
m_ctrlComm.SetInputMode(1); //输入方式为二进制方式
m_ctrlComm.SetInBufferSize(1024); //设置输入缓冲区大小
m_ctrlComm.SetOutBufferSize(512); //设置输出缓冲区大小
//波特率9600,无校验,8个数据位,1个停止位
m_ctrlComm.SetSettings("9600,n,8,1");
...全文
529 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
slimfeng 2007-02-13
  • 打赏
  • 举报
回复
如果把SetRThreshold设成9,刚才的问题就不存在了,但设成8还是存在,由于我现在程序里不只这一条指令,有的指令长度为5,除了让我修改协议之外,是否还有其他的处理办法?
这种方法是否可行?启动一个子进程处理串口接收的信息文件,串口中断就可以不断地将收到的信息往子进程克访问的文件中写,只要处理好文件访问问题就可以了。
happyprince 2007-02-13
  • 打赏
  • 举报
回复
两头波特率有没有对上号阿
东文-桑晨 2007-02-13
  • 打赏
  • 举报
回复
楼主确定硬件是否有问题,也可以通过修改硬件设备去改掉这个bug
old_bonze 2007-02-13
  • 打赏
  • 举报
回复
回楼主:可行是可行,但是有点多此一举的味道。简单的说,你直接建立一个全局的缓冲区,当串口接收数据事件触发后,先将收到的数据在缓冲区里拼凑,然后对缓冲区的内容进行分析,如果发现缓冲区里包含某个完整的指令,就从缓冲区里割出这个指令(如果割掉后还有多余的,仍然保留在缓冲区中),通知处理程序进行指令处理不就行了?如果你想开一个线程也行,思路类似。但是楼主说启动一个进程,然后依赖文件实现进程间通讯,那就太麻烦而且太低效率了,不可取。
SCOIN 2007-02-12
  • 打赏
  • 举报
回复
楼上有理
试试把n写大点
old_bonze 2007-02-12
  • 打赏
  • 举报
回复
SetRThreshold(n)方法用于指定当组件收到的字符个数 >= n 时触发接收数据事件。如果你设的为1,那么就是每收到1个字符时,接收数据事件被触发。但是,由于应用程序处理与串口硬件通讯在速度上不可能保持一致,就有可能实际已经收到了2个、3个或是更多的字符,接收数据事件才被触发。所以,在做这一类通讯程序的时候,切不可假想我发送n个字符,接收端就一定能一次性接收到n个字符。你必须要根据实际通讯的要求,将接收的数据进行组合。这也就是各类通讯系统都要有“协议”的原因,通过起始标志、结束标志或其它特殊标志,用来对数据的完整性进行标识。
slimfeng 2007-02-12
  • 打赏
  • 举报
回复
现在的情况是:
有时候第一次通讯接收成功,但第二次少一个字符,有的时候就一直不成功
东文-桑晨 2007-02-12
  • 打赏
  • 举报
回复
标准的USB转成串口与普通的串口使用起来没什么区别的~

设置过程如下:
if(m_Com.GetPortOpen())
m_Com.SetPortOpen(FALSE);
m_Com.SetCommPort(1);//select com1
if(!m_Com.GetPortOpen())
m_Com.SetPortOpen(TRUE);//open serial port
m_Com.SetSettings("9600,n,8,1);
m_Com.SetInputMode(1);
m_Com.SetRThreshold(1);
m_Com.SetInputLen(0);
m_Com.GetInput();
slimfeng 2007-02-12
  • 打赏
  • 举报
回复
m_ctrlComm.SetRThreshold(1);
m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据
我已经在初始化的时候加了这个操作,是不是跟我用的串口有关,我现在用的一个是串口1,另一个是通过USB转换成的串口。
sanbao1983 2007-02-12
  • 打赏
  • 举报
回复
你在串口初始化步骤中在后面加上
m_mscom.put_InputLen(0);//一次读出接收缓存区的字符
m_mscom.get_Input();////清空接收缓存区

我这是vc.net的方法,在c++中方法可能不这么写
slimfeng 2007-02-12
  • 打赏
  • 举报
回复
现在就是只能接收8个字符,不知道跟什么设置有关
slimfeng 2007-02-12
  • 打赏
  • 举报
回复
试过了,不管用
windindance 2007-02-12
  • 打赏
  • 举报
回复
在发送的字符串末尾加个 \0 看看?

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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