在windows程序设计与开发过程中,特别是涉及到开发嵌入式软硬件系统时,往往会涉及到串口编程。网上以及一些书籍上讲解windows下的串口编程
知识也挺多的,但我个人觉得,看完书上的知识点有时依然不知道该如何下手开始自己的程序设计和代码编写,许多知识如果能结合着详细的例子往往能够帮助我们
学习得更快,所以,在此,我专门为串口编程初学者设计了一个详细的例子,供大家参考和学习。
下面我将自己用C++编写的串口通信的例子贴出来,其特点如下:
1. 本例子使用了比较规范的软件设计方法,类的设计具有比较好的可扩展性和移植性、代码的注释采用doxgen支持的javaDoc风格。
2. 为了能方便初学者更快地了解和入门,几乎每一行代码都加上了详细的注释,对于注释中如果依然有不清楚的概念,相信你通过百度和google一定能找到答案。
3. 本例子设计的串口操作类可以直接移植到其他的工程中去,大家也可以根据自己的需要添加其他的接口。
4.
本例子只实现了串口数据的基本收发功能,其实为了保证串口数据传输的正确性,往往需要设计一些串口通信协议,协议的设计有待你自己完成,如果以后有时间,
我也会尝试提供一种比较基本的串口通信协议设计案例给大家学习。
5. 关于本程序的验证方法,可以使用虚拟串口软件VSPM和串口调试助手进行程序的测试与验证,上述两个软件的使用方法请参考:http://ticktick.blog.51cto.com/823160/285610
下面即为例子工程的三个文件,SerialPort.h、SerialPort.cpp、maincpp
附件中是工程文件,需要使用vs2008打开
。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#ifndefSERIALPORT_H_
-
#defineSERIALPORT_H_
-
-
#include<Windows.h>
-
-
-
-
-
-
-
class
CSerialPort
-
{
-
public
:
-
CSerialPort(
void
);
-
~CSerialPort(
void
);
-
-
public
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
bool
InitPort(
UINT
portNo=1,
UINT
baud=CBR_9600,
char
parity=
'N'
,
UINT
databits=8,
UINT
stopsbits=1,
DWORD
dwCommEvents=EV_RXCHAR);
-
-
-
-
-
-
-
-
-
-
-
bool
InitPort(
UINT
portNo,
const
LPDCB&plDCB);
-
-
-
-
-
-
-
-
-
bool
OpenListenThread();
-
-
-
-
-
-
-
-
-
bool
CloseListenTread();
-
-
-
-
-
-
-
-
-
-
-
bool
WriteData(unsigned
char
*pData,unsigned
int
length);
-
-
-
-
-
-
-
-
-
UINT
GetBytesInCOM();
-
-
-
-
-
-
-
-
-
-
bool
ReadChar(
char
&cRecved);
-
-
private
:
-
-
-
-
-
-
-
-
-
-
bool
openPort(
UINT
portNo);
-
-
-
-
-
-
-
-
-
void
ClosePort();
-
-
-
-
-
-
-
-
-
-
static
UINT
WINAPIListenThread(
void
*pParam);
-
-
private
:
-
-
-
HANDLE
m_hComm;
-
-
-
static
bool
s_bExit;
-
-
-
volatile
HANDLE
m_hListenThread;
-
-
-
CRITICAL_SECTIONm_csCommunicationSync;
-
-
};
-
-
#endif//SERIALPORT_H_
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#include"StdAfx.h"
-
#include"SerialPort.h"
-
#include<process.h>
-
#include<iostream>
-
-
-
bool
CSerialPort::s_bExit=
false
;
-
-
const
UINT
SLEEP_TIME_INTERVAL=5;
-
-
CSerialPort::CSerialPort(
void
)
-
:m_hListenThread(INVALID_HANDLE_VALUE)
-
{
-
m_hComm=INVALID_HANDLE_VALUE;
-
m_hListenThread=INVALID_HANDLE_VALUE;
-
-
InitializeCriticalSection(&m_csCommunicationSync);
-
-
}
-
-
CSerialPort::~CSerialPort(
void
)
-
{
-
CloseListenTread();
-
ClosePort();
-
DeleteCriticalSection(&m_csCommunicationSync);
-
}
-
-
bool
CSerialPort::InitPort(
UINT
portNo
,
UINT
baud
,
char
parity
,
-
UINT
databits
,
UINT
stopsbits
,
DWORD
dwCommEvents
)
-
{
-
-
-
char
szDCBparam[50];
-
sprintf_s(szDCBparam,
"baud=%dparity=%cdata=%dstop=%d"
,baud,parity,databits,stopsbits);
-
-
-
if
(!openPort(portNo))
-
{
-
return
false
;
-
}
-
-
-
EnterCriticalSection(&m_csCommunicationSync);
-
-
-
BOOL
bIsSuccess=TRUE;
-
-
-
-
-
-
-
-
-
-
-
COMMTIMEOUTSCommTimeouts;
-
CommTimeouts.ReadIntervalTimeout=0;
-
CommTimeouts.ReadTotalTimeoutMultiplier=0;
-
CommTimeouts.ReadTotalTimeoutConstant=0;
-
CommTimeouts.WriteTotalTimeoutMultiplier=0;
-
CommTimeouts.WriteTotalTimeoutConstant=0;
-
if
(bIsSuccess)
-
{
-
bIsSuccess=SetCommTimeouts(m_hComm,&CommTimeouts);
-
}
-
-
DCBdcb;
-
if
(bIsSuccess)
-
{
-
-
DWORD
dwNum=MultiByteToWideChar(CP_ACP,0,szDCBparam,-1,NULL,0);
-
wchar_t
*pwText=
new
wchar_t
[dwNum];
-
if
(!MultiByteToWideChar(CP_ACP,0,szDCBparam,-1,pwText,dwNum))
-
{
-
bIsSuccess=TRUE;
-
}
-
-
-
bIsSuccess=GetCommState(m_hComm,&dcb)&&BuildCommDCB(pwText,&dcb);
-
-
dcb.fRtsControl=RTS_CONTROL_ENABLE;
-
-
-
delete
[]pwText;
-
}
-
-
if
(bIsSuccess)
-
{
-
-
bIsSuccess=SetCommState(m_hComm,&dcb);
-
}
-
-
-
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
-
-
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
bIsSuccess==TRUE;
-
}
-
-
bool
CSerialPort::InitPort(
UINT
portNo,
const
LPDCB&plDCB)
-
{
-
-
if
(!openPort(portNo))
-
{
-
return
false
;
-
}
-
-
-
EnterCriticalSection(&m_csCommunicationSync);
-
-
-
if
(!SetCommState(m_hComm,plDCB))
-
{
-
return
false
;
-
}
-
-
-
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
-
-
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
true
;
-
}
-
-
void
CSerialPort::ClosePort()
-
{
-
-
if
(m_hComm!=INVALID_HANDLE_VALUE)
-
{
-
CloseHandle(m_hComm);
-
m_hComm=INVALID_HANDLE_VALUE;
-
}
-
}
-
-
bool
CSerialPort::openPort(
UINT
portNo)
-
{
-
-
EnterCriticalSection(&m_csCommunicationSync);
-
-
-
char
szPort[50];
-
sprintf_s(szPort,
"COM%d"
,portNo);
-
-
-
m_hComm=CreateFileA(szPort,
-
GENERIC_READ|GENERIC_WRITE,
-
0,
-
NULL,
-
OPEN_EXISTING,
-
0,
-
0);
-
-
-
if
(m_hComm==INVALID_HANDLE_VALUE)
-
{
-
LeaveCriticalSection(&m_csCommunicationSync);
-
return
false
;
-
}
-
-
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
true
;
-
}
-
-
bool
CSerialPort::OpenListenThread()
-
{
-
-
if
(m_hListenThread!=INVALID_HANDLE_VALUE)
-
{
-
-
return
false
;
-
}
-
-
s_bExit=
false
;
-
-
UINT
threadId;
-
-
m_hListenThread=(
HANDLE
)_beginthreadex(NULL,0,ListenThread,
this
,0,&threadId);
-
if
(!m_hListenThread)
-
{
-
return
false
;
-
}
-
-
if
(!SetThreadPriority(m_hListenThread,THREAD_PRIORITY_ABOVE_NORMAL))
-
{
-
return
false
;
-
}
-
-
return
true
;
-
}
-
-
bool
CSerialPort::CloseListenTread()
-
{
-
if
(m_hListenThread!=INVALID_HANDLE_VALUE)
-
{
-
-
s_bExit=
true
;
-
-
-
Sleep(10);
-
-
-
CloseHandle(m_hListenThread);
-
m_hListenThread=INVALID_HANDLE_VALUE;
-
}
-
return
true
;
-
}
-
-
UINT
CSerialPort::GetBytesInCOM()
-
{
-
DWORD
dwError=0;
-
COMSTATcomstat;
-
memset(&comstat,0,
sizeof
(COMSTAT));
-
-
UINT
BytesInQue=0;
-
-
if
(ClearCommError(m_hComm,&dwError,&comstat))
-
{
-
BytesInQue=comstat.cbInQue;
-
}
-
-
return
BytesInQue;
-
}
-
-
UINT
WINAPICSerialPort::ListenThread(
void
*pParam)
-
{
-
-
CSerialPort*pSerialPort=
reinterpret_cast
<CSerialPort*>(pParam);
-
-
-
while
(!pSerialPort->s_bExit)
-
{
-
UINT
BytesInQue=pSerialPort->GetBytesInCOM();
-
-
if
(BytesInQue==0)
-
{
-
Sleep(SLEEP_TIME_INTERVAL);
-
continue
;
-
}
-
-
-
char
cRecved=0x00;
-
do
-
{
-
cRecved=0x00;
-
if
(pSerialPort->ReadChar(cRecved)==
true
)
-
{
-
std::cout<<cRecved;
-
continue
;
-
}
-
}
while
(--BytesInQue);
-
}
-
-
return
0;
-
}
-
-
bool
CSerialPort::ReadChar(
char
&cRecved)
-
{
-
BOOL
bResult=TRUE;
-
DWORD
BytesRead=0;
-
if
(m_hComm==INVALID_HANDLE_VALUE)
-
{
-
return
false
;
-
}
-
-
-
EnterCriticalSection(&m_csCommunicationSync);
-
-
-
bResult=ReadFile(m_hComm,&cRecved,1,&BytesRead,NULL);
-
if
((!bResult))
-
{
-
-
DWORD
dwError=GetLastError();
-
-
-
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_RXABORT);
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
false
;
-
}
-
-
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
(BytesRead==1);
-
-
}
-
-
bool
CSerialPort::WriteData(unsigned
char
*pData,unsigned
int
length)
-
{
-
BOOL
bResult=TRUE;
-
DWORD
BytesToSend=0;
-
if
(m_hComm==INVALID_HANDLE_VALUE)
-
{
-
return
false
;
-
}
-
-
-
EnterCriticalSection(&m_csCommunicationSync);
-
-
-
bResult=WriteFile(m_hComm,pData,length,&BytesToSend,NULL);
-
if
(!bResult)
-
{
-
DWORD
dwError=GetLastError();
-
-
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_RXABORT);
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
false
;
-
}
-
-
-
LeaveCriticalSection(&m_csCommunicationSync);
-
-
return
true
;
-
}
-
-
-
-
#include"stdafx.h"
-
#include"SerialPort.h"
-
#include<iostream>
-
-
int
_tmain(
int
argc,_TCHAR*argv[])
-
{
-
-
CSerialPortmySerialPort;
-
-
if
(!mySerialPort.InitPort(2))
-
{
-
std::cout<<
"initPortfail!"
<<std::endl;
-
}
-
else
-
{
-
std::cout<<
"initPortsuccess!"
<<std::endl;
-
}
-
-
if
(!mySerialPort.OpenListenThread())
-
{
-
std::cout<<
"OpenListenThreadfail!"
<<std::endl;
-
}
-
else
-
{
-
std::cout<<
"OpenListenThreadsuccess!"
<<std::endl;
-
}
-
-
int
temp;
-
std::cin>>temp;
-
-
return
0;
-
}
-
分享到:
相关推荐
Virtual Serial Port Driver Pro(虚拟串口工具)是一款功能非常专业的虚拟串口辅助软件。压缩包内有破解说明,旧版本的win10用着好像有些兼容问题,于是到官网看看,发现已经更新到9.0版本了,还分为专业版和标准版,...
Serial port emulator by Eltima Software allows creating a large number of virtual COM ports and gives you great possibility to emulate serial port behavior fully. Virtual Serial Port Driver is not ...
Serial Port/Debug : Shows serial port debug msg such as open/close etc. ;; Serial Port/Hex : Shows data in hex format ;; Serial Port/CR : Appens \r\n at end of the line ;; Serial Port/Send file : ...
Virtual Serial Port Driver Pro(虚拟串口工具)是一款功能非常专业的虚拟串口辅助软件。最近课设需要用到这款软件,旧版本的win10用着好像有些兼容问题,于是到官网看看,发现已经更新到9.0版本了,还分为专业版和...
Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual....
Virtual Serial Port Driver 7.1.289 手工破解版。 原程序DLL库用Armadillo 7.0 加壳。 可以用ArmaG3ddon_v1.9脱壳机直接脱壳 也可以手工脱壳,手工脱壳参考【Armadillo 7.0 DLL 脱壳】 脱壳后OD载入,patch几个...
HSM USB SERIAL DRIVER HSM 系统驱动程序
DS1306 Serial Alarm Real Time Clock (RTC),时钟芯片的说明文档资料 Real time clock counts seconds, minutes, hours, date of the month, month, day of the week, and year with leap year compensation valid ...
Serial to Ethernet Connector 8.0.1203 直接替换文件
Serial Port Monitor 4.1.2.293 破解版 主要用来SPSniff串口,可以监听其他程序与串口的通信内容。 官方网站 http://www.eltima.com/products/serial-port-monitor/ 请支持正版
一个很棒的串口调试工具,HHD出品,Serial Monitor 6.02,原来有个Free版的,容易使电脑死机,所以换了这个V6.02最新版,我将使用天数改成了固定的,永不过期了。 不求完美,但求能用~
python serial模块,可以做为你的学习设计参考,开发python串口的模块,简洁方便。
USB-Serial Controller的驱动程序
Lumion8.0 Pro Serial number reading toolLumion8.0 Pro Serial number reading tool
基于https://github.com/wjwwood/serial/tree/boostless项目修改,删除不必要文件,无需catkin只要cmake即可使用
根据USB设备的VID 和PID得到他的serial number。一些开发环境对于多个USB设备(同时插入多个设备),通过serial number区别使用不同的USB设备。 得到USB设备VID和PID方法。插拔一次设备,执行如下命令。 $ sudo dmesg ...
gadgetserial 驱动 实测win7可用,设备id为: USB\VID_0525&PID_A4A7,如果你的设备不是这个id,勿下载。
USB-serial controller驱动程序,支持多种操作系统,连接console口必备工具
Virtual Serial Ports Driver XP 这款配置实用工具使用可以被包含到你自己的软件当中提供直接从你的应用软件创建和配置虚拟端口方式,通过虚拟非调制解调器电缆模拟 RS232 串口连接。使用 VSPD XP 你可以在你的系统...
Virtual Serial Port Driver主要功能 1、创建任意数量的虚拟COM端口 Virtual Serial Port Driver使您能够创建无限数量的虚拟串行端口。创建的端口位于设备管理器中的“端口”组中,这意味着它们将被所有安装的所有...