VC串口读写

#pragma once

//#include "CommonDefine.h"
#include <WINDOWS.H>
#include "MySerial.h"
//不使用读超时
#define TIMEOUT_READ_INTERVAL 0xFFFFFFFF
#define TIMEOUT_READ_TOTAL_MULTIPLIER 0
#define TIMEOUT_READ_TOTAL_CONSTANT 0

//写超时为秒
#define TIMEOUT_WRITE_TOTAL_MULTIPLIER 0 
#define TIMEOUT_WRITE_TOTAL_CONSTANT 5000 

//推荐的输入/输出缓冲区(注意:实际值由系统设置) 
#define BUFFER_INPUT_RECOMMEND 10000 
#define BUFFER_OUTPUT_RECOMMEND 10000

//异步读取/写入操作时等待事件的超时时间 
#define TIMEOUT_READCOMM_EVENT 4000 
#define TIMEOUT_WRITECOMM_EVENT 2000

//一些通讯协议使用的宏  
#define FC_DTRDSR       0x01 
#define FC_RTSCTS       0x02 
#define FC_XONXOFF      0x04 
#define ASCII_BEL       0x07 
#define ASCII_BS        0x08 
#define ASCII_LF        0x0A 
#define ASCII_CR        0x0D 
#define ASCII_XON       0x11 
#define ASCII_XOFF      0x13

#define UINT8 unsigned char



/*
 *异步串口
 *  针对同步而言的,异步串口不需要等I/O操作完成才返回,而是立即返回
 *  异步串口可以更快得响应用户操作,但是要处理的异常就多一些
 */

class MySerial
{
public:
    MySerial();
    virtual ~MySerial();
public:
    bool Open(int port, int baund = 115200, int byteSize = 8);
    int WriteData(const char *pBuffer, int size);
    int ReadData(void *pBuffer, int limit);
private:
    void WriteCommByte(UINT8 byte)
    {
        DWORD bytesWriitten;
        BOOL wrieteStat = WriteFile(m_hCom, (LPSTR)&byte, 1, &bytesWriitten, &m_overlappedWrite);

        //查询写入是否完成,未完成则挂起等待
        if ((!wrieteStat) && (GetLastError() == ERROR_IO_PENDING))
        {
            if (WaitForSingleObject(m_overlappedWrite.hEvent, TIMEOUT_WRITECOMM_EVENT))
            {
                bytesWriitten = 0;
            }
            else
            {
                GetOverlappedResult(m_hCom, &m_overlappedWrite, &bytesWriitten, FALSE);
                m_overlappedWrite.Offset += bytesWriitten;
            }
        }
    }

    int ReadDataWaiting()
    { 
        if ((!m_bOpened) || (m_hCom == INVALID_HANDLE_VALUE))
        {
            return 0;
        }
            
        DWORD dwErrorFlags; 
        COMSTAT ComStat;       
        ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
        return ((int)ComStat.cbInQue);
    }
public:
    HANDLE m_hCom;
    bool m_bOpened;
    DWORD m_dwError;
    OVERLAPPED m_overlappedRead;
    OVERLAPPED m_overlappedWrite;
};

int serial_write_string(const char *buffer);
void serial_init(void);
int serial_open(int baund,int nPort);
void serial_close();
int serial_write(const char *buffer, int size);
int serial_read(void *buffer, int limit);
int serial_isopen(void);

 

#include "stdafx.h"
#include "MySerial.h"

MySerial m_serial;
int serial_opened = 0;

int slip_encapsulate(const void *psrcbuf,const int srclen,void *pdstbuf,int *dstlen);
int slip_decapsulate(const void *psrcbuf,const int srclen,const void *pdstbuf,int *dstlen);

MySerial::MySerial()
{
    m_hCom = INVALID_HANDLE_VALUE;
    m_bOpened = false;
    m_dwError = ERROR_SUCCESS;
    memset(&m_overlappedRead, 0, sizeof(OVERLAPPED));
    memset(&m_overlappedWrite, 0, sizeof(OVERLAPPED));
}

MySerial::~MySerial()
{
    if (!m_bOpened || m_hCom == NULL)
    {
        return;
    }
    
    if (m_overlappedRead.hEvent != NULL) 
    {
        CloseHandle (m_overlappedRead.hEvent);
    }
    
    if (m_overlappedWrite.hEvent != NULL) 
    {
        CloseHandle (m_overlappedWrite.hEvent); 
    }
    
    CloseHandle(m_hCom);
    m_bOpened = FALSE;
    m_hCom = INVALID_HANDLE_VALUE; 
}

