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

头文件 SerialPort.h

 /***************************************************************************************************
* SerialPort.h
*
* 功 能:串口通讯类
* 类 名:CSerialPort
*
* Ver 变更日期 负责人 变更内容
* ─────────────────────────────────────────────────────
* V1.0.0.0 2015年8月27日 金胖胖 新建
*
*****************************************************************************************************/ #pragma once
#include "StdAfx.h" #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 class CSerial
{
public:
CSerial();
~CSerial(); // 打开串口
BOOL Open( int nPort = , int nBaud = ); // 关闭串口
BOOL Close( void ); // 读取数据
int ReadData( void *, int ); //发送数据
int SendData( const char *, int ); //
int ReadDataWaiting( void ); // 是否打开串口
BOOL IsOpened( void ); // 清空缓冲区
void ClearBuffer(void); // 获取计算机中的所有串口号
vector<string> GetPortNames(); // 十六进制数据 转换到 字符串
CString HexToStr(unsigned char *lpDataBuffer,int Total);
protected: BOOL WriteCommByte( unsigned char );
HANDLE m_hIDComDev; // 串口文件句柄
OVERLAPPED m_OverlappedRead;
OVERLAPPED m_OverlappedWrite;
BOOL m_bOpened; // 是否打开标识
};

实现文件 SerialPort.cpp

 /***************************************************************************************************
* Serial.cpp
*
* 功 能:串口通讯类
* 类 名:CSerial
* 参考文献:http://blog.csdn.net/zw0558/article/details/4465835
* 参考文献:http://blog.csdn.net/cp1300/article/details/40591699
* 参考文献:http://dev.21tx.com/2001/08/01/10054.shtml
* Ver 变更日期 负责人 变更内容
* ─────────────────────────────────────────────────────
* V1.0.0.0 2015年8月27日 金胖胖 新建
*
*****************************************************************************************************/
#pragma region Include #include "stdafx.h"
#include "Serial.h"
CRITICAL_SECTION sec; #pragma endregion Include #pragma region 构造 析构函数 CSerial::CSerial()
{ memset( &this->m_OverlappedRead, , sizeof( OVERLAPPED ) );
memset( &this->m_OverlappedWrite, , sizeof( OVERLAPPED ) );
this->m_hIDComDev = NULL;
this->m_bOpened = FALSE; } CSerial::~CSerial()
{
this->Close();
} #pragma endregion 构造 析构函数 /***************************************************/
/* 函数: 获取计算机中的所有串口号
/* 返回: vector<string>
/* 创建人: 日期 内容
/* 金胖胖 2015年8月27日 新建
/***************************************************/
vector<string> CSerial::GetPortNames()
{
vector<string> vecArr; int i = ;
CHAR Name[];
UCHAR szPortName[];
LONG Status;
DWORD dwIndex = ;
DWORD dwName;
DWORD dwSizeofPortName;
DWORD Type;
HKEY hKey;
CString strSerialList[]; // 临时定义 256 个字符串组,因为系统最多也就 256 个
LPCTSTR data_Set="HARDWARE\\DEVICEMAP\\SERIALCOMM\\";
dwName = sizeof(Name);
dwSizeofPortName = sizeof(szPortName);
long ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, , KEY_READ, &hKey); //打开一个制定的注册表键,成功返回ERROR_SUCCESS即“0”值
if(ret0 == ERROR_SUCCESS)
{
do
{
Status = RegEnumValue(hKey, dwIndex++, Name, &dwName, NULL, &Type, szPortName, &dwSizeofPortName);//读取键值
if((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA))
{
strSerialList[i] = CString(szPortName); // 串口字符串保存
vecArr.push_back(strSerialList[i].GetBuffer());
i++;// 串口计数
}
//每读取一次dwName和dwSizeofPortName都会被修改
//注意一定要重置,否则会出现很离奇的错误,本人就试过因没有重置,出现先插入串口号大的(如COM4),再插入串口号小的(如COM3),此时虽能发现两个串口,但都是同一串口号(COM4)的问题,同时也读不了COM大于10以上的串口
dwName = sizeof(Name);
dwSizeofPortName = sizeof(szPortName);
} while((Status == ERROR_SUCCESS)||(Status == ERROR_MORE_DATA));
RegCloseKey(hKey);
}
return vecArr ;
} /***************************************************/
/* 函数: 打开串口
/* 参数: int 串口号
/* 参数: int 波特率
/* 返回: BOOL 是否成功
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
BOOL CSerial::Open( int nPort, int nBaud )
{ DWORD dwErrorFlags;
COMSTAT ComStat; ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat ); if( this->m_bOpened ) return( TRUE ); char szPort[];
char szComParams[];
DCB dcb; wsprintf( szPort, "COM%d", nPort );
this->m_hIDComDev = ::CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( this->m_hIDComDev == NULL ) return( FALSE ); memset( &this->m_OverlappedRead, , sizeof( OVERLAPPED ) );
memset( &this->m_OverlappedWrite, , sizeof( OVERLAPPED ) ); COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = ;
CommTimeOuts.ReadTotalTimeoutConstant = ;
CommTimeOuts.WriteTotalTimeoutMultiplier = ;
CommTimeOuts.WriteTotalTimeoutConstant = ;
::SetCommTimeouts( this->m_hIDComDev, &CommTimeOuts ); wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud ); this->m_OverlappedRead.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
this->m_OverlappedWrite.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL ); dcb.DCBlength = sizeof( DCB );
::GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = ;
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != );
if( !::SetCommState( this->m_hIDComDev, &dcb ) ||!::SetupComm( this->m_hIDComDev, , ) ||this->m_OverlappedRead.hEvent == NULL ||this->m_OverlappedWrite.hEvent == NULL )
{
DWORD dwError = GetLastError();
if( this->m_OverlappedRead.hEvent != NULL ) ::CloseHandle( this->m_OverlappedRead.hEvent );
if( this->m_OverlappedWrite.hEvent != NULL ) ::CloseHandle( this->m_OverlappedWrite.hEvent );
::CloseHandle( this->m_hIDComDev );
return( FALSE );
} this->m_bOpened = TRUE;
return( this->m_bOpened ); } /***************************************************/
/* 函数: 关闭函数
/* 返回: BOOL 是否成功
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
BOOL CSerial::Close( void )
{ if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( TRUE ); if( this->m_OverlappedRead.hEvent != NULL ) ::CloseHandle( this->m_OverlappedRead.hEvent );
if( this->m_OverlappedWrite.hEvent != NULL ) ::CloseHandle( this->m_OverlappedWrite.hEvent );
::CloseHandle( this->m_hIDComDev );
this->m_bOpened = FALSE;
this->m_hIDComDev = NULL;
return( TRUE ); } /***************************************************/
/* 函数: 写串口数据 字节
/* 参数: unsigned char 字节
/* 返回: BOOL 是否成功
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten; bWriteStat = ::WriteFile( this->m_hIDComDev, (LPSTR) &ucByte, , &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
if( ::WaitForSingleObject( this->m_OverlappedWrite.hEvent, ) ) dwBytesWritten = ;
else{
::GetOverlappedResult( this->m_hIDComDev, &this->m_OverlappedWrite, &dwBytesWritten, FALSE );
this->m_OverlappedWrite.Offset += dwBytesWritten;
}
} return( TRUE ); } /***************************************************/
/* 函数: 发送数据
/* 参数: const char 缓冲区
/* 参数: int 长度
/* 返回: int 发送的成功的长度
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
int CSerial::SendData( const char *buffer, int size )
{ if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( ); DWORD dwBytesWritten = ;
int i;
for( i=; i<size; i++ ){
this->WriteCommByte( buffer[i] );
dwBytesWritten++;
}
return( (int) dwBytesWritten );
} /***************************************************/
/* 函数: 清除错误信息 获取通讯状态
/* 返回: int 通讯状态
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
int CSerial::ReadDataWaiting( void )
{ if( !this->m_bOpened || this->m_hIDComDev == NULL ) return( ); DWORD dwErrorFlags;
COMSTAT ComStat; ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat ); return( (int) ComStat.cbInQue ); } /***************************************************/
/* 函数: 读取数据
/* 参数: void * 缓冲区
/* 参数: int 缓冲区长度
/* 返回: int 读到的字节数
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
int CSerial::ReadData( void *buffer, int limit )
{ if( !this->m_bOpened || this->m_hIDComDev == NULL )
return( ); BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat; ::ClearCommError( this->m_hIDComDev, &dwErrorFlags, &ComStat );//清空错误信息
if( !ComStat.cbInQue )
return( ); dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead )
dwBytesRead = (DWORD) limit; bReadStatus = ::ReadFile( this->m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus )
{
if( GetLastError() == ERROR_IO_PENDING )
{
::WaitForSingleObject( this->m_OverlappedRead.hEvent, );
return( (int) dwBytesRead );
}
return( );
} return( (int) dwBytesRead );
} /***************************************************/
/* 函数: 清空缓冲区
/* 返回: void
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
void CSerial::ClearBuffer()
{
::PurgeComm(this->m_hIDComDev,PURGE_RXABORT | PURGE_RXCLEAR );//| PURGE_TXABORT | PURGE_TXCLEAR
} /***************************************************/
/* 函数: 串口是否打开
/* 返回: BOOL 是否打开
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
BOOL CSerial::IsOpened( void )
{
return( this->m_bOpened );
} /***************************************************/
/* 函数: 十六进制数据 转换到 字符串
/* 参数: unsigned char * 缓冲区
/* 参数: int 长度
/* 返回: CString 转换成功的字符串
/* 创建人: 日期 内容
/* 金胖胖 2015年8月31日 新建
/***************************************************/
CString CSerial::HexToStr(unsigned char *lpDataBuffer,int Total)
{
CString ReturnStr;
char OneNumber[]; ReturnStr.Empty();
memset(OneNumber,,); for(int i=;i<Total;i++)
{
itoa(lpDataBuffer[i],OneNumber,); if(strlen(OneNumber) < )
{
OneNumber[] = OneNumber[];
OneNumber[] = OneNumber[];
OneNumber[] = '';
}
ReturnStr+=OneNumber;
ReturnStr+=",";
memset(OneNumber,,);
} return ReturnStr;
}

