串口类

//专本针对命令试的串口

Serial.h

#if !defined(AFX_SERIAL_H__F97E181C_46A7_404D_98FB_07595B7767F3__INCLUDED_)
#define AFX_SERIAL_H__F97E181C_46A7_404D_98FB_07595B7767F3__INCLUDED_

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

#define MAXSERBUF 2048 //串口最大缓存

class CSerial  
{
private:
    //检测串口程序
    static void CommWatchProc(LPVOID pParam);
   
    HANDLE m_hIDComDev;
   
    static BOOL  m_bOpened;    //串口是否打开
    static HANDLE R_Event;    //接收事件
    static HANDLE W_Event;    //发送事件
   
    static BYTE     m_szRevBuf[MAXSERBUF];
    static DWORD    m_dwRevBuf;
   
    //读数据到串口
    BOOL ReadComm(PBYTE pbuf, DWORD *pbuflen);
    //写数据到串口
    BOOL WriteComm(const unsigned char *pbBuf, DWORD dwSize);
public: 
   
    VOID    StarMonitor();  //打开监测线程
    VOID    StarRevData();  //开始接收数据
    VOID    StopRevData();  //停止接收数据
   
    DWORD Transmit(PBYTE pbSendBuffer, DWORD cbSendLength,
        PBYTE pbRecvBuffer, DWORD *pcbRecvLength,
        DWORD dwOverTime = 1000);
   
    //串口是否打开
    BOOL isOpen() { return m_bOpened; };
   
    //打开串口
    BOOL Open(int nPort       = 1,
        int nBaud       = 9600,
        int nByteSize   = 8,
        int nParity     = 0,
        int nStopBits   = 1,
        int nSendBuffer = MAXSERBUF);
   
    //关闭串口
    void Close();
   
    CSerial();
    virtual ~CSerial();
};

#endif // !defined(AFX_SERIAL_H__F97E181C_46A7_404D_98FB_07595B7767F3__INCLUDED_)


Serial.cpp


#include "stdafx.h"
#include "Serial.h"

#include <assert.h>
#include <process.h>

//创建一个读事件, 读完数据后产生该事件
HANDLE CSerial::R_Event;
//创建一个写事件, 写完数据后产生该事件
HANDLE CSerial::W_Event;

//串口是否被打开
BOOL CSerial::m_bOpened;  

//串口缓存
BYTE CSerial::m_szRevBuf[MAXSERBUF];
DWORD CSerial::m_dwRevBuf;

//
// Construction/Destruction
//

CSerial::CSerial()
{
    m_bOpened = FALSE;
}

CSerial::~CSerial()
{
    Close();
}

