📄 comm.cpp
字号:
#include "stdafx.h"
#include "comm.h"
//////////////////////////////////////////////////////////////////////////
//Serial port operation implemention
//
HANDLE m_AbortEvent;
HANDLE m_hComDev; //串口设备句柄
OVERLAPPED m_OverlappedRead,m_OverlappedWrite;//读重叠方式
//////////////////////////////////////////////////////////////////////////
//函数名称:打开串口设备
//函数功能:打开串口,并初始化
//输入参数:
//nPort - 串口类型,如COM1,则nPort = 1
//nBaudRate-波特率
//返回值:
//成功返回TRUE,失败返回FALSE
//////////////////////////////////////////////////////////////////////////
BOOL OpenDevice(int nPort,int nBaudRate)
{
char szPort[15];
DCB dcb;//串口控制块
wsprintf( szPort, "COM%d", nPort );
//打开串口,独占方式,异步读写
m_hComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
if( m_hComDev == INVALID_HANDLE_VALUE ) return( FALSE );
//初始化重叠结构
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ));
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ));
//超时控制
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = MAXDWORD ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts( m_hComDev, &CommTimeOuts );
//创建读写事件对象
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
//设置串口控制参数和缓冲区大小
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hComDev, &dcb );
dcb.BaudRate = nBaudRate;
dcb.ByteSize = 8;
dcb.StopBits = 0;
dcb.Parity = 0;
if( !SetCommState( m_hComDev, &dcb ) ||!SetupComm( m_hComDev, 1024, 1024 ) ||m_OverlappedRead.hEvent == NULL ||m_OverlappedWrite.hEvent == NULL )
{
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
return FALSE;
}
//m_bOpened = TRUE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//函数名称:关闭串口设备
//函数功能:关闭串口,删除对象
//输入参数:无
//返回值:
//成功返回非零值
//失败返回零值
//////////////////////////////////////////////////////////////////////////
BOOL CloseDevice(void)
{
if (m_OverlappedRead.hEvent != NULL)CloseHandle(m_OverlappedRead.hEvent);
if (m_OverlappedWrite.hEvent != NULL)CloseHandle(m_OverlappedWrite.hEvent);
return CloseHandle(m_hComDev);
}
//////////////////////////////////////////////////////////////////////////
//函数名称:读串口
//函数功能:从串口读数据到指定的内存中
//输入参数:
//pBuffer - 存放读出来的数据的缓存
//dwBytesRead - 要读的数据长度
//返回值:
//实际读的数据长度,如返回零为出错,返回-1则为中止本次操作
//////////////////////////////////////////////////////////////////////////
DWORD ReadComm(BYTE* pBuffer, DWORD dwLength )
{
if( m_hComDev == INVALID_HANDLE_VALUE )
{
//句柄无效
return 0;
}
BOOL bReadStatus;
DWORD dwBytesRead ;
DWORD dwEvent;
HANDLE hArray[2] = { m_AbortEvent,m_OverlappedRead.hEvent};
//dwRemain = dwLength;
//读数据
bReadStatus = ReadFile( m_hComDev, pBuffer, dwLength, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus )
{
if( GetLastError() == ERROR_IO_PENDING )
{
//读操作未完成
//WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
//等待事件对象变成信号量
dwEvent = WaitForMultipleObjects(2,hArray,FALSE,INFINITE);
if (dwEvent == WAIT_OBJECT_0)
{
//用户中止读操作
return -1;
}
else if(dwEvent = (WAIT_OBJECT_0 +1))
{
//读操作完成
//bReadStatus = GetOverlappedResult(m_hComDev,&m_OverlappedRead,&dwBytesRead,FALSE);
ResetEvent(m_OverlappedRead.hEvent);
}
else
{
//出错
return 0;
}//else
}
else
{
//出错
return 0;
}//else
}
else
{
//读操作立即完成
ResetEvent(m_OverlappedRead.hEvent);
}//else
return dwLength;
}
//////////////////////////////////////////////////////////////////////////
//函数名称:写串口
//函数功能:从内存写数据到串口,同步方式
//输入参数:
//pBuffer - 数据缓冲区
//dwLength - 数据长度
//返回值:
//实际读的数据长度,如返回零为出错,返回-1则为中止本次操作
//////////////////////////////////////////////////////////////////////////
DWORD WriteComm(BYTE* pBuffer, DWORD dwLength)
{
if (m_hComDev == INVALID_HANDLE_VALUE)
{
//句柄无效
return 0;
}
BOOL bWriteStatus;
DWORD dwRemain,dwBytesWritten;
DWORD dwEvent;
HANDLE hArray[2] = { m_AbortEvent,m_OverlappedWrite.hEvent};
dwRemain = dwLength;
//写数据
while (dwRemain)
{
bWriteStatus = WriteFile( m_hComDev, pBuffer, dwRemain, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStatus)
{
if( GetLastError() == ERROR_IO_PENDING )
{
//写操作未完成
//等待对象变成信号量
dwEvent = WaitForMultipleObjects(2,hArray,FALSE,INFINITE);
if (dwEvent == WAIT_OBJECT_0)
{
//用户中止读操作
return -1;
}
else if (dwEvent == (WAIT_OBJECT_0 +1))
{
//写操作完成
bWriteStatus = GetOverlappedResult(m_hComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
pBuffer += dwBytesWritten;
dwRemain -= dwBytesWritten;
ResetEvent(m_OverlappedWrite.hEvent);
}
else
{
//出错
return 0 ;
}//else
}
else
{
//出错
return 0;
}//else
}
else
{
//写操作完成
bWriteStatus = GetOverlappedResult(m_hComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
dwRemain -= dwBytesWritten;
ResetEvent(m_OverlappedWrite.hEvent);
}//else
}//while
return dwLength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -