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

📄 异步串口通信 vc++ .cpp

📁 异步串口通信 VC++ 本文参考MSDN及相关网上文章。 ////////////////////////////////////////////// //MyComm.h 多机控制 异步串口通信 /
💻 CPP
字号:
class CMyComm
{
public:
CMyComm();
virtual ~CMyComm();
void PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue);
     // size of input buffer, size of output buffer
BOOL Open(int nPort, int nBaud);
    //默认无校验,每个字节发送11个bit,异步方式。
    //若设置校验后,校验错则字节被替换为0x7E
BOOL SetupQueue(DWORD dwInQueue, DWORD dwOutQueue);
    // size of input buffer, size of output buffer
BOOL ResetParity(char Parity);//parity = 'N', 'O', 'E',  'M',  'S' 不区分大小写
         //分别表示   no, odd, even, mark, space 
        // 在Open()前设置无效。
BOOL SendData(LPCVOID lpBuf, DWORD dwToWrite);
DWORD ReadData(LPVOID lpBuf, DWORD dwToRead);
void Close();

protected:
HANDLE m_hCom;
BOOL m_bOpened;
OVERLAPPED m_osReader;
OVERLAPPED m_osWriter;
DWORD m_dwInBuf;
DWORD m_dwOutBuf;
};

//////////////////////////////////////////////////////////
//MyComm.cpp
#include "stdafx.h"
#include "MyComm.h"
///////////////////////////////////////////

CMyComm::CMyComm()
{
m_bOpened = FALSE;
m_dwInBuf = 512;
m_dwOutBuf = 512;
m_hCom = NULL;
}

void CMyComm::PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue)
{
m_dwInBuf = dwInQueue;
m_dwOutBuf = dwOutQueue;
}

BOOL CMyComm::Open(int nPort, int nBaud)
{
ASSERT(nPort > 0 || nPort < 5 || nBaud >= 110 || nBaud <= 128000);
if( m_bOpened ) return TRUE;
char szPort[15];
char lpDef[15];
DCB dcb = {0};
dcb.DCBlength = sizeof(dcb);
wsprintf(szPort, "COM%d", nPort);
wsprintf(lpDef, "%d,n,8,1", nBaud);
m_hCom = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE,
  0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if( m_hCom == INVALID_HANDLE_VALUE ) return FALSE;

FillMemory(&m_osReader, sizeof(OVERLAPPED), 0);
FillMemory(&m_osWriter, sizeof(OVERLAPPED), 0);
m_osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

int byteUsedTime = 14400 / nBaud +1;
COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20};
dcb.fParity = TRUE;
dcb.fErrorChar = TRUE;
dcb.ErrorChar = '~'; 
if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL
   || !SetCommTimeouts(m_hCom, &timeouts) 
   || !BuildCommDCB(lpDef, &dcb) || !SetupComm(m_hCom, m_dwInBuf, m_dwOutBuf)) {
  if( m_osReader.hEvent != NULL )
   CloseHandle( m_osReader.hEvent );
  if( m_osWriter.hEvent != NULL )
   CloseHandle( m_osWriter.hEvent );
  CloseHandle( m_hCom );
  return FALSE;
}
m_bOpened = TRUE;
return m_bOpened;
}

BOOL CMyComm::SetupQueue(DWORD dwInQueue, DWORD dwOutQueue)
{
if (m_hCom == NULL) return FALSE;
m_dwInBuf = dwInQueue;
m_dwOutBuf = dwOutQueue;
return SetupComm(m_hCom, m_dwInBuf, m_dwOutBuf);
}

BOOL CMyComm::ResetParity(char Parity)
{
if (m_hCom == NULL) return FALSE;
DCB dcb;
dcb.DCBlength = sizeof( DCB );
if (!GetCommState(m_hCom, &dcb)) return FALSE;
BYTE cParity;
Parity = tolower(Parity);
switch (Parity) {
case 'o':
  cParity = 1;
  break;
case 'e':
  cParity = 2;
  break;
case 'm':
  cParity = 3;
  break;
case 's':
  cParity = 4;
  break;
default:
  cParity = 0;
  break;
}
dcb.Parity = cParity;
return SetCommState(m_hCom, &dcb);
}

BOOL CMyComm::SendData(LPCVOID lpBuf, DWORD dwToWrite)
{
TRACE("SSSSSSSSSSSSS 00\n"); 
if( !m_bOpened || m_hCom == NULL ) return FALSE;
DWORD dwWritten;
if (WriteFile(m_hCom, lpBuf, dwToWrite, &dwWritten, &m_osWriter)) return TRUE;
if (GetLastError() != ERROR_IO_PENDING)  return FALSE;
GetOverlappedResult(m_hCom, &m_osWriter, &dwWritten, TRUE);
TRACE("SSSSSSSSSSSSS 11\n"); 
return (dwToWrite == dwWritten);
}


DWORD CMyComm::ReadData(LPVOID lpBuf, DWORD dwToRead)
{ 
TRACE("RRRRRRRRRRRR 00\n"); 
if( !m_bOpened || m_hCom == NULL ) return 0;
DWORD dwRead;
if (ReadFile(m_hCom, lpBuf, dwToRead, &dwRead, &m_osReader) ) return dwRead; 
if (GetLastError() != ERROR_IO_PENDING)  return 0;

if (WaitForSingleObject(m_osReader.hEvent, INFINITE) != WAIT_OBJECT_0 ) 
  return 0;

if (!GetOverlappedResult(m_hCom, &m_osReader, &dwRead, FALSE) )
  return 0;
TRACE("RRRRRRRRRRRR 11\n");  
return dwRead;
}

void CMyComm::Close()
{ 
if (m_osReader.hEvent != NULL) CloseHandle( m_osReader.hEvent );
if (m_osWriter.hEvent != NULL) CloseHandle( m_osWriter.hEvent );
if (m_hCom != NULL)    CloseHandle( m_hCom );
m_bOpened = FALSE;
}

CMyComm::~CMyComm()
{
Close();
}

///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// main.cpp

char Buf[40];
int nArray[3];
CMyComn myCom;
UINT SendDataProc(LPVOID pParam);

void OnCommSendReceive() 
{
myCom.PreOpenSetupQueue(12, 12);
if (!myCom.Open(2, 4800)) return;
//如果想改变校验位,在此位置,如:myCom.ResetParity('m');
FillMemory(Buf, 40, 0);
nArray[0] = 0;
nArray[1] = 17;
nArray[2] = 88888;
AfxBeginThread(SendDataProc, (LPVOID)(12));
TRACE("EEEEEEEE\n");
int nRead = myCom.ReadData(Buf, 12);
int* nA = (int*) Buf;
TRACE("AAAAAAAAAAAAAA %d, %d %d %d\n",nRead, nA[0], nA[1], nA[1]); 
}

UINT SendDataProc(LPVOID pParam)
{
return myCom.SendData((LPVOID)nArray, (DWORD) pParam);
}


⌨️ 快捷键说明

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