现在的位置: 首页 > 综合 > 正文

vc串口编程使用mscomm控件的,接受字符个数多余8个时,会重复进中断的OnCommMscomm()的处理对策

2013年12月13日 ⁄ 综合 ⁄ 共 2045字 ⁄ 字号 评论关闭

在串口编程时,使用microsoft的mscomm控件,简单,实用,特别是对于一些异步处理的场合,使用控件的中断(消息映射),比较方便。

但是,在实际使用中,发现当接收的字符个数大于8个时,会重复进入中断处理函数,这种方式在某些场合使用会出现问题。

本文的目的就是提出一种解决方式,当接受的字符个数大于8个时,在一次中断处理函数中全部接收到这些字符串,而不用多次进入中断处理函数。

 

串口的控件初始化:

m_ComPort.SetCommPort(1);   // 选择串口号

       m_ComPort.SetInBufferSize(1024); //接收缓冲区

       m_ComPort.SetOutBufferSize(1024);//发送缓冲区

       m_ComPort.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取

       m_ComPort.SetInputMode(1);//以二进制方式读写数据

       m_ComPort.SetRThreshold(1);//接收缓冲区有大于等于1个字符时,将引发接收数据的OnCommMscomm事件

       m_ComPort.SetSettings("9600,n,8,1"); //设置波特率等参数

       if(!m_ComPort.GetPortOpen())   //打开串口

              m_ComPort.SetPortOpen(TRUE);

       else

              m_ComPort.SetOutBufferCount(0);

 

消息映射:

ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnCommMscomm,VTS_NONE)
//映射

 

中断(消息)处理函数:

void CSportDlg::OnCommMscomm()  // 串口事件到来

{

       VARIANT
variant_inp;

       COleSafeArray
safearray_inp;

       LONG
len,k;

       BYTE
rxdata[2048]; //
设置BYTE数组 An 8-bit integerthat is not
signed.

       CString
strtemp;   

       switch(m_ComPort.GetCommEvent())

       {

       case
1: // comEvSend
发送数据

                     break;

       case
2: // comEvReceive
读取数据    串口接收事件到来

     Sleep(50);

                     variant_inp=m_ComPort.GetInput();
//
读缓冲区

                     safearray_inp=variant_inp;
//VARIANT
型变量转换为ColeSafeArray型变量

                     len=safearray_inp.GetOneDimSize();
//
得到有效数据长度

                     //
接受数据

                     for(k=0;
k<len; k++)

                     {

                            safearray_inp.GetElement(&k,rxdata+k);
//
转换为BYTE型数组    

                            BYTE
bt=*(char*)(rxdata+k); //
字符型

                            strtemp.Format("%c",bt);
//
将字符送入临时变量strtemp存放

                            m_receive+=strtemp;
                       

                     }

                     break;

       default:
//
传输事件出错

                     m_ComPort.SetOutBufferCount(0);

                     break;

             

       }

       UpdateData(FALSE);
//
更新对话框内容

}

 

注意消息处理函数中的case 2 中的Sleep(50);这一句,这里用了延时再去读取缓冲区的数据m_ComPort.GetInput(); 

这里使用延时的目的就是为了缓冲区接收到更多的字符。

 

这里使用延时时间的长短,根据实际要接受的的数据的多少来灵活设置。

 

使用这种方式可以保证在一次中断处理中,收到到所有的字符,而不会多次进入中断接受字符。

抱歉!评论已关闭.