WINCE 5.0 VC++ 串口通信类

CESeries.h文件

  
  
CESeries.h
//  CESeries.h: interface for the CCESeries class.
//
/ /

#if  !defined(AFX_CESERIES_H__1952D4CB_F6A6_489B_80B2_FD59F845BC86__INCLUDED_)
#define  AFX_CESERIES_H__1952D4CB_F6A6_489B_80B2_FD59F845BC86__INCLUDED_

#if  _MSC_VER > 1000
#pragma  once
#endif   //  _MSC_VER > 1000

// 定义串口接收数据函数类型
typedef  void  (CALLBACK *  ONSERIESREAD)(CWnd * ,BYTE *  buf, int  bufLen);

// CE串口通讯类
class  CCESeries  
{
public :
    CCESeries();
    
virtual   ~ CCESeries();

    
// 打开串口
    BOOL OpenPort(CWnd *  pPortOwner,             // 使用串口类,窗体句柄
                  UINT portNo     =   1 ,         // 串口号
                  UINT baud         =   19200 ,         // 波特率
                  UINT parity     =  NOPARITY,  // 奇偶校验
                  UINT databits     =   8 ,         // 数据位
                  UINT stopbits     =   1          // 停止位
                  );
    
// 关闭串口
     void  ClosePort();
    
// 设置串口读取、写入超时
    BOOL SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts);
    
// 向串口写入数据
    BOOL WritePort( const  BYTE  * buf,DWORD bufLen);
    
// 串口读取回调函数
    ONSERIESREAD m_OnSeriesRead; 

private :
    
// 串口读线程函数
     static   DWORD WINAPI ReadThreadFunc(LPVOID lparam);
    
// 串口写线程函数
     static  DWORD WINAPI WriteThreadFunc(LPVOID lparam);

    
// 向串口写入数据
     static  BOOL WritePort(HANDLE hComm, const  BYTE  * buf,DWORD bufLen);

    
// 关闭读线程
     void  CloseReadThread();
    
// 关闭写线程
     void  CloseWriteThread();

    
// 已打开的串口句柄
    HANDLE    m_hComm;
    CWnd
*  m_pPortOwner;

    
// 读写线程句柄
    HANDLE m_hReadThread;
    HANDLE m_hWriteThread;

    
// 读写线程ID标识
    DWORD m_dwReadThreadID;
    DWORD m_dwWriteThreadID;

    
// 读线程退出事件
    HANDLE m_hReadCloseEvent;
    
// 写线程退出事件
    HANDLE m_hWriteCloseEvent;
};
#endif  
//  !defined(AFX_CESERIES_H__1952D4CB_F6A6_489B_80B2_FD59F845BC86__INCLUDED_)

 

CESeries.cpp 文件

 

ggg

  
  
CESeries.cpp
//  CESeries.cpp: implementation of the CCESeries class. 
#include  " stdafx.h "  
#include 
" CESeries.h "  
#ifdef _DEBUG 
#undef  THIS_FILE 
static   char  THIS_FILE[] = __FILE__; 
#define  new DEBUG_NEW 
#endif  
// 定义向写线程发送的消息常量 
const   int  CM_THREADCOMMWRITE  =  WM_USER + 110
/
//  Construction/Destruction 
/
// 类CCESeries构造函数 
CCESeries::CCESeries() 

    m_hComm 
=  INVALID_HANDLE_VALUE;

// 类CCESeries析构函数 
CCESeries:: ~ CCESeries() 


// 关闭读线程 
void  CCESeries::CloseReadThread() 

    SetEvent(m_hReadCloseEvent); 
    
// 设置所有事件无效无效 
    SetCommMask(m_hComm,  0 ); 
    
// 清空所有将要读的数据     
    PurgeComm( m_hComm,  PURGE_RXCLEAR );     
    