VC 串口通信类的更多相关文章

  1. 串口通信类,WPF

    参考之前的资料,写了一个自己常用的串口类, 字符串发送类型用了两种方式,char[] 和byte[] : 数据接收也是采用两种 char[] 和byte[] 两种. 类代码贴出来: public cl ...

  2. c#串口通信类代码可以直接调用

    文章首发于浩瀚先森博客 直接上代码 public struct SerialPara { private string portName; public string PortNameSetGet { ...

  3. 一个由印度人编写的VC串口类

    http://www.cnblogs.com/lwngreat/p/4098374.html 软件介绍 一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些 ...

  4. (转载)用vs2010开发基于VC++的MFC 串口通信一*****两台电脑同一个串口号之间的通信

    此文章以visual C++数据採集与串口通信測控应用实战为參考教程 此文章适合VC++串口通信入门 一.页面布局及加入控件 1, 安装好vs2010如图 2, 新建一个基于VC++的MFC项目com ...

  5. boost实现串口通信(一):小试牛刀

    /************************************************************************/ /* 功能:boost实现串口通信类 */ /* ...

  6. Qt 串口通信

    在Qt5之前,串口通信基本依赖于第三方库,下面是我曾接触过的串口通信类库: 名称 语言 平台   QextSerialPort QT C++ Win/Linux http://sourceforge. ...

  7. java 串口通信 代码

    下面是我自己实现的串口接收的类,串口发送比较简单,就直接发送就可以了.下面的这个类可以直接使用. package com.boomdts.weather_monitor.util; import ja ...

  8. Qt串口通信

    1. Qt串口通信类QSerialPort 在Qt5的的更新中,新增了串口通信的相关接口类QSerialPort,这使得在开发者在使用Qt进行UI开发时,可以更加简单有效地实现串口通信的相关功能. 开 ...

  9. C\C++串口通信编程的一点技术记录

    新工作接的第一个活,要写一个配合设备调试的上位机程序. 除了MFC界面的部分,就是要处理几条命令. 串口通信部分代码借鉴的是这一篇文章:http://blog.sina.com.cn/s/blog_a ...

随机推荐

  1. Android 虚拟机快捷键

    何须这样麻烦,直接用快捷键就行了,你用鼠标点来点去怎么还不如用快捷键来得快:一下是快捷键: Home键(小房子键) 在键盘上映射的就是home键,这倒是很好记. Menu键 用于打开菜单的按键,在键盘 ...

  2. WinForm(C#)自定义控件之——RoundButton(圆形按钮)

    最近需要做一个圆形的按钮,去CodeProject找了一下,发现有现成的可用,但不能完全满足我的需求.因此自己试着利用WinForm中的自定义组件功能,制作一个圆形按钮.圆形按钮小制作即将开始之前,先 ...

  3. Java系列--第八篇 基于Maven的SSME之定时邮件发送

    关于ssme这个我的小示例项目,想做到麻雀虽小,五脏俱全,看到很多一些web都有定时发送邮件的功能,想我ssme也加入一下这种功能,经查询相关文档,发现spring本身自带了一个调度器quartz,下 ...

  4. 教训 Mac下装windows系统 失败后 磁盘空间丢失

    本来Mac上装的是win10 最近老提示快过期了 想到月底就要停止免费更新了 决定装一下win8 然后升级到win10 因为之前有过装win10的经验 所以很轻松 进入Mac 先到bootcamp 取 ...

  5. jQuery 幻灯片 ----摘录

    Cloud Carousel (演示 | 下载) ShineTime (演示 | 下载) Nivo Slider (演示 | 下载) Interactive Photo Desk (演示 | 下载) ...

  6. resumable.js —— 基于 HTML 5 File API 的文件上传组件 支持续传后台c#实现

    在git上提供了java.nodejs.c#后台服务方式:在这里我要用c#作为后台服务:地址请见:https://github.com/23/resumable.js 我现在visual studio ...

  7. Spring boot构建基于rest的Web服务

    一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Mav ...

  8. Swift类和结构体定义-备

    Swift中的类和结构体定义的语法是非常相似的.类使用class关键词定义类,使用struct关键词定义结构体,它们的语法格式如下: class 类名 { 定义类的成员 } struct 结构体名 { ...

  9. 『安全工具』目录扫描 DirBuster AND 御剑

    要想熟悉目标网站的体系架构,知道网站有哪些目录是必不可少的 向AWVS,Burp类大型扫描工具也可以进行目录扫描,不过个人感觉远没有专业扫描工具来的简单,实在 0x 01 DirBuster 简介:D ...

  10. 使用Query 进行空值(empty)校验

    效果如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...