异步方式winAPI串口通信

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

使用winAPI串口通信(二)

分类:Windows转载2009-09-23 16: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 空");

相关文档
最新文档