博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VC 串口通信类
阅读量:7221 次
发布时间:2019-06-29

本文共 12450 字,大约阅读时间需要 41 分钟。

为了节省时间,我就贴出来吧

头文件 SerialPort.h

1 /*************************************************************************************************** 2 * SerialPort.h 3 * 4 * 功 能:串口通讯类 5 * 类 名:CSerialPort 6 * 7 * Ver        变更日期             负责人      变更内容 8 * ───────────────────────────────────────────────────── 9 * V1.0.0.0   2015年8月27日       金胖胖        新建10 *11 *****************************************************************************************************/12 13 #pragma once14 #include "StdAfx.h"15 16 #define FC_DTRDSR       0x0117 #define FC_RTSCTS       0x0218 #define FC_XONXOFF      0x0419 #define ASCII_BEL       0x0720 #define ASCII_BS        0x0821 #define ASCII_LF        0x0A22 #define ASCII_CR        0x0D23 #define ASCII_XON       0x1124 #define ASCII_XOFF      0x1325 26 class CSerial27 {28 public:    29     CSerial();30     ~CSerial();31 32     // 打开串口 33     BOOL Open( int nPort = 2, int nBaud = 9600 ); 34 35     // 关闭串口36     BOOL Close( void );    37 38     // 读取数据39     int ReadData( void *, int ); 40 41      //发送数据42     int SendData( const char *, int );43 44     // 45     int ReadDataWaiting( void ); 46 47     // 是否打开串口48     BOOL IsOpened( void ); 49 50     // 清空缓冲区51     void ClearBuffer(void);  52 53     // 获取计算机中的所有串口号54     vector
GetPortNames(); 55 56 // 十六进制数据 转换到 字符串57 CString HexToStr(unsigned char *lpDataBuffer,int Total);58 protected:59 60 BOOL WriteCommByte( unsigned char );61 HANDLE m_hIDComDev; // 串口文件句柄62 OVERLAPPED m_OverlappedRead;63 OVERLAPPED m_OverlappedWrite;64 BOOL m_bOpened; // 是否打开标识65 };
View Code

 

实现文件 SerialPort.cpp

