电脑串口接收数据程序.docx

上传人:b****6 文档编号:6578838 上传时间:2023-01-08 格式:DOCX 页数:14 大小:18.74KB
下载 相关 举报
电脑串口接收数据程序.docx_第1页
第1页 / 共14页
电脑串口接收数据程序.docx_第2页
第2页 / 共14页
电脑串口接收数据程序.docx_第3页
第3页 / 共14页
电脑串口接收数据程序.docx_第4页
第4页 / 共14页
电脑串口接收数据程序.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

电脑串口接收数据程序.docx

《电脑串口接收数据程序.docx》由会员分享,可在线阅读,更多相关《电脑串口接收数据程序.docx(14页珍藏版)》请在冰豆网上搜索。

电脑串口接收数据程序.docx

电脑串口接收数据程序

本程序用于电脑串口接收数据

SerialPort.h

#ifndefSERIALPORT_H_

#defineSERIALPORT_H_

#include

#include"TChar.h"

#include

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

/**串口通信类

*

*本类实现了监听发到指定串口的数据

*/

classCSerialPort

{

public:

CSerialPort(void);

~CSerialPort(void);

public:

/**初始化串口函数

*

*@param:

UINTportNo串口编号,默认值为1,即COM1,注意,尽量不要大于9

*@param:

UINTbaud波特率,默认为9600

*@param:

charparity是否进行奇偶校验,'Y'表示需要奇偶校验,'N'表示不需要奇偶校验

*@param:

UINTdatabits数据位的个数,默认值为8个数据位

*@param:

UINTstopsbits停止位使用格式,默认值为1

*@param:

DWORDdwCommEvents默认为EV_RXCHAR,即只要收发任意一个字符,则产生一个事件

*@return:

bool初始化是否成功

*@note:

在使用其他本类提供的函数前,请先调用本函数进行串口的初始化

*     /n本函数提供了一些常用的串口参数设置,若需要自行设置详细的DCB参数,可使用重载函数

*/n本串口类析构时会自动关闭串口,无需额外执行关闭串口

*@see:

*/

//boolInitPort(UINTportNo=3,UINTbaud=CBR_19200,charparity='N',UINTdatabits=8,UINTstopsbits=1,DWORDdwCommEvents=EV_RXCHAR);

boolInitPort(UINTportNo,UINTbaud,charparity,UINTdatabits,UINTstopsbits,DWORDdwCommEvents);

/**串口初始化函数

*

*本函数提供直接根据DCB参数设置串口参数

*@param:

UINTportNo

*@param:

constLPDCB&plDCB

*@return:

bool初始化是否成功

*@note:

本函数提供用户自定义地串口初始化参数

*@see:

*/

boolInitPort(UINTportNo,constLPDCB&plDCB);

/**开启监听线程

*

*本监听线程完成对串口数据的监听,并将接收到的数据打印到屏幕输出

*@return:

bool操作是否成功

*@note:

当线程已经处于开启状态时,返回flase

*@see:

*/

boolOpenListenThread();

/**关闭监听线程

*

*

*@return:

bool操作是否成功

*@note:

调用本函数后,监听串口的线程将会被关闭

*@see:

*/

boolCloseListenTread();

/**获取串口缓冲区中的字节数

*

*

*@return:

UINT操作是否成功

*@note:

当串口缓冲区中无数据时,返回0

*@see:

*/

UINTGetBytesInCOM();

/**读取串口接收缓冲区中的数据

*

*

*@param:

unsignedchar*lpInBuffer存放读取数据的字符变量

*@return:

bool读取是否成功

*@note:

*@see:

*/

boolMyReadFile(unsignedchar*lpInBuffer);

private:

/**打开串口

*

*

*@param:

UINTportNo串口设备号

*@return:

bool打开是否成功

*@note:

*@see:

*/

boolopenPort(UINTportNo);

/**关闭串口

*

*

*@return:

void操作是否成功

*@note:

*@see:

*/

voidClosePort();

/**串口监听线程

*

*监听来自串口的数据和信息

*@param:

void*pParam线程参数

*@return:

UINTWINAPI线程返回值

*@note:

*@see:

*/

staticUINTWINAPIListenThread(void*pParam);

private:

/**串口句柄*/

HANDLEm_hComm;

/**线程退出标志变量*/

staticbools_bExit;

/**线程句柄*/

volatileHANDLEm_hListenThread;

/**同步互斥,临界区保护*/

CRITICAL_SECTIONm_csCommunicationSync;//!

<互斥操作串口

};

#endif//SERIALPORT_H_

/**线程退出标志*/

boolCSerialPort:

:

s_bExit=false;//CSerialPort:

:

为自定义的前缀。

/**当串口无数据时,sleep至下次查询间隔的时间,单位:

秒*/

constUINTSLEEP_TIME_INTERVAL=5;//定义UINTSLEEP_TIME_INTERVAL为一个常量。

UINT:

指无符号整数。

CSerialPort:

:

CSerialPort(void)

:

m_hListenThread(INVALID_HANDLE_VALUE)//INVALID_HANDLE_VALUE实际值等于-1

{

m_hComm=INVALID_HANDLE_VALUE;

m_hListenThread=INVALID_HANDLE_VALUE;

InitializeCriticalSection(&m_csCommunicationSync);

}

CSerialPort:

:

~CSerialPort(void)

{

CloseListenTread();

ClosePort();

DeleteCriticalSection(&m_csCommunicationSync);

}

//初始化串口函数

boolCSerialPort:

:

InitPort(UINTportNo/*=1*/,UINTbaud/*=CBR_9600*/,charparity/*='N'*/,

UINTdatabits/*=8*/,UINTstopsbits/*=1*/,DWORDdwCommEvents/*=EV_RXCHAR*/)

{

/**临时变量,将制定参数转化为字符串形式,以构造DCB结构:

串口通讯中的设置信息,如波特率,奇偶校验位等....*/

charszDCBparam[50];

sprintf_s(szDCBparam,"baud=%dparity=%cdata=%dstop=%d",baud,parity,databits,stopsbits);

/**打开指定串口,该函数内部已经有临界区保护,上面请不要加保护*/

if(!

openPort(portNo))

{

returnfalse;

}

/**进入临界段*/

EnterCriticalSection(&m_csCommunicationSync);

/**是否有错误发生*/

BOOLbIsSuccess=TRUE;

/**

设置输入缓冲区和输出缓冲区的大小都是1024.

*/

if(bIsSuccess)

{

bIsSuccess=SetupComm(m_hComm,1024,1024);

}

/**设置串口的超时时间,均设为0,不使用超时限制*/

COMMTIMEOUTSCommTimeouts;

CommTimeouts.ReadIntervalTimeout=0;

CommTimeouts.ReadTotalTimeoutMultiplier=0;

CommTimeouts.ReadTotalTimeoutConstant=0;

if(bIsSuccess)

{

bIsSuccess=SetCommTimeouts(m_hComm,&CommTimeouts);

}

DCBdcb;

if(bIsSuccess)

{

/**获取当前串口配置参数,并且构造串口DCB参数*/

bIsSuccess=GetCommState(m_hComm,&dcb)&&BuildCommDCB(szDCBparam,&dcb);

/**开启RTSflow控制*/

dcb.fRtsControl=RTS_CONTROL_ENABLE;

}

if(bIsSuccess)

{

/**使用DCB参数配置串口状态*/

bIsSuccess=SetCommState(m_hComm,&dcb);

}

/**清空串口缓冲区*/

PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);

/**离开临界段*/

LeaveCriticalSection(&m_csCommunicationSync);

returnbIsSuccess==TRUE;

}

//关闭串口

voidCSerialPort:

:

ClosePort()

{

if(m_hComm!

=INVALID_HANDLE_VALUE)

{

CloseHandle(m_hComm);

m_hComm=INVALID_HANDLE_VALUE;

}

}

//打开串口

boolCSerialPort:

:

openPort(UINTportNo)

{

/**进入临界段*/

EnterCriticalSection(&m_csCommunicationSync);

/**把串口的编号转换为设备名*/

charszPort[50];

sprintf_s(szPort,"COM%d",portNo);

/**打开指定的串口*/

m_hComm=CreateFileA(szPort,/**设备名,COM1,COM2等*/

GENERIC_READ,/**只读模式*/

0,/**共享模式,0表示不共享*/

NULL,/**安全性设置,一般使用NULL*/

OPEN_EXISTING,/**该参数表示设备必须存在,否则创建失败*/

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,/**重叠方式*/

0);

/**如果打开失败,释放资源并返回*/

if(m_hComm==INVALID_HANDLE_VALUE)

{

LeaveCriticalSection(&m_csCommunicationSync);

returnfalse;

}

/**退出临界区*/

LeaveCriticalSection(&m_csCommunicationSync);

returntrue;

}

//打开监听线程

boolCSerialPort:

:

OpenListenThread()

{

/**检测线程是否已经开启了*/

if(m_hListenThread!

=INVALID_HANDLE_VALUE)

{

/**线程已经开启*/

returnfalse;

}

s_bExit=false;

/**线程ID*/

UINTthreadId;

/**开启串口数据监听线程*/

m_hListenThread=(HANDLE)_beginthreadex(NULL,0,ListenThread,this,0,&threadId);

/**检测线程是否开启或发生错误了*/

if(!

m_hListenThread)

{

returnfalse;

}

/**设置线程的优先级,高于普通线程*/

if(!

SetThreadPriority(m_hListenThread,THREAD_PRIORITY_ABOVE_NORMAL))

{

returnfalse;

}

returntrue;

}