bool MySerial::Open(int port, int baund, int byteSize)
{
//    if (m_bOpened)
    //{
//        return true;
//    }

    TCHAR aPort[20];
    //TCHAR aComParams[50];
    DCB dcb;
    wsprintf(aPort, "\\\\.\\COM%d", port);

    m_hCom = CreateFile(aPort, 
            GENERIC_READ | GENERIC_WRITE, //文件访问类型为:读和写
            0, //串口不支持任何形式的共享,只能填0
            NULL, //安全属性,一般不用,填NULL
            OPEN_EXISTING, //文件创建方式,对于串口只能是打开已存在
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // 定义文件属性和标志 第二个表示异步通信
            NULL); //指向一个模板文件的句柄,对于串口无模板可言
    if (m_hCom == INVALID_HANDLE_VALUE )
    {
    //    printf("CreateFile...get invalid handle value!\n");
        return false;
    }

    //设置超时
    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout  = TIMEOUT_READ_INTERVAL; 
    CommTimeOuts.ReadTotalTimeoutMultiplier = TIMEOUT_READ_TOTAL_MULTIPLIER;  
    CommTimeOuts.ReadTotalTimeoutConstant = TIMEOUT_READ_TOTAL_CONSTANT; 
    CommTimeOuts.WriteTotalTimeoutMultiplier= TIMEOUT_WRITE_TOTAL_MULTIPLIER; 
    CommTimeOuts.WriteTotalTimeoutConstant = TIMEOUT_WRITE_TOTAL_CONSTANT;  
    SetCommTimeouts(m_hCom, &CommTimeOuts); 

    //设置波特率
//    wsprintf(aComParams, _T("COM%d:%d, N, 8, 1"), port, baund);

    // 设置异步读取/写入监视事件   
    m_overlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_overlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    //读取、设置串口设备参数
    dcb.DCBlength = sizeof(DCB);
    GetCommState(m_hCom, &dcb);
    dcb.BaudRate = baund; 
    dcb.ByteSize = byteSize; 
    
    unsigned char ucSet;   
    ucSet = (UINT8)((FC_RTSCTS & FC_DTRDSR ) != 0);    
    ucSet = (UINT8)((FC_RTSCTS & FC_RTSCTS ) != 0);   
    ucSet = (UINT8)((FC_RTSCTS & FC_XONXOFF ) != 0);  

    if (!SetCommState(m_hCom, &dcb) 
            || !SetupComm(m_hCom, BUFFER_INPUT_RECOMMEND, BUFFER_OUTPUT_RECOMMEND)
            || m_overlappedRead.hEvent == NULL 
            || m_overlappedWrite.hEvent == NULL)
    {
        m_dwError = GetLastError();
        
        if (m_overlappedRead.hEvent != NULL)
        {
            CloseHandle(m_overlappedRead.hEvent);
        }
        
        if (m_overlappedWrite.hEvent != NULL) 
        {
            CloseHandle(m_overlappedWrite.hEvent);
        }
        
        CloseHandle(m_hCom);
        return false;
    }  

    m_bOpened = true;
    return true;
}

int MySerial::WriteData(const char *pBuffer, int size)
{
    if ((!m_bOpened) || (m_hCom == INVALID_HANDLE_VALUE))
    {
        return 0;
    }
    
    int bytesWritten = 0; 
    int i;
    for (i = 0; i < size; i++)
    {
        WriteCommByte(pBuffer[i]);
        bytesWritten++; 
    }
    
    return bytesWritten; 
}

int MySerial::ReadData(void *pBuffer, int limit)
{
    if ((!m_bOpened) || (m_hCom == INVALID_HANDLE_VALUE))
    {
        return 0;
    }
    
    BOOL readStatus;
    DWORD bytesRead;
    DWORD errorFlags; 
    COMSTAT comStat;
    
    //读取之前须清楚错误信息    
    ClearCommError(m_hCom, &errorFlags, &comStat);
    if (!comStat.cbInQue)
    {
        return 0;
    }
    
    bytesRead = comStat.cbInQue; 
    if (limit < (int)bytesRead) 
    {
        bytesRead = (DWORD)limit;
    }
    
    readStatus = ReadFile(m_hCom, pBuffer, bytesRead, &bytesRead, &m_overlappedRead);
    
    //查询异步读取是否完成,未完成则挂起等待   
    if (!readStatus)
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            WaitForSingleObject(m_overlappedRead.hEvent, TIMEOUT_READCOMM_EVENT);
            return ((int)bytesRead);
        }
        
        return 0;
    }
    
    return ((int)bytesRead); 
}


void serial_init(void)
{
    serial_opened = 0;
    m_serial.m_hCom = NULL;

}

int serial_open(int baund,int nPort)
{
   if(  m_serial.Open(nPort,baund) )
   {
       serial_opened =1;
   }
   else
   {
       serial_opened = 0;
   }
   return serial_opened;
}


void serial_close()
{
    CloseHandle(m_serial.m_hCom);
    m_serial.m_hCom = NULL;
}

int serial_write_string(const char *buffer)
{
//    int slip_encapsulate(const void *psrcbuf,const int srclen,void *pdstbuf,int *dstlen)
    char buf[1024]={0};
    int len = 0;
    int size = strlen(buffer);
    slip_encapsulate(buffer,size,buf,&len);
    return m_serial.WriteData(buf,len);
    //slip_encapsulate(0,0,0,0);
}

int serial_write(const char *buffer, int size)
{
   return m_serial.WriteData(buffer,size);
}


int serial_read(void *buffer, int limit)
{
    return m_serial.ReadData(buffer,limit);
}


int serial_isopen(void)
{
    return serial_opened;
}

 

posted @ 2017-09-12 15:45  未命名blogs  阅读(451)  评论(0编辑  收藏  举报