VC6.0编写摸拟电能表645规约程序,请问如何判断串口已收完一帧?

d383137359 2012-06-29 05:50:03
第一。RT

第二。VC6.0中的串口控件只有一个函数OnComm() 接收数组应该在此函数中吗?还是另外写线程?

第三。OnComm函数接收数据是先帧尾再帧头吗?
...全文
307 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
CrazyCater 2012-07-23
  • 打赏
  • 举报
回复
你判断一下帧头和帧尾就好了

VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组
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)
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%02X ",bt); //将字符送入临时变量strtemp 16进制形式
strtemps+=strtemp;
if(strtemps.Find("16",0)!=-1&&strtemps.Find("FE 68",0)!=-1&&(strtemps.Find("16",0)>strtemps.Find("FE 68",0)))
{
int count=pEt->GetLineCount();
if(count==10)
{
m_strRXData="";
}
m_strRXData+=strtemps+"\r\n"; //加入接收编辑框对应的字符串
strtemps="";
}

}
}
UpdateData(FALSE);
d383137359 2012-07-03
  • 打赏
  • 举报
回复
哦,你说的OnComm事件呀,我以为还有OnComm时间呢。
那里面我写了一些,我把代码贴出来你指点一下。
void CMnmeterDlg::OnOnCommMscomm1()
{
// TODO: Add your control notification handler code here
VARIANT m_input1;
COleSafeArray m_input2;
long length,i;
BYTE data[4096];
CString str;

//recvcount++;
if(m_com.GetCommEvent()==2) //接收缓冲区内有字符
{
m_input1 = m_com.GetInput();
m_input2 = m_input1;
length = m_input2.GetOneDimSize();
for(i=0; i<length; i++)
{
m_input2.GetElement(&i,data+i);
BYTE bt =* (char *)(data+i);
str.Format("%02X",bt);
recvframe += str;
}
}
m_conlist.AddString(recvframe);
UpdateData(false);
}

如果我发送68 39 00 00 00 00 00 68 01 02 43 C3 12 16 过去。

这样子在m_conlist列表控件中会打印5、6次
第一条:6839000000000068
第二条:6839000000000068
第三条:6839000000000068
第四条:6839000000000068
第五条:6839000000000068010243C31216

每次只有最后一次的才是完整的一帧。而且字节不一样有可能打印出来的少字节帧会多出几行。
LinuxCard 2012-07-03
  • 打赏
  • 举报
回复
1.本来就是这样的机制,一帧分多次接受的情况太正常了。

2.oncom事件返回

大概给你写个框架吧
char *buf=new char[1024];
int bufidx=0;
oncomm()
{
memcpy(buf+idx,串口缓冲区,需要接受的长度)

idx=idx+实际写入缓冲区的长度;

//判断buf中的数据是否足够一帧

如果足够,则将buf中的已经处理的数据删除,如果不够,则直接return,等待下次事件的到来



}
d383137359 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
oncom时间返回,就是接收完毕一次了吧,下次有数据到来,会再次触发事件的,所以,别怕丢包,一般丢不了的,有数据就往buffer里存,这次没收全,下次接着收
[/Quote]

1、有可能是完整的一帧数据会多次触发OnComm事件。我打断点试过了,我一帧有14个字节时,他就会触发6次OnComm。真不知道这MSCOM32是怎么做的接收。
2、OnCom时间返回是什么意思,没大明白。
LinuxCard 2012-07-02
  • 打赏
  • 举报
回复
oncom时间返回,就是接收完毕一次了吧,下次有数据到来,会再次触发事件的,所以,别怕丢包,一般丢不了的,有数据就往buffer里存,这次没收全,下次接着收
LinuxCard 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 5 楼 的回复:
你也别管头尾,直接接受到就放buffer里面,然后定时判断buffer里面的数据是不是够一帧的长度了,够了就取出来分析

感谢你的回复,这儿有点我得说明下。定时判断不好操作。因为我收到了及时就是要发回去。定时判断可能在时间处理上不好找恰当的时间。
[/Quote]

不能定时判断,那就在每次接受完毕后处理不就行了吗?
d383137359 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
你定义一个接收数组 然后发送的时候 发送你需要的指令就可以了 我也是用mscomm
[/Quote]
恩,我在网上找了下资料,定义的了一个BYTE 型的数组。这儿有点疑惑的就是,怎么把BYTE数组中的数类型转换成我的数组中,如unsigned char teFrame[]
Kanson 2012-07-02
  • 打赏
  • 举报
回复
你定义一个接收数组 然后发送的时候 发送你需要的指令就可以了 我也是用mscomm
d383137359 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
引用 7 楼 的回复:

引用 5 楼 的回复:
你也别管头尾,直接接受到就放buffer里面,然后定时判断buffer里面的数据是不是够一帧的长度了,够了就取出来分析

感谢你的回复,这儿有点我得说明下。定时判断不好操作。因为我收到了及时就是要发回去。定时判断可能在时间处理上不好找恰当的时间。


不能定时判断,那就在每次接受完毕后处理不就行了吗?
[/Quote]



对,就是这点,我也是这样想的,但是不知道什么串口收完一帧啊。我发送的数据帧格式有帧尾,可在判断帧尾期间,也不能阻止串口收,不然就丢包了。就是在这儿不知道怎么处理才合适
d383137359 2012-07-01
  • 打赏
  • 举报
回复
其实我用VC6.0编码的,但是那边没人回答,所以跑这边来了
d383137359 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
你也别管头尾,直接接受到就放buffer里面,然后定时判断buffer里面的数据是不是够一帧的长度了,够了就取出来分析
[/Quote]
感谢你的回复,这儿有点我得说明下。定时判断不好操作。因为我收到了及时就是要发回去。定时判断可能在时间处理上不好找恰当的时间。
d383137359 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
似乎控件总有各种各样不尽如人意的地方,我现在都是用API写。代码和用控件差不多长。PS:一想到MSComm中的那个VARIANT我头就晕。
[/Quote]

MSComm 目前知识只局限说用这个控件。请问你有API的例子吗?能否发一个我。dengpeak@163.com
LinuxCard 2012-07-01
  • 打赏
  • 举报
回复
你也别管头尾,直接接受到就放buffer里面,然后定时判断buffer里面的数据是不是够一帧的长度了,够了就取出来分析
BORLANDSUN 2012-07-01
  • 打赏
  • 举报
回复
似乎控件总有各种各样不尽如人意的地方,我现在都是用API写。代码和用控件差不多长。PS:一想到MSComm中的那个VARIANT我头就晕。
dataxdata 2012-07-01
  • 打赏
  • 举报
回复
对于接收来说,如果已经转换为事件处理并且数据量不大的话,可以不用再单独开一个线程
串口接收应该是按顺序接收的,先收到的放在缓冲区前面,后收到的放在后面,可以通过自己分析接收到的字节流来判断帧的结束
lzh280 2012-07-01
  • 打赏
  • 举报
回复
先接收帧头,再帧尾。

13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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