控件虽然简单易用,但由于必须拿到对话框中使用,在一些需要在线程中实现通信的应用场合下,控件的使用显得捉襟见肘。API是附带在Windows内部的一个极其重要的组成部分。Windows的32位API主要是一系列很复杂的函数和消息集合。它可以看作是Windows系统为在其下运行的各种开发系统提供的开放式通用功能增强接口。
通信程序在
CreateFile处指定串口设备及相关的操作属性,再返回一个句柄,该句柄将被用于后续的通信操作,并贯穿整个通信过程。串口打开后,其属性被设置为默认值,根据具体需要,通过调用
GetCommState(hComm,&&dcb)读取当前串口设备控制块DCB设置,修改后通过
SetCommState(hComm,&&dcb)将其写入。运用
ReadFile()与
WriteFile()这两个API函数实现串口读写操作,若为异步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,调用GetLastError()函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用
WaitForSingleObject()来等待结束信号并设置最长等待时间,举例如下:
BOOL bReadStatus; bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &&dwBytesRead, &&m_OverlappedRead ); if(!bReadStatus){ if(GetLastError()==ERROR_IO_PENDING){ WaitForSingleObject(m_OverlappedRead.hEvent,1000); return ((int)dwBytesRead);} return(0);} return ((int)dwBytesRead); |
多线程下实现串行通信
Windows内部的抢先调度程序在活动的线程之间分配CPU时间,Windows区分两种不同类型的线程,一种是
用户界面线程(User Interface Thread),它包含消息循环或消息泵,用于处理接收到的消息;另一种是
工作线程(Work Thread),它没有消息循环,用于执行后台任务、监视串口事件的线程即为工作线程。
多线程程序的编写在端口的配置,连接部分与单线程的相同,在端口配置完毕后,最重要的是根据实际情况,建立多线程之间的同步对象,如信号灯、临界区和事件等。
一切就绪后即可启动工作线程,程序如下:
CWinThrea CommThread = AfxBeginThread(CommWatchThread, // 线程函数名 (LPVOID) m_pTTYInfo, // 传递的参数 THREAD_PRIORITY_ABOVE_NORMAL, // 设置线程优先级 (UINT) 0, // 最大堆栈大小 (DWORD) CREATE_SUSPENDED , // 创建标志 (LPSECURITY_ATTRIBUTES) NULL); if(WaitCommEvent(pTTYInfo->idComDev,&&dwEvtMask,NULL)) { if((dwEvtMask && pTTYInfo->dwEvtMask )== pTTYInfo->dwEvtMask) { WaitForSingleObject(pTTYInfo->hPostEvent,0xFFFFFFFF); ResetEvent(pTTYInfo->hPostEvent); // 置同步事件对象为非信号态 ::PostMessage(CSampleView,ID_COM1_DATA,0,0); // 发送通知消息}} BEGIN_MESSAGE_MAP(CSampleView, CView) //{{AFX_MSG_MAP(CSampleView) ON_MESSAGE(ID_COM1_DATA, OnProcessCom1Data) ON_MESSAGE(ID_COM2_DATA, OnProcessCom2Data) ..... //}}AFX_MSG_MAP END_MESSAGE_MAP() |
多线程的实现可以使得各端口独立,准确地实现串行通信,使串行通信具有更广泛的灵活性与严格性,且充分利用CPU时间。但在具体的实时监控系统中如何协调多个线程、线程之间以何种方式实现同步,这是多线程串行通信程序实现的难点。
以上内容摘自《基于VC的串行通信技术应用实例》
以下内容摘自《电能质量监测系统中大容量存储设备的研制》
应用程序设计
应用程序是在主机上运行的用户应用程序,使用VC++编制而成,可对USB设备进行控制,通过USB取得保存在Flash中的电能数据,对数据进行分析并画出波形。应用程序现通过调用Win 32函数CreateFile()取得访问设备驱动程序的句柄。然后,应用程序使用Win32函数DevicelOControl()提交I/O控制码,并为CreateFile()函数返回的设备句柄设置I/O缓冲区。
对于每一个连接到主机的EZ-USB设备,EZ-USB GPD都为其创建一个形如ezusb-i的链接符,i从0开始递增。调用CreateFile()函数,实际上就是取得由设备驱动程序产生目标设备的句柄,它使用设备的链接符作为函数参数。应用程序通过Win32函数DeviceloControl()向设备驱动程序发送请求。
若程序只有一个线程,在程序运行过程中,由于数据传输会占据程序的大部分时间,使得此时的命令输人无响应。因此,将数据传送设置为单独的一个线程,使命令得到及时响应。