• WinCE下的串口通信开发(VS2005,VB.Net,VC++)


    WinCE下的串口通信开发(VS2005,VB.Net,VC++)
     

    WinCE下的串口通信开发

    一、利用Visual Basic 开发很简单,因为有现成的控件可以直接调用

    VS2005为例,首先要从工具箱中找到SerialPort控件,将其拖到设计视图的下方,因为这些控件(包括定时控件Timer等)在运行的时候不会显示在视图中的。可以通过两种方法对串口进行配置,即点击控件的属性页码,在里面直接修改;也可以通过代码来配置成功,主要如下:

    If VBSerial.IsOpen Then

               VBSerial.Close()

           End If

            '串口设置:9600-N-8-1

           With VBSerial

               .PortName = "COM2"

               .BaudRate = 9600

               .Parity = Parity.None

               .ReceivedBytesThreshold = 13 '接受的数据包长度

               .DataBits = 8

               .StopBits = StopBits.One

            End With

    串口的基本配置完成以后,下一步就是重要的事件属性了,既要设置数据接收的事件属性,在串口控件的属性页,点击事件标志(闪电状的),右方输入事件函数的名字即可,然后在事件函数中用Try,Catch读取串口字符,代码如下:

    Dim rec_byte(LENGTH) As Byte '串口接收数据包     LENGTH是一个宏定义的数据包长度

           Try

               data_num = VBSerial.BytesToRead '串口接收到的字节数,用于测试调校程序

               Me.VBSerial.Read(rec_byte, 0, LENGTH)

               …………

               …………

               操作数组rec_byte(LENGTH)即可完成拆包等工作

           Catch ex AsTimeoutException       '超时后的处理,包括读、写超时等

               Timer1.Enabled = False

               VBSerial.Close()

               System.Threading.Thread.Sleep(300)

            End Try

    至此,即可完成Vb2005 开发WinCE的串口简单操作。

    二、利用Visual C++开发

    Visual C++没有封装好的现成通信控件可以直接调用,故需要用API函数或者第三方的类,这里推荐一个现成的类,见参考文件1中第十章的内容,这个类的详细内容与使用方法,书中写的已经非常仔细,这里我只将我的一点建议叙述,该类的读线程代码主要如下:

    while (TRUE)

         {

             if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))

             {            

                  SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );

                  //表示串口收到字符    

                  if (evtMask & EV_RXCHAR)

                  {

                       ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);

                       if(cmState.cbInQue == (ceSeries->m_RThreshold) )//这个if内的内容是我的测试

                       {

                       willReadLen= cmState.cbInQue ;

                       if (willReadLen <= 0)

                       {

                           continue;

                       }

                      

                       //分配内存

                       readBuf= new BYTE[willReadLen];

                       ZeroMemory(readBuf,willReadLen);

                       //读取串口数据

                       ReadFile(ceSeries->m_hComm,readBuf, willReadLen, &actualReadLen,0);

                      

                       //如果读取的数据大于0

                       if (actualReadLen>0)

                       {

                           //触发读取回调函数

                           if (ceSeries->m_OnSeriesRead)

                           {
                                 
    ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
                            }

                       }

     

                       //释放内存

                       delete[] readBuf;

                       readBuf= NULL;

                       }

                  }

             }

             //如果收到读线程退出信号,则退出线程

             if(WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)

             {

                  break;

             }

    }

    原来的代码中没有那个if来限制,这样每次读取的字符数最多有8个(之前我测试的时候,发现如果数据包长度大于8,就需要分几次读完,给实际应用中造成了不便),此处我加一个if语句来判别:

    if(cmState.cbInQue ==(ceSeries->m_RThreshold) )

    cmState.cbInQue表示现在的接受缓冲区队列中的字符个数,而ceSeries->m_RThreshold是需要预先设置好的,在串口的初始化中设置:

    if(m_pSerial->OpenPort (this ,2,9600,0,8,0,16))

             SetTimer(1,1000,NULL);

         else

         AfxMessageBox(L"串口打开失败");

    最后一个16代表设置的数据包字符个数,这个是由通信协议来确定的。这样每次当检测事件为收到字符时,先等到接收缓冲区队列中的字符个数是16,然后才一次性读取字符,再发送消息给主线程,便于在主线程中一次处理拆包解析工作。

    参考文献

    [1] 汪兵.Windows CE 嵌入式高级编程与实例详解(C++实现),[M].中国水利水电出版社,2008

  • 相关阅读:
    [TJOI2007]小朋友
    弦图小结
    Bzoj2141: 排队
    [SYZOI Round1] 滑稽♂树
    Bzoj2244: [SDOI2011]拦截导弹
    Bzoj1492: [NOI2007]货币兑换Cash(不单调的斜率优化)
    Bzoj1495: [NOI2006]网络收费
    Bzoj1496: [NOI2006]千年虫
    Bzoj1498&1416: [NOI2006]神奇的口袋
    Bzoj4553: [Tjoi2016&Heoi2016]序列
  • 原文地址:https://www.cnblogs.com/fozu/p/3616070.html
Copyright © 2020-2023  润新知