性的值将 被改变, 应用程序检查 CommEvent 属性值并作出相应的反应。 在程序中用 ClassWizard 为 CMSComm 控件添 加 OnComm 消息处理函数:
void //
CSampleDlg::OnComm(){ 串行口数据接收,处理;
...... }}
switch(m_Serial.GetCommEvent())
{
case
2:
---- 方法二:在单线程中实现自定义的串口通信类 ---- 控件简单易用,但由于必须拿到对话框中使用,在一些需要在线程中实现通信的应用场合,控件的使用显 得捉襟见肘。此时,若能够按不同需要定制灵活的串口通信类将弥补控件的不足,以下将介绍如何在单线程中建 立自定义的
通信类。 ---- 该通信类 CSimpleComm 需手动加入头文件与源文件,其基类为 CObject,大致建立步骤如下: ---- (1) 打开串口,获取串口资源句柄 ---- 通信
程序从 CreateFile 处指定串口设备及相关的操作属性。 再返回一个句柄,该句柄将被用于后续的通信 操作,并贯穿整个通信过程。CreateFile()函数中有几个值得注意的参数设置:串口共享方式应设为 0,串口为不 可共享设备;创建方式必须为 OPEN_EXISTING,即打开已有的串口。对于 dwFlagAndAttribute 参数,对串口有 意义的值是 FILE_FLAG_OVERLAPPED,该标志表明串口采用异步通信模式,可进行重叠操作;若值为 NULL, 则为同步通信方式,在同步方式下,应用程序将始终控制程序流,直到程序结束,若遭遇通信故障等因素,将导 致应用程序的永久等待,所以一般多采用异步通信。 ---- (2)串口设置 ---- 串口打开后,其属性被设置为默认值,根据具体需要,通过调用 GetCommState(hComm,&;dcb)读取当前 串口设备控制块 DCB(Device Control Block)设置,修改后通过 Set
CommState(hComm,&;dcb)将其写入。再 需注意异步读写的超时控制设置, 通过 COMMTIMEOUTS 结构设置超时,调用 SetCommTimeouts(hComm,&;timeouts)将结果写入。以下是温度监控程序中串口初始化成员函数:
BOOL
CSimpleComm::Open( )
{
DCB dcb;m_hIDComDev=CreateFile( "COM2", GENERIC_READ | RLAPPED,
GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVE NULL ); //
打开串口,异步操作 if( m_hIDComDev == NULL ) return( FALSE );dcb.DCBlength =
sizeof( DCB );GetCommState( m_hIDComDev, &;dcb );
//
获得端口默认设置
dcb.BaudRate=CBR_4800;dcb.ByteSize=8;dcb.Parity= NOPARITY;dcb.StopBits=(BYTE) ONESTOPBIT; ...... }
---- (3)串口读写操作 ---- 主要运用 ReadFile()与 WriteFile()API 函数,若为异步通信方式,两函数中最后一个参数为指向 OVERLAPPED 结构的非空指针,在读写函数返回值为 FALSE 的情况下,调用 GetLastError()函数,返回值 为 ERROR_IO_PENDING,表明 I/O 操作悬挂,即操作转入后台继续执行。此时,可以用 WaitForSingleObject() 来等待结束信号并设置最长等待时间,举例如下:
BOOL
bReadStatus;
bReadStatus = ReadFile( m_hIDComDev, buffer, if(!bReadStatus) {
dwBytesRead,
&;dwBytesRead, PENDING) {
&;m_OverlappedRead );
if(GetLastError()==ERROR_IO_ return
WaitForSingleObject(m_OverlappedRead.hEvent,1000); } return(0); } return ((int)dwBytesRead);
((int)dwBytesRead);
---- 定义全局变量 m_Serial 作为新建通信类 CSimpleComm 的对象,通过调用类的成员函数即可实现所需串 行通信功能。与方法一相比,方法二赋予串行通信程序
设计较大的灵活性,端口的读写可选择较简单的
查询式, 或通过设置与外设数据发送时间间隔 TimeCycle 相同的定时器: SetTimer(1,TimeCycle,NULL), 进行定时读取或 发送。
CSampleView:: OnTimer(UINT nIDEvent) 数据处理 } { char InputData[30]; m_Serial.ReadData(InputData,30); //
---- 若对端口数据的响