BOOL CSerial::Open(int nPort, int nBaud, int nByteSize, int nParity, int nStopBits, int nSendBuffer)
{
    if ( isOpen() ) return true;
   
    DWORD lpErrCode = 0;
    char szPort[15] = {"/0"};
   
    wsprintf(szPort, "COM%d", nPort);
   
    m_hIDComDev  =  CreateFile(szPort,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);
    if (m_hIDComDev == INVALID_HANDLE_VALUE) return FALSE;
   
    //设置超时
    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout  =  MAXDWORD;
    CommTimeOuts.ReadTotalTimeoutMultiplier =  0;
    CommTimeOuts.ReadTotalTimeoutConstant =  0;
    CommTimeOuts.WriteTotalTimeoutMultiplier=  0;
    CommTimeOuts.WriteTotalTimeoutConstant  =  0;
    SetCommTimeouts(m_hIDComDev, &CommTimeOuts);
   
    //设置为字符形
    if  (!SetCommMask(m_hIDComDev, EV_RXCHAR))
    { 
        goto err;
    } 
   
    //设置输入输出缓存
    if  (!SetupComm(m_hIDComDev, nSendBuffer, nSendBuffer))
    { 
        goto err;
    }
   
    // Clear all comunication errors
    ClearCommError(m_hIDComDev, &lpErrCode, NULL);
   
    //清空缓存
    if  (!PurgeComm(m_hIDComDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
    { 
        goto err;
    }
   
   
    // Gets COM Settings
    // Gets COM Settings
    DCB dcb;
    dcb.DCBlength = sizeof( DCB );
    GetCommState( m_hIDComDev, &dcb );
    dcb.BaudRate = nBaud;
    dcb.ByteSize = nByteSize;
    dcb.Parity   =  nParity  ; 
    dcb.StopBits = nStopBits;
   
    char sDCBState[100];
    wsprintf( sDCBState,"baud=%d parity=N data=%d stop=%d",
        nBaud, nByteSize, nStopBits );
   
    if(!BuildCommDCB(sDCBState, &dcb))
    {
        DWORD ret = GetLastError();
        goto err;
    }
   
    if (!SetCommState(m_hIDComDev, &dcb))
    {
        DWORD ret = GetLastError();
        goto err;
    }
   
    m_bOpened = true;
   
    return true;
   
err:
    CloseHandle(m_hIDComDev);
    return false;
}

void CSerial::Close()
{
    if (!isOpen() || m_hIDComDev == NULL) return;
   
    CloseHandle(R_Event);
    CloseHandle(m_hIDComDev);
   
    m_bOpened = false;
    m_hIDComDev = NULL;
    m_bOpened = false;
}

BOOL CSerial::ReadComm(PBYTE pbuf, DWORD *pbuflen)
{
    assert(pbuf != NULL);
    if ( !isOpen() ) return FALSE;
   
    OVERLAPPED ovRead;
    memset(&ovRead,0,sizeof(ovRead));
    ovRead.hEvent = CreateEvent(0, true, 0, 0);
   
    if (!ReadFile(m_hIDComDev, pbuf, *pbuflen, pbuflen, &ovRead) )
        return FALSE;
   
    CloseHandle( ovRead.hEvent );
    return TRUE;
}

BOOL CSerial::WriteComm(const unsigned char * pbBuf, DWORD dwSize)

    assert(pbBuf != NULL);
    if ( !isOpen() ) return FALSE;
   
    if (dwSize > MAXSERBUF) return FALSE;
   
    int iRet = 0 ;
    OVERLAPPED ov;
    memset(&ov,0,sizeof(ov));
    ov.hEvent = CreateEvent( 0,true,0,0);
    DWORD dwBytesWritten = 0;
    //do
    {
        iRet = WriteFile (m_hIDComDev,pbBuf,dwSize,&dwBytesWritten  ,&ov);
        if ( iRet == 0 )
        {
            WaitForSingleObject(ov.hEvent, INFINITE);
        }
       
    }// while ( ov.InternalHigh != dwSize ) ;
    CloseHandle(ov.hEvent);
   
    return TRUE;
}

void CSerial::CommWatchProc(LPVOID pParam)
{
    assert(pParam != 0);
   
    HANDLE _hIDComDev     = pParam; 
    DWORD dwBytesRead     = 0;
    DWORD   dwWaitOverTime  = 0;           //ms单项位时间
   
    BOOL isSend = FALSE;
   
    char szTmp[MAXSERBUF];
   
    OVERLAPPED ovRead;
    memset(&ovRead,0,sizeof(ovRead));
    ovRead.hEvent = CreateEvent(0, true, 0, 0);
   
    while(m_bOpened){       
        WaitForSingleObject(W_Event, INFINITE);
       
        if (isSend && dwWaitOverTime>=2){
            PulseEvent(R_Event);
           
            dwWaitOverTime = 0;
            isSend = FALSE;
        }
       
        dwBytesRead = 1;//ComStat.cbInQue;
        if (dwBytesRead + m_dwRevBuf > MAXSERBUF){
            PulseEvent(R_Event);
            continue;
        }
       
        if (!ReadFile(_hIDComDev, szTmp, dwBytesRead, &dwBytesRead, &ovRead) ) return;
       
        if (dwBytesRead > 0){
            isSend = TRUE;
            dwWaitOverTime = 0;
           
            m_szRevBuf[m_dwRevBuf] = szTmp[0]; //dwBytesRead);
            m_dwRevBuf += dwBytesRead;
           
            continue;
        }           
       
        dwWaitOverTime++;
        Sleep(1);       
    }
    CloseHandle( ovRead.hEvent );
}

DWORD CSerial::Transmit(PBYTE pbSendBuffer, DWORD cbSendLength,
                        PBYTE pbRecvBuffer, DWORD *pcbRecvLength,
                        DWORD dwOverTime)
{
    if (!isOpen()) return ERROR_ACCESS_DENIED;
   
    if (cbSendLength > MAXSERBUF || pbRecvBuffer == NULL ||
        pbSendBuffer == NULL || pcbRecvLength == NULL)
        return ERROR_INVALID_PARAMETER;
   
    WriteComm(pbSendBuffer, cbSendLength);
    m_dwRevBuf = 0;
   
    StarRevData();
   
    if (WaitForSingleObject(R_Event, dwOverTime))
    {
        StopRevData();
        return WAIT_TIMEOUT;
    }
   
    StopRevData();
   
    memcpy(pbRecvBuffer, m_szRevBuf, m_dwRevBuf);
    *pcbRecvLength = m_dwRevBuf;
   
    m_dwRevBuf = 0;
   
    return 0;
}

VOID CSerial::StopRevData()
{
    ResetEvent(W_Event);
}

VOID CSerial::StarRevData()
{
    SetEvent(W_Event);
}

VOID CSerial::StarMonitor()
{
    //创建一个读事件, 读完数据后产生该事件
    R_Event = CreateEvent(NULL, TRUE, false, NULL);
    //创建一个写事件, 写完数据后产生该事件
    W_Event = CreateEvent(NULL, TRUE, false, NULL);
   
    //开始
    ::_beginthread(CommWatchProc, 0, m_hIDComDev);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值