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; }
联系方式:heshengjun@tinywsn.com