1 /***************************************************************************************************  2 * Serial.cpp  3 *  4 * 功 能:串口通讯类  5 * 类 名:CSerial  6 * 参考文献:http://blog.csdn.net/zw0558/article/details/4465835  7 * 参考文献:http://blog.csdn.net/cp1300/article/details/40591699  8 * 参考文献:http://dev.21tx.com/2001/08/01/10054.shtml  9 * Ver        变更日期             负责人      变更内容 10 * ───────────────────────────────────────────────────── 11 * V1.0.0.0   2015年8月27日       金胖胖        新建 12 * 13 *****************************************************************************************************/ 14 #pragma region Include 15  16 #include "stdafx.h" 17 #include "Serial.h" 18 CRITICAL_SECTION sec; 19  20 #pragma endregion Include 21  22 #pragma region 构造 析构函数 23  24 CSerial::CSerial() 25 { 26  27     memset( &this->m_OverlappedRead, 0, sizeof( OVERLAPPED ) ); 28      memset( &this->m_OverlappedWrite, 0, sizeof( OVERLAPPED ) ); 29     this->m_hIDComDev = NULL; 30     this->m_bOpened = FALSE; 31  32 } 33  34  35 CSerial::~CSerial() 36 { 37     this->Close(); 38 } 39  40 #pragma endregion 构造 析构函数 41  42 /***************************************************/ 43 /*  函数: 获取计算机中的所有串口号 44 /*    返回: vector
45 /* 创建人: 日期 内容 46 /* 金胖胖 2015年8月27日 新建 47 /***************************************************/ 48 vector
CSerial::GetPortNames() 49 { 50 vector
vecArr; 51 52 int i = 0; 53 CHAR Name[25]; 54 UCHAR szPortName[25]; 55 LONG Status; 56 DWORD dwIndex = 0; 57 DWORD dwName; 58 DWORD dwSizeofPortName; 59 DWORD Type; 60 HKEY hKey; 61 CString strSerialList[256]; // 临时定义 256 个字符串组,因为系统最多也就 256 个 62 LPCTSTR data_Set="HARDWARE\\DEVICEMAP\\SERIALCOMM\\"; 63 dwName = sizeof(Name); 64 dwSizeofPortName = sizeof(szPortName); 65 long ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey); //打开一个制定的注册表键,成功返回ERROR_SUCCESS即“0”值 66 if(ret0 == ERROR_SUCCESS) 67 { 68 do 69 { 70 Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type, szPortName, &dwSizeofPortName);//读取键值 71 if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA)) 72 { 73 strSerialList[i] = CString(szPortName); // 串口字符串保存 74 vecArr.push_back(strSerialList[i].GetBuffer(0)); 75 i++;// 串口计数 76 } 77 //每读取一次dwName和dwSizeofPortName都会被修改 78 //注意一定要重置,否则会出现很离奇的错误,本人就试过因没有重置,出现先插入串口号大的(如COM4),再插入串口号小的(如COM3),此时虽能发现两个串口,但都是同一串口号(COM4)的问题,同时也读不了COM大于10以上的串口 79 dwName = sizeof(Name); 80 dwSizeofPortName = sizeof(szPortName); 81 } while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA)); 82 RegCloseKey(hKey); 83 } 84 return vecArr ; 85 } 86 87 /***************************************************/ 88 /* 函数: 打开串口 89 /* 参数: int 串口号 90 /* 参数: int 波特率 91 /* 返回: BOOL 是否成功 92 /* 创建人: 日期 内容 93 /* 金胖胖 2015年8月31日 新建 94 /***************************************************/ 95 BOOL CSerial::Open( int nPort, int nBaud ) 96 { 97 98 DWORD dwErrorFlags; 99 COMSTAT ComStat;100 101 ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat );102 103 if( this->m_bOpened ) return( TRUE );104 105 char szPort[15];106 char szComParams[50];107 DCB dcb;108 109 wsprintf( szPort, "COM%d", nPort );110 this->m_hIDComDev = ::CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );111 if( this->m_hIDComDev == NULL ) return( FALSE );112 113 memset( &this->m_OverlappedRead, 0, sizeof( OVERLAPPED ) );114 memset( &this->m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );115 116 COMMTIMEOUTS CommTimeOuts;117 CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;118 CommTimeOuts.ReadTotalTimeoutMultiplier = 0;119 CommTimeOuts.ReadTotalTimeoutConstant = 0;120 CommTimeOuts.WriteTotalTimeoutMultiplier = 0;121 CommTimeOuts.WriteTotalTimeoutConstant = 5000;122 ::SetCommTimeouts( this->m_hIDComDev, &CommTimeOuts );123 124 wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );125 126 this->m_OverlappedRead.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );127 this->m_OverlappedWrite.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );128 129 dcb.DCBlength = sizeof( DCB );130 ::GetCommState( m_hIDComDev, &dcb );131 dcb.BaudRate = nBaud;132 dcb.ByteSize = 8;133 unsigned char ucSet;134 ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );135 ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );136 ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );137 if( !::SetCommState( this->m_hIDComDev, &dcb ) ||!::SetupComm( this->m_hIDComDev, 10000, 10000 ) ||this->m_OverlappedRead.hEvent == NULL ||this->m_OverlappedWrite.hEvent == NULL )138 {139 DWORD dwError = GetLastError();140 if( this->m_OverlappedRead.hEvent != NULL ) ::CloseHandle( this->m_OverlappedRead.hEvent );141 if( this->m_OverlappedWrite.hEvent != NULL ) ::CloseHandle( this->m_OverlappedWrite.hEvent );142 ::CloseHandle( this->m_hIDComDev );143 return( FALSE );144 }145 146 this->m_bOpened = TRUE;147 return( this->m_bOpened );148 149 }150 151 /***************************************************/152 /* 函数: 关闭函数153 /* 返回: BOOL 是否成功154 /* 创建人: 日期 内容155 /* 金胖胖 2015年8月31日 新建156 /***************************************************/157 BOOL CSerial::Close( void )158 {159 160 if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( TRUE );161 162 if( this->m_OverlappedRead.hEvent != NULL ) ::CloseHandle( this->m_OverlappedRead.hEvent );163 if( this->m_OverlappedWrite.hEvent != NULL ) ::CloseHandle( this->m_OverlappedWrite.hEvent );164 ::CloseHandle( this->m_hIDComDev );165 this->m_bOpened = FALSE;166 this->m_hIDComDev = NULL;167 return( TRUE );168 169 }170 171 /***************************************************/172 /* 函数: 写串口数据 字节173 /* 参数: unsigned char 字节174 /* 返回: BOOL 是否成功175 /* 创建人: 日期 内容176 /* 金胖胖 2015年8月31日 新建177 /***************************************************/178 BOOL CSerial::WriteCommByte( unsigned char ucByte )179 {180 BOOL bWriteStat;181 DWORD dwBytesWritten;182 183 bWriteStat = ::WriteFile( this->m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );184 if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){185 if( ::WaitForSingleObject( this->m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;186 else{187 ::GetOverlappedResult( this->m_hIDComDev, &this->m_OverlappedWrite, &dwBytesWritten, FALSE );188 this->m_OverlappedWrite.Offset += dwBytesWritten;189 }190 }191 192 return( TRUE );193 194 }195 196 /***************************************************/197 /* 函数: 发送数据198 /* 参数: const char 缓冲区199 /* 参数: int 长度200 /* 返回: int 发送的成功的长度201 /* 创建人: 日期 内容202 /* 金胖胖 2015年8月31日 新建203 /***************************************************/204 int CSerial::SendData( const char *buffer, int size )205 {206 207 if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( 0 );208 209 DWORD dwBytesWritten = 0;210 int i;211 for( i=0; i
WriteCommByte( buffer[i] );213 dwBytesWritten++;214 }215 return( (int) dwBytesWritten );216 }217 218 /***************************************************/219 /* 函数: 清除错误信息 获取通讯状态220 /* 返回: int 通讯状态221 /* 创建人: 日期 内容222 /* 金胖胖 2015年8月31日 新建223 /***************************************************/224 int CSerial::ReadDataWaiting( void )225 {226 227 if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( 0 );228 229 DWORD dwErrorFlags;230 COMSTAT ComStat;231 232 ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat );233 234 return( (int) ComStat.cbInQue );235 236 }237 238 /***************************************************/239 /* 函数: 读取数据240 /* 参数: void * 缓冲区241 /* 参数: int 缓冲区长度242 /* 返回: int 读到的字节数243 /* 创建人: 日期 内容244 /* 金胖胖 2015年8月31日 新建245 /***************************************************/246 int CSerial::ReadData( void *buffer, int limit )247 {248 249 if( !this->m_bOpened || this->m_hIDComDev == NULL ) 250 return( 0 );251 252 BOOL bReadStatus;253 DWORD dwBytesRead, dwErrorFlags;254 COMSTAT ComStat;255 256 ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat );//清空错误信息257 if( !ComStat.cbInQue ) 258 return( 0 );259 260 dwBytesRead = (DWORD) ComStat.cbInQue;261 if( limit < (int) dwBytesRead ) 262 dwBytesRead = (DWORD) limit;263 264 bReadStatus = ::ReadFile( this->m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );265 if( !bReadStatus )266 {267 if( GetLastError() == ERROR_IO_PENDING )268 {269 ::WaitForSingleObject( this->m_OverlappedRead.hEvent, 2000 );270 return( (int) dwBytesRead );271 }272 return( 0 );273 }274 275 return( (int) dwBytesRead );276 }277 278 /***************************************************/279 /* 函数: 清空缓冲区 280 /* 返回: void 281 /* 创建人: 日期 内容282 /* 金胖胖 2015年8月31日 新建283 /***************************************************/284 void CSerial::ClearBuffer()285 {286 ::PurgeComm(this->m_hIDComDev,PURGE_RXABORT | PURGE_RXCLEAR );//| PURGE_TXABORT | PURGE_TXCLEAR287 }288 289 /***************************************************/290 /* 函数: 串口是否打开291 /* 返回: BOOL 是否打开292 /* 创建人: 日期 内容293 /* 金胖胖 2015年8月31日 新建294 /***************************************************/295 BOOL CSerial::IsOpened( void )296 {297 return( this->m_bOpened ); 298 }299 300 /***************************************************/301 /* 函数: 十六进制数据 转换到 字符串302 /* 参数: unsigned char * 缓冲区303 /* 参数: int 长度304 /* 返回: CString 转换成功的字符串305 /* 创建人: 日期 内容306 /* 金胖胖 2015年8月31日 新建307 /***************************************************/308 CString CSerial::HexToStr(unsigned char *lpDataBuffer,int Total)309 {310 CString ReturnStr;311 char OneNumber[5];312 313 ReturnStr.Empty();314 memset(OneNumber,0,5);315 316 for(int i=0;i
View Code

 

转载于:https://www.cnblogs.com/-jpp/p/4773856.html

你可能感兴趣的文章
裂变问题
查看>>
使用oracle外部表进行数据泵卸载数据
查看>>
弹出消息对话框ScriptManager
查看>>
WEB打印(jsp版)
查看>>
URLEncode与URLDecode总结与实现
查看>>
Gradle 多渠道打包的使用和错误分析(转)
查看>>
64位调试器花费的时间比预期的要长(A 64-bit debugging operation is taking longer than expected)...
查看>>
压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate
查看>>
ECShop模板原理
查看>>
STL学习系列六:List容器
查看>>
LFS 中文版手册发布:如何打造自己的 Linux 发行版
查看>>
spring 第一篇(1-1):让java开发变得更简单(下)转
查看>>
Java定位CPU使用高问题--转载
查看>>
ADO.NET与Oracle(一):获取多行记录集
查看>>
C/C++程序员必须熟练应用的开源项目
查看>>
python 时间及日期函数
查看>>
SMTP 简单邮件传输协议
查看>>
Python实现二叉树的存储和遍历
查看>>
国外人工智能界牛人主页
查看>>
Android 自定义View合集
查看>>