⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cserial.cpp

📁 这是一个自动控制光开关的程序
💻 CPP
字号:
#include "CSerial.h"

CSerial::CSerial(void){
	m_bOpened = false;
}
CSerial::~CSerial(void){
}

BOOL CSerial::Open(int nPort,int nBaud )
{
	if( m_bOpened ) return( TRUE );

	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 );
//CreateFile用指定的方式打开指定的串口
//m_hCom为文件句柄。
//GENERIC_READ | GENERIC_WRITE指定可以对串口进行读写操作。
//参数0表示串口为独占打开。
//OPEN_EXISTING当指定串口不存在时,返回失败。
//FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED表示文件属性。
//打开串口时,须指定 FILE_FLAG_OVERLAPPED,表示文件或设备不会维护访问指针,
//在读写时,须使用OVERLAPPED 结构指定访问的文件偏移量。
	if( m_hComDev == NULL ) return( FALSE );

	memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
	memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
//COMMTIMEOUTS:串口超时参数设置
	COMMTIMEOUTS CommTimeOuts;
	CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
	//ReadIntervalTimeout:两字符之间最大的延时,当读取串口数据时,
	//一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。
	//设置为0表示该参数不起作用。

	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;//读取每字符间的超时。
	CommTimeOuts.ReadTotalTimeoutConstant = 0;//一次读取串口数据的固定超时。
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;//写入每字符间的超时。
	CommTimeOuts.WriteTotalTimeoutConstant = 5000;//一次写入串口数据的固定超时。
	SetCommTimeouts( m_hComDev, &CommTimeOuts );
//SetCommTimeouts函数设置某设备句柄的超时参数,要得到某设备句柄的超时参数可以用GetCommTimeouts函数

	m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
//DCB:串口参数设置
	dcb.DCBlength = sizeof( DCB );
	GetCommState( m_hComDev, &dcb );
	dcb.BaudRate = nBaud;//串口的通讯速度。如为9600
	dcb.ByteSize = 8;//字节位数
	if( !SetCommState( m_hComDev, &dcb ) ||
	!SetupComm( m_hComDev, 10000, 10000 ) ||//设置串口输入、输出缓冲区
	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 m_bOpened;

}

int CSerial::InBufferCount( void )
{

	if( !m_bOpened || m_hComDev == NULL ) return( 0 );

	DWORD dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

	return (int)ComStat.cbInQue;

}

DWORD CSerial::ReadData( void *buffer, DWORD dwBytesRead)
{

	if( !m_bOpened || m_hComDev == NULL ) return 0;

	BOOL bReadStatus;
	DWORD dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
	if( !ComStat.cbInQue ) return 0;

	dwBytesRead = min(dwBytesRead,(DWORD) ComStat.cbInQue);
    //ReadFile:读取串口数据
	bReadStatus = ReadFile( m_hComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
	if( !bReadStatus ){
		if( GetLastError() == ERROR_IO_PENDING ){
			WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
			return dwBytesRead;
		}
		return 0;
	}

	return dwBytesRead;

}

DWORD CSerial::SendData( const char *buffer, DWORD dwBytesWritten)
{

	if( !m_bOpened || m_hComDev == NULL ) return( 0 );

	BOOL bWriteStat;
//WriteFile:向串口写数据
	bWriteStat = WriteFile( m_hComDev, buffer, dwBytesWritten, &dwBytesWritten, &m_OverlappedWrite );
	if( !bWriteStat){
		if ( GetLastError() == ERROR_IO_PENDING ) {
			WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 );
			return dwBytesWritten;
		}
		return 0;
	}
	return dwBytesWritten;

}
//CloseHandle:关闭串口
void CSerial::Close(){
	if(m_hComDev!=NULL){
		if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
		if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
		CloseHandle( m_hComDev );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -