异步方式winAPI串口通信.docx

上传人:b****5 文档编号:3832225 上传时间:2022-11-25 格式:DOCX 页数:9 大小:17.91KB
下载 相关 举报
异步方式winAPI串口通信.docx_第1页
第1页 / 共9页
异步方式winAPI串口通信.docx_第2页
第2页 / 共9页
异步方式winAPI串口通信.docx_第3页
第3页 / 共9页
异步方式winAPI串口通信.docx_第4页
第4页 / 共9页
异步方式winAPI串口通信.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

异步方式winAPI串口通信.docx

《异步方式winAPI串口通信.docx》由会员分享,可在线阅读,更多相关《异步方式winAPI串口通信.docx(9页珍藏版)》请在冰豆网上搜索。

异步方式winAPI串口通信.docx

异步方式winAPI串口通信

 

使用winAPI串口通信

(二)

分类:

 Windows 转载2009-09-2316:

51 263人阅读 评论(0) 收藏 举报

  采用同步方式的查询方式读取串口数据时,若由于串口操作耗费较长的时间,则程序会被挂起.为解决这种问题,可以在读取数据时采用重叠I/O操作.此时,读写数据的操作在单独的线程 中进行,发出读写要求的主线程可以继续运行.当读写数据成功后,读写数据线程可以通过某种方式通知主线程.两个线程协调工作 ,可以明显提高程序的效率.

         为了实现重叠I/O操作,主要有如下几个编程步骤:

 定义全局变量、创建串口、发出读写操作、读写线程函数的建立、关闭串口等.

         1.定义全局变量

              HANDLE    hCom;         //串口句柄

             DWORD   ThreadProcWrite(LPVOID pParam);      //写线程函数

             DWORD    ThreadProcRead(LPVOID pParam);     //读线程函数

              OVERLAPPED    Wol={0};         //写操作OVERLAPPED结构变量

             OVERLAPPED    Rol={0};         //读操作OVERLAPPED结构变量

             HANDLE   hThreadWrite;        //写线程句柄

             HANDLE   hThreadRead;       //读线程句柄

             HWND     hWnd;       //窗口句柄

         2.创建串口

               hCom=CreateFile("COM2",

                            GENERIC_READ|GENERIC_WRITE,

                            0,

                             NULL,

                            OPEN_EXISTING,

                            FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//使用重叠方式

                            NULL);

                     if(hCom!

=INVALID_HANDLE_VALUE)

                {

                            SetupComm(hCom,1024,512);

                             DCB  myDCB;

                             GetCommState(hCom,&myDCB);

                             myDCB.BaudRate=CBR_19200;

                             myDCB.fBinary=TRUE;

                             myDCB.fParity=TRUE;

                             myDCB.ByteSize=8;

                             myDCB.Parity=ODDPARITY;

                             myDCB.StopBits=ONESTOPBIT;

                             SetCommState(hCom,&myDCB);

                }

               else

                {

                        AfxMessageBox("创建串口失败!

");

               }

               hWnd=GetSafeHwnd();         //获取当前窗口的句柄

         3.发出读写操作

               

(1)读操作

                   在读操作中,只是启动读线程.实际的读操作在读线程函数中完成.

                   DWORD   dwThreadID;

                   DWORD   dwParam;

                   hThreadRead=CreateThread(NULL,

                                               0,

                                               (LPTHREAD_START_ROUTINE)ThreadProcRead,

                                               &dwParam,

                                               0,      //创建线程后,立即执行该线程

                                               &dwThreadID);

                    if(hThreadRead==NULL)

                    {

                              AfxMessageBox("读线程创建失败!

");

                    }

                          CreateThread()函数用于创建一个线程.

                   HANDLE  CreateThread(

                                      //线程安全属性,NULL表示该线程不能被继承

                                      LPSECURITY_ATTRIBUTES    lpThreadAttributes,

                                      //初始化栈大小.0表示默认值或按调用栈线程配置

                                      DWORD    dwStackSize,

                                       //执行函数名称

                                      LPTHREAD_START_ROUTINE     lpStartAddress,   

                                       LPVOID  lpParameter,          //向新线程传递的参数

                                       DWORD  dwCreationFlags,    //创建标志.0表示创建后立即执行 

                                                   LPDWORD    lpThreadId

                            );

                    

(2)写操作

                           在写操作中,同样只是启动写线程.实际的写操作在写线程函数中完成.

                          DWORD   dwThreadID;

                          DWORD   dwParam;

                          hThreadWrite=CreateThread(NULL,

                                                      0,

                                                      (LPTHREAD_START_ROUTINE)ThreadProcWrite,

                                                       &dwParam,

                                                       0,

                                                      &dwThreadID);

                             if(hThreadWrite==NULL)

                            {

                                       AfxMessageBox("写线程创建失败!

");

                             }

                4.读写线程函数的建立

                    读写的实际操作在读写线程函数中执行.这两个函数都是全局函数.

                    

(1)读线程函数

                           在读线程函数中,首先应初始化重叠结构Rol的成员hEvent,将其设置为无信号状态.当读操作完成或出现通信错误时,该变量会被自动设置为有信号状态.接下来就可以使用ReadFile()函数发出读命令.若该读函数返回TRUE,说明读操作已经完成,可以处理读取的数据.若该读函数返回FALSE,说明读操作未完成.此时使用WaitForSingleObject()函数等待读操作的结构。

根据返回结果的不同,采取相应的处理代码即可.

                      DWORD    ThreadProcRead(LPVOID  pParam)

                      {

                              BYTE   myByte[20];

                              CString   myStr;

                              DWORD   dwRes;

                              DWORD    dwRead;

                              BOOL   fRes;

                              char    myChar[10];

                              Rol.hEvent=CreateEvent(NULL,         //创建Rol的hEvent成员为无信号状态

                                                      TRUE;

                                                      FALSE;

                                                      NULL);

                               if(Rol.hEvent==NULL)

                              {

                                      AfxMessageBox("hEvent空");

                                     return-1;

                               }

                               if(ReadFile(hCom,        //串口句柄

                                                      &myByte,    //存放读取数据

                                                     3,        //要读取的字节数

                                                      NULL,

                                                      &Rol))      //指向创建hCom时的Rol的指针

                                 {

                                           //AfxMessageBox("成功读出!

");

                                         //在这里加入处理读取数据代码,数据存放在myByte数组中 

                                  }

                                 else

                                {

                                          dwRes=WaitForSingleObject(Rol.Event,5000);  //5秒超时

                                          switch(dwRes)

                                          {

                                                 case  WAIT_OBJECT_0:

                                                          if(!

GetOverlappedResult(hCom,

                                                                &Rol,

                                                                &dwRead,   //实际读出的字节数

                                                                 TRUE))    //TRUE表示直到操作完成函数才返回

                                                          {

                                                                 //操作失败,可以使用GetLastError()获取错误信息

                                                           }

                                                         else

                                                          {

                                                                    //操作成功完成,数据读取存入myByte中

                                                                    //这里加入处理数据的代码

                                                           }

                                                           break;

                                               case  WAIT_TIMEOUT:

                                                         //读操作失败,原因是超时

                                                         break;

                                                default:

                                                         //这里加入默认处理代码

                                                         break;

                                          }

                              }

                             closeHandle(Rol.hEvent);

                             return0;

                       }

                        CreateEvent()函数用来创建一个事件句柄,并设置其信号状态.

                       HANDLE   CreateEvent(

                                       //事件安全属性,NULL表示该事件句柄不能用于继承

                                     LPSECURITY_ATTRIBUTES  lpEventAttributes,

                                      BOOL    bManualReset,   //TRUE表示该事件需人工复位

                                     BOOL    bInitialState,  //事件对象的初始状态,TRUE表示有信号,反之无信号

                                       LPCTSTR   lpName      //指向事件对象的名称,NULL表示创建一个无名事件对象

                                     );

                 ReadFile()函数是读缓冲区命令,若该命令执行后返回TRUE,说明已经读成功.若该命令返回FALSE,说明该命令返回时,读操作尚未完成,读操作继续在后台中进行. 此时使用waitForSingleObject()函数来获取后台 读命令的操作结果. 

                   DWORD   WaitForSingleObject(

                                     HANDLE    hHandle,      //指向等待对象的句柄

                                     DWORD    dwMilliseconds,      //超时时间

                                    );

                  GetOverlappedResult()函数其实与WaitForSingleObject()函数功能类似,都可以返回某操作的操作结果.之所以使用GetOverlappedResult()函数,是因为它可以返回读操作实际读出的字节数量.

                   BOOL   GetOverlappedResult(

                                HANDLE     hFile,          //指向串口句柄

                                LPOVERLAPPED   lpOverlapped,      //执行读函数中使用的OVERLAPPED结构变量

                                LPDWORD   lpNumberOfBytesTransferred,    //存放实际读出字节数量变量的地址

                                BOOL    bWait     //设为TRUE表示读操作完成该函数才返回,若为FALSE表示如果操作未完成时函数将返回FALSE.

                               );

                     

(2)写线程函数

                          写线程函数所作操作与读线程函数的操作相似.首先初始化Wol的hEvent事件成员,然后发出写命令WriteFile().若该写命令返回TRUE,说明写操作成功完成.若写命令返回FALSE,说明写操作没有完成.使用WaitForSingleObject()函数等待写操作的结果,根据返回结果的不同,采取相应的处理代码.

                          DWORD    ThreadProcWrite(LPVOID  pParam)

                   

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1