异步串口通信 VC++(VC在线)

文章标题:异步串口通信 VC++
原 作 者:ucx
原 出 处:vczx.com
发 布 者:UCXNM
发布类型:原创

本文参考MSDN及相关网上文章。

//
//MyComm.h 多机控制 异步串口通信

//说不定能有用上的。

//
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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值