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

沙粒的博客

 
 
 

日志

 
 

MFC:pc_c51通信-1  

2014-11-14 22:23:08|  分类: 通信 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、功能:

1、对话框中创建2edit控件,1个接收串口数据,1个发送串口数据。

2、可作为PC端串口通信模板程序

3、程序主要代码

二、流程

1、设置串口

2、创建线程,线程调用函数完成读串口

3、主线程完成写串口

三、关键点

1、发送数据时,获取的是CString类型数据,转换为字符数组char buf[]的方法;

char buf[]; //待发送的数据

CString  str; 获取的输入字符串

len=str.GetLength(); //获取输入字符串字节数

     for(int i=0;i<len;i++)

buf[i]=str.GetAt(i);

四、程序创建的句柄

1HANDLE m_hcom;

2HANDLE m_hthread;

3olap.hEvent;线程事件句柄

五、步骤

1、创建1个对话框类型的MFC工程test

2、添加2edit控件,ID: IDC_EDIT_receive,接收数据。 ID: IDC_EDIT_send发送数据。2Button控件,IDIDC_BNT_clear,清空IDC_EDIT_receive IDIDC_BNT_send,发送数据

3、创建opencomm函数。

3.1其功能:设置串口,设置EV_RXCHAR 事件,创建线程。并在OnInitDialog()中调用。

3.2、需在CTestDlg中定义函数用到的下列变量

HANDLE m_hcom; //串口句柄

HANDLE m_hthread; //线程句柄

BOOL m_bconnected; //表示串口连接状态

3.3创建线程

3.3.1格式:DWORD WINAPI threadfun(LPVOID lpParam )

3.3.2创建为全局函数。定义在CTestDlg.cpp开始位置。

代码:

BOOL CTestDlg::opencomm()

{

     //如果串口打开,关闭

     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函数启动

            NULL);

     if(m_hthread==NULL)

     {

            MessageBox("CreateThread error");

 

            //串口未连接

            m_bconnected=0;

 

            return false;

     }

     else

     {

            //启动线程

            ResumeThread(m_hthread);

 

            //串口连接状态

            m_bconnected=1;

            //

     }

     return true;

 

}

4、创建线程函数,如输入缓存有数据,调用ProcessNotification函数处理信息,不用抛出信息方式。否则等待EV_RXCHAR 事件。

4.1此函数定义为全局函数,定义位置在CTestDlg.cpp的开始位置。

4.2代码

//

DWORD WINAPI threadfun(LPVOID lpParam )

{

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

     CTestDlg* pdlg=(CTestDlg*)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_bconnected)

     {

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

            BOOL cce=ClearCommError(

                   pdlg->m_hcom,

                   &dwErrorflag,

                   &cs);

 

            //如果串口有接收到的数据,调用函数执行串口读操作

            if(cs.cbInQue)

            {

                   //调用函数,读串口

                   //参数表示事件类型

                   pdlg->ProcessNotification(EV_RXCHAR,0);

 

            }

 

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

            //表示事件代码

            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 //出错

                   {

                          //关闭事件句柄

                          CloseHandle(olap.hEvent);

                          return false;

                   }

            }

     }

     //关闭事件句柄

     CloseHandle(olap.hEvent);

 

     return true;

}


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

历史上的今天

评论

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

页脚

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