// 等待10秒,如果读线程没有退出,则强制退出    
     if  (WaitForSingleObject(m_hReadThread, 10000 ==  WAIT_TIMEOUT)
    { 
        TerminateThread(m_hReadThread,
0 );
    } 
    m_hReadThread 
=  NULL; 

// 关闭写线程 
void  CCESeries::CloseWriteThread() 

    SetEvent(m_hWriteCloseEvent); 
    
// 清空所有将要写的数据     
    PurgeComm( m_hComm,  PURGE_TXCLEAR );     
    
// 等待10秒,如果写线程没有退出,则强制退出     
     if  (WaitForSingleObject(m_hWriteThread, 10000 ==  WAIT_TIMEOUT) 
    { 
        TerminateThread(m_hWriteThread,
0 ); 
    } 
    m_hWriteThread 
=  NULL; 

/*  
*函数介绍:关闭串口 
*入口参数:(无) 
*出口参数:(无) 
*返回值:  (无) 
*/  
void  CCESeries::ClosePort() 

    
// 表示串口还没有打开 
     if  (m_hComm  ==  INVALID_HANDLE_VALUE) {  return  ; } 
    
// 关闭读线程 
    CloseReadThread(); 
    
// 关闭写线程 
    CloseWriteThread(); 
    
// 关闭串口 
     if  ( ! CloseHandle (m_hComm)) 
    { 
        m_hComm 
=  INVALID_HANDLE_VALUE; 
        
return  ; 
    }

/*  
*函数介绍:设置串口读取、写入超时 
*入口参数:CommTimeOuts : 指向COMMTIMEOUTS结构 
*出口参数:(无) 
*返回值:TRUE:设置成功;FALSE:设置失败 
*/  
BOOL CCESeries::SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts) 

    ASSERT(m_hComm 
!=  INVALID_HANDLE_VALUE); 
    
return  SetCommTimeouts(m_hComm, & CommTimeOuts); 
}
/*  
*函数介绍:打开串口 
*入口参数:pPortOwner :使用此串口类的窗体句柄    
           portNo :串口号    
           baud :波特率    
           parity :奇偶校验    
           databits :数据位    
           stopbits :停止位 
*出口参数:(无) 
*返回值:TRUE:成功打开串口;
         FALSE:打开串口失败
*/  
BOOL CCESeries::OpenPort(CWnd
*  pPortOwner,  /* 使用串口类,窗体句柄 */   
                         UINT portNo  , 
/* 串口号 */   
                         UINT baud , 
/* 波特率 */   
                         UINT parity , 
/* 奇偶校验 */   
                         UINT databits  , 
/* 数据位 */   
                         UINT stopbits
/* 停止位 */

    DCB commParam; 
    TCHAR szPort[
15 ]; 
    
//  已经打开的话,直接返回 
     if  (m_hComm  !=  INVALID_HANDLE_VALUE) 
    { 
        
return  TRUE; 
    } 
    ASSERT(pPortOwner 
!=  NULL); 
    ASSERT(portNo 
>   0   &&  portNo <   5 ); 
    
// 设置串口名 
    wsprintf(szPort, L " COM%d: " , portNo);
    
// 打开串口 
    m_hComm  =  CreateFile(
        szPort,
        GENERIC_READ
| GENERIC_WRITE,  // 允许读和写 
         0 // 独占方式(共享模式) 
        NULL, 
        OPEN_EXISTING, 
// 打开而不是创建(创建方式) 
         0
        NULL); 
    
if  (m_hComm  ==  INVALID_HANDLE_VALUE) 
    { 
        
//  无效句柄,返回。 
         return  FALSE; 
    } 
    
//  得到打开串口的当前属性参数,修改后再重新设置串口。 
    
//  设置串口的超时特性为立即返回。 
     if  ( ! GetCommState(m_hComm, & commParam)) 
    { 
        
return  FALSE; 
    } 
    commParam.BaudRate 
=  baud; 
    
//  设置波特率  
    commParam.fBinary  =  TRUE; 
    
//  设置二进制模式,此处必须设置TRUE 
    commParam.fParity  =  TRUE; 
    
//  支持奇偶校验  
    commParam.ByteSize  =  databits; 
    
//  数据位,范围:4-8  
    commParam.Parity  =  NOPARITY; 
    
//  校验模式 
    commParam.StopBits  =  stopbits; 
    
//  停止位  
    commParam.fOutxCtsFlow  =  FALSE; 
    
//  No CTS output flow control  
    commParam.fOutxDsrFlow  =  FALSE; 
    
//  No DSR output flow control  
    commParam.fDtrControl  =  DTR_CONTROL_ENABLE; 
    
//  DTR flow control type  
    commParam.fDsrSensitivity  =  FALSE; 
    
//  DSR sensitivity  
    commParam.fTXContinueOnXoff  =  TRUE; 
    
//  XOFF continues Tx  
    commParam.fOutX  =  FALSE; 
    
//  No XON/XOFF out flow control  
    commParam.fInX  =  FALSE; 
    
//  No XON/XOFF in flow control  
    commParam.fErrorChar  =  FALSE; 
    
//  Disable error replacement  
    commParam.fNull  =  FALSE; 
    
//  Disable null stripping  
    commParam.fRtsControl  =  RTS_CONTROL_ENABLE;  
    
//  RTS flow control  
    commParam.fAbortOnError  =  FALSE; 
    
//  当串口发生错误,并不终止串口读写 
     if  ( ! SetCommState(m_hComm,  & commParam)) {  return  FALSE; }     
    
// 设置串口读写时间 
    COMMTIMEOUTS CommTimeOuts; 
    GetCommTimeouts (m_hComm, 
& CommTimeOuts); 
    CommTimeOuts.ReadIntervalTimeout 
=  MAXDWORD;  
    CommTimeOuts.ReadTotalTimeoutMultiplier 
=   0 ;  
    CommTimeOuts.ReadTotalTimeoutConstant 
=   0 ;   
    CommTimeOuts.WriteTotalTimeoutMultiplier 
=   10 ;  
    CommTimeOuts.WriteTotalTimeoutConstant 
=   1000 ;  
    
if ( ! SetCommTimeouts( m_hComm,  & CommTimeOuts )) 
    { 
        
return  FALSE; 
    } 
    m_pPortOwner 
=  pPortOwner; 
    
// 指定端口监测的事件集 
    SetCommMask (m_hComm, EV_RXCHAR); 
    
// 分配设备缓冲区 
    SetupComm(m_hComm, 512 , 512 );
    
// 初始化缓冲区中的信息 
    PurgeComm(m_hComm,PURGE_TXCLEAR | PURGE_RXCLEAR); 
    m_hReadCloseEvent 
=  CreateEvent(NULL,TRUE,FALSE,NULL); 
    m_hWriteCloseEvent 
=  CreateEvent(NULL,TRUE,FALSE,NULL); 
    
// 创建读串口线程 
    m_hReadThread  =  CreateThread(NULL, 0 ,ReadThreadFunc, this , 0 , & m_dwReadThreadID); 
    
// 创建写串口线程 
    m_hWriteThread  =  CreateThread(NULL, 0 ,WriteThreadFunc, this , 0 , & m_dwWriteThreadID); 
    
return  TRUE; 

// 串口读线程函数 
DWORD CCESeries::ReadThreadFunc(LPVOID lparam) 
{
    CCESeries 
* ceSeries  =  (CCESeries * )lparam; 
    DWORD evtMask; 
    BYTE 
*  readBuf  =  NULL;
    
// 读取的字节 
    DWORD actualReadLen = 0 ;
    
// 实际读取的字节数 
    DWORD willReadLen; 
    DWORD dwReadErrors; 
    COMSTAT cmState; 
    
//  清空缓冲,并检查串口是否打开。 
    ASSERT(ceSeries -> m_hComm  != INVALID_HANDLE_VALUE);  
    
// 清空串口 
    PurgeComm(ceSeries -> m_hComm,PURGE_RXCLEAR  |  PURGE_TXCLEAR ); 
    SetCommMask (ceSeries
-> m_hComm,EV_RXCHAR  |  EV_CTS | EV_DSR );
    
while  (TRUE) 
    {    
        
if  (WaitCommEvent(ceSeries -> m_hComm, & evtMask, 0 )) 
        {
            SetCommMask (ceSeries
-> m_hComm,EV_RXCHAR  |  EV_CTS  |  EV_DSR );
            
// 表示串口收到字符 
             if  (evtMask  &  EV_RXCHAR)  
            { 
                ClearCommError(ceSeries
-> m_hComm, & dwReadErrors, & cmState); 
                willReadLen 
=  cmState.cbInQue ; 
                
if  (willReadLen   <=   0 )
                { 
                    
continue
                } 
                readBuf 
=   new  BYTE[willReadLen]; 
                ReadFile(ceSeries
-> m_hComm, readBuf, willReadLen,  & actualReadLen, 0 ); 
                
// 如果读取的数据大于0, 
                 if  (actualReadLen > 0 ) { 
                    
// 触发读取回调函数 
                    ceSeries -> m_OnSeriesRead(ceSeries -> m_pPortOwner,readBuf,actualReadLen);
                }
            }
        } 
        
// 如果收到读线程退出信号,则退出线程 
         if  (WaitForSingleObject(ceSeries -> m_hReadCloseEvent, 500 ==  WAIT_OBJECT_0)
        { 
            
break
        } 
    }
    
return   0

// 串口写线程函数 
DWORD CCESeries::WriteThreadFunc(LPVOID lparam)

    CCESeries 
* ceSeries  =  (CCESeries * )lparam; 
    MSG msg; DWORD dwWriteLen 
=   0 ; BYTE  *  buf =   new  BYTE();
    
while  (TRUE) { 
        
// 如果捕捉到线程消息 
         if  (PeekMessage( & msg,  0 0 0 , PM_REMOVE)) 
        { 
            
if  (msg.hwnd  !=   0  ) { 
                TranslateMessage(
& msg); 
                DispatchMessage(
& msg); 
                
continue
            }
            
if  (msg.message == CM_THREADCOMMWRITE)
            { 
                
// 向串口写 
                buf  =  (BYTE * )msg.lParam; dwWriteLen  =  msg.wParam; 
                
// 向串口写 
                WritePort(ceSeries -> m_hComm,buf,dwWriteLen);
                
// 删除动态分配的内存 
                delete[] buf; 
            } 
        } 
        
// 如果收到写线程退出信号,则退出线程 
         if  (WaitForSingleObject(ceSeries -> m_hWriteCloseEvent, 500 ==  WAIT_OBJECT_0) 
        {
            
break
        } 
        ceSeries
-> m_hWriteThread  =  NULL; 
    } 
    
return   0

// 私用方法,用于向串口写数据,被写线程调用 
BOOL CCESeries::WritePort(HANDLE hComm, const  BYTE  * buf,DWORD bufLen) 

    DWORD dwNumBytesWritten; 
    DWORD dwHaveNumWritten 
= 0  ; 
    
// 已经写入多少 
    ASSERT(hComm != INVALID_HANDLE_VALUE);
    CString s(buf);
    AfxMessageBox(s);
    
do  { 
        
if  (WriteFile (hComm,  // 串口句柄  
            buf + dwHaveNumWritten,  // 被写数据缓冲区  
            bufLen  -  dwHaveNumWritten,   // 被写数据缓冲区大小 
             & dwNumBytesWritten,  // 函数执行成功后,返回实际向串口写的个数 
            NULL))
            
// 此处必须设置NULL
        { 
            dwHaveNumWritten 
=  dwHaveNumWritten  +  dwNumBytesWritten; 
            
// 写入完成 
             if  (dwHaveNumWritten  ==  bufLen) 
            { 
break ; } 
            Sleep(
10 ); 
        } 
        
else  {  return  FALSE; } 
    }
while  (TRUE); 
    
return  TRUE; 

/*  
*函数介绍:向串口发送数据 
*入口参数:buf : 将要往串口写入的数据的缓冲区    
          bufLen : 将要往串口写入的数据的缓冲区长度 
*出口参数:(无) 
*返回值: TRUE:表示成功地将要发送的数据传递到写线程消息队列。  
          FALSE:表示将要发送的数据传递到写线程消息队列失败。 
注:此处的TRUE,不直接代表数据一定成功写入到串口了。 
*/  
BOOL CCESeries::WritePort(
const  BYTE  * buf,DWORD bufLen) 

    
// 将要发送的数据传递到写线程消息队列 
     return  PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,WPARAM(bufLen), LPARAM(buf)); 

 

示例代码:

m_ceSeries.ClosePort();
m_ceSeries.OpenPort(this,1,19200,NOPARITY,8,1);
CString strUnlogall("UNLOGALL/r/n");

int length=strUnlogall.GetLength();
char *cUnlogall=new char[length+1];
WideCharToMultiByte(CP_ACP, 0, (const unsigned short*)strUnlogall,
-1, cUnlogall, length+1, NULL, NULL);

if (!m_ceSeries.WritePort((BYTE*)cUnlogall,length+1))
{
AfxMessageBox(L"写入失败");
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值