//关闭监听线程

boolCSerialPort:

:

CloseListenTread()

{

if(m_hListenThread!

=INVALID_HANDLE_VALUE)

{

/**通知线程退出*/

s_bExit=true;

/**等待线程退出*/

Sleep(10);

/**置线程句柄无效*/

CloseHandle(m_hListenThread);

m_hListenThread=INVALID_HANDLE_VALUE;

}

returntrue;

}

//获取串口缓冲区的字节数

UINTCSerialPort:

:

GetBytesInCOM()

{

DWORDdwError=0;/**错误码*/

COMSTATcomstat;/**COMSTAT结构体,记录通信设备的状态信息*/

memset(&comstat,0,sizeof(COMSTAT));

UINTBytesInQue=0;

/**在调用ReadFile和WriteFile之前,通过本函数清除以前遗留的错误标志*/

if(ClearCommError(m_hComm,&dwError,&comstat))

{

BytesInQue=comstat.cbInQue;/**获取在输入缓冲区中的字节数*/

}

returnBytesInQue;

}

//串口监听线程

UINTWINAPICSerialPort:

:

ListenThread(void*pParam)

{

/**得到本类的指针*/

CSerialPort*pSerialPort=reinterpret_cast(pParam);

//线程循环,轮询方式读取串口数据

while(!

pSerialPort->s_bExit)

{

/**获取串口输入缓冲区的字节数据*/

UINTBytesInQue=pSerialPort->GetBytesInCOM();

/**如果串口输入缓冲区中无数据,则休息一会再查询*/

if(BytesInQue==0)

{

Sleep(SLEEP_TIME_INTERVAL);

continue;

}

/**读取输入缓冲区中的数据并输出显示*/

do

{

unsignedcharlpInBuffer[1024];

if(pSerialPort->MyReadFile(lpInBuffer)==true)

{

/**将读取的数据显示到命令行窗口*/

cout<

continue;

}

}while(--BytesInQue);

}

return0;

}

boolCSerialPort:

:

MyReadFile(unsignedchar*lpInBuffer)

{

DWORDdwBytesRead=1024;

COMSTATComStat;

DWORDdwErrorFlags;

OVERLAPPEDm_osRead;//创建OVERLAPPED结构。

memset(&m_osRead,0,sizeof(OVERLAPPED));

m_osRead.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);

ClearCommError(m_hComm,&dwErrorFlags,&ComStat);//清除错误

dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue);

if(m_hComm==INVALID_HANDLE_VALUE)

{

returnfalse;

}

/**临界区保护*/

EnterCriticalSection(&m_csCommunicationSync);

/*等待串口输入缓冲区的输入*/

if(!

dwBytesRead)

returnFALSE;

BOOLbReadStatus;

//从缓冲区读取数据。

bReadStatus=ReadFile(m_hComm,lpInBuffer,dwBytesRead,&dwBytesRead,&m_osRead);//异步读取数据。

if((!

bReadStatus))

{

/*GetLastError()返回ERROR_IO_PENDING,表示串口正在进行读操作*/

if(GetLastError()==ERROR_IO_PENDING)

{

/*表示知道对象被触发信号才返回。

*/

WaitForSingleObject(m_osRead.hEvent,INFINITE);

/*当串口读操作进行完毕后,m_osRead的hEvent时间会变为有信号,清空缓冲区*/

PurgeComm(m_hComm,PURGE_TXABORT|PURGE_RXABORT|PURGE_RXCLEAR|PURGE_RXABORT);

}

/**离开临界区*/

LeaveCriticalSection(&m_csCommunicationSync);

returntrue;

}

returntrue;

}

Main.c

#include"SerialPort.h"

usingnamespacestd;

int_tmain(intargc,_TCHAR*argv[])

{

CSerialPortmySerialPort;//首先将之前定义的类实例化

intlength=8;//定义传输的长度

if(!

mySerialPort.InitPort(2,CBR_9600,'N',8,1,EV_RXCHAR))//串口、波特率、奇偶校验、数据位个数、停止位……

{

std:

:

cout<<"initPortfail!

"<

:

endl;

}

else

{

std:

:

cout<<"initPortsuccess!

"<

:

endl;

}

if(!

mySerialPort.OpenListenThread())//是否打开监听线程,开启线程用来传输返回值

{

std:

:

cout<<"OpenListenThreadfail!

"<

:

endl;

}

else

{

std:

:

cout<<"OpenListenThreadsuccess!

"<

:

endl;

}

system("pause");

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1