注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

沙粒的博客

 
 
 

日志

 
 

MFC: 串口通信模板-1  

2014-11-08 17:05:32|  分类: 通信 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 篇幅限制本文分为2篇,此为第一篇

一、程序功能

1、串口通信面板,完成串口打开串口,配置串口,设置串口事件,创建线程,读写串口函数。

2、添加修改处理代码可完成串口通信功能。

 

二、步骤

1、创建基于对话框的MFC工程pctest.

2、在对话框中添加2edit控件ID: IDC_EDIT_sendID: IDC_EDIT_rec; 1Button控件ID: IDC_BNT_SEND, caption:send.

3、在CPctestDlg中定义setcomm函数完成打开串口,配置串口,设置串口事件,创建接收数据线程。此函数由BOOL CScmDlg::OnInitDialog()调用。

同时还需在CPctestDlg中定义的变量有:

1HANDLE m_hcom; 串口句柄,在析构函数中关闭

2HANDLE m_hthread;  线程句柄,在析构函数中关闭

DWORD dwthreadID;  //线程ID

代码:

//打开串口,配置串口,设置串口事件,创建线程

BOOL CPctestDlg::setcomm()

{

      //如果串口打开,关闭

      if(m_hcom!=NULL)

             CloseHandle(m_hcom);

 

      //创建串口

      m_hcom=CreateFile(

             "COM1",

             GENERIC_READ | GENERIC_WRITE,

             0, //不共享

             NULL,  //

             OPEN_EXISTING,  //

             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //异步操作

             NULL);

      //

      if(m_hcom==INVALID_HANDLE_VALUE)

      {

             MessageBox("CreateFile error");

             return false;

      }

 

      //-----配置串口

      //定义通信设备

      DCB dcb;

      //获取串口配置,成功返回非零

      BOOL gcs=GetCommState(m_hcom,&dcb);

      if(gcs==0)

      {

             MessageBox("GetCommState err");

             return false;

      }

 

      //修改串口参数

      dcb.BaudRate=9600;

      dcb.ByteSize=8;

      dcb.Parity=NOPARITY;   //无校验

      dcb.StopBits=ONESTOPBIT;  //1位停止位

 

      //设置串口设备参数

      BOOL scs=SetCommState(m_hcom,&dcb);

      if(scs==0)

      {

             MessageBox("SetCommState err");

             return false;

      }

 

      //设置通信事件,EV_RXCHAR 事件

      BOOL scm=SetCommMask(

             m_hcom,

             EV_RXCHAR);

      if(scm==0)

      {

             MessageBox("SetCommMask err");

             return false;

      }

 

      //创建线程接收输入字符串,

      m_hthread=CreateThread(

             NULL,

             0,

             (LPTHREAD_START_ROUTINE)threadfun,  //线程函数

             this,  //参数为 CScmDlg 类指针

             CREATE_SUSPENDED , //线程挂起运行,ResumeThread函数启动

             &dwthreadID);

      if(m_hthread==NULL)

      {

             MessageBox("CreateThread error");

 

             return false;

      }

      else

      {

             //启动线程

             ResumeThread(m_hthread);

      }

 

 

 

      return true;

 

 

}

 

4、完成第3部调用的线程函数threadfun。此函数为全局函数,定义在pctestDlg.cpp的开始位置。

函数功能,判定串口是否收到了数据。如果收到数据,抛出自定义 UM_RECEIVE 信息,由信息处理函数完成串口数据读取。如果串口未收到数据,等待EV_RXCHAR 事件。

线程中引用的变量:

1)自定义信息UM_RECEIVE,声明位置在pctestDlg.cpp的开始位置。

2)事件句柄m_hPostMsgEvent

CScmDlg中声明,在构造函数中定义,其代码:m_hPostMsgEvent=CreateEvent(NULL,true,false,NULL);

关闭位置,CScmDlg的析构函数中。

线程函数代码:

 

/*定义线程函数,完成读串口相关操作

函数流程:

1.判定串口是否收到了数据。如果收到数据,抛出自定义 UM_RECEIVE 信息,由信息处理函数完成串口数据读取,

2.如果串口未收到数据,等待EV_RXCHAR 事件。

*/

DWORD WINAPI threadfun(LPVOID lpParam )

{

      //获取类指针,用于调用类变量

      CPctestDlg* pdlg=(CPctestDlg*)lpParam;

 

      //串口错误标识

      DWORD dwErrorflag;

      //串口状态信息结构

      COMSTAT cs;

 

 

      //事件掩码

      DWORD dwMask;

      //实际传送的字节数

      DWORD dwTrans;

 

      //定义异步结构

      OVERLAPPED olap;

      memset(&olap,0,sizeof(OVERLAPPED));

      //异步操作要求,事件手动置位,初始nonsignaled 状态

      //程序结束关闭,关闭位置 else 函数结束时。

      //

      olap.hEvent=CreateEvent(NULL,true,false,NULL);

      if(olap.hEvent==NULL)

      {

             AfxMessageBox("in threadfun, CreateEvent error");

             return false;

      }

 

             //如果串口存在,读操作,

      while(pdlg->m_hcom)

      {

             //清除串口错误,获取串口信息

             BOOL cce=ClearCommError(

                    pdlg->m_hcom,

                    &dwErrorflag,

                    &cs);

 

             //如果串口有接收到的数据,抛出信息,在信息响应函数中执行串口读操作

             if(cs.cbInQue)

             {

                    //抛出信息,指定信息由pview->m_hWnd窗口接收,

                    //信息UM_RECEIVE

                    //信息处理函数 wParam 携带参数  EV_RXCHAR

                    PostMessage(pdlg->m_hWnd,UM_RECEIVE,EV_RXCHAR,0);

 

                    //程序等待,当m_hPostMsgEventsignaled 时,函数返回

                    //m_hPostMsgEvent是手动控制的事件句柄,在CScmDlg的构造函数中定义,

                    //抛出的信息处理处理函数运行结束,使m_hPostMsgEventsignaled

                    WaitForSingleObject(pdlg->m_hPostMsgEvent,INFINITE);

 

                    //此时m_hPostMsgEventsignaled,函数返回

                    //设置m_hPostMsgEventnonsignaled,使函数等待

                    ResetEvent(pdlg->m_hPostMsgEvent);

 

                    //回到循环语句的开始的地方,while语句

                    continue;

 

             }

 

             //如果串口没有收到数据,等待串口事件发生

             //表示事件代码

             dwMask=0;

            

             //等待串口事件,异步操作,函数马上返回,

             //函数返回0GetLastError函数返回ERROR_IO_PENDING,表示异步操作

             //异步操作要求,pdlg->m_hcom设置了FILE_FLAG_OVERLAPPED

             //要求olap.hEvent事件为手动,无信号状态

             //olap.hEventd 的变化:

             //函数返回前,系统将olap.hEventd 设为nonsignaled,

             //当等待的事件发生时,系统将olap.hEventd 设为signaled,

             BOOL wce=WaitCommEvent(

                    pdlg->m_hcom,

                    &dwMask,  //输出事件代码

                    &olap);  //overlapped 结构

 

             //异步操作,或函数出错

             if(wce==0)

             {

                    //异步操作

                    if(GetLastError()==ERROR_IO_PENDING)

                    {

                           //等待WaitCommEvent 函数异步操作的结果

                           //bWait=true,WaitCommEvent等待的事件发生后,此函数才返回

                           //注意此语句与 WaitForSingleObject语句

                           GetOverlappedResult(

                                  pdlg->m_hcom,

                                  &olap,

                                  &dwTrans, //实际传送的字节数

                                  true);

 

                    }

                    else

                    {

                           //关闭事件句柄

  评论这张
 
阅读(289)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017