VC中用API实现串口通信

     本人才学习串口,现在将自己用API写的串口通信类的源代码公布,以供大家参考。

   //头文件件

// SerialAPI.h: interface for the CSerialAPI class.
//
//

#if !defined(AFX_SERIALAPI_H__9B5A3F02_39E2_478D_8AA9_AB0A7775FE3D__INCLUDED_)
#define AFX_SERIALAPI_H__9B5A3F02_39E2_478D_8AA9_AB0A7775FE3D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CSerialAPI 
{
public:
    int i ;
// unsigned char* receiveData();
 int receiveData(unsigned char * lpBuf);
 BOOL WriteABuffer(unsigned char *lpBuf, DWORD dwToWrite);
 HANDLE openPort(char* port,char* dataSet);
 HANDLE hComm;
 DCB dcb;
 //用来存放当前的串口的数据,来返回
 unsigned char* curentBufferData;
 CSerialAPI();
 virtual ~CSerialAPI();


};

#endif // !defined(AFX_SERIALAPI_H__9B5A3F02_39E2_478D_8AA9_AB0A7775FE3D__INCLUDED_)
 

//。CPP文件

// SerialAPI.cpp: implementation of the CSerialAPI class.
//
//

#include "stdafx.h"
#include "showData.h"
#include "SerialAPI.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CSerialAPI::CSerialAPI()
{

}

CSerialAPI::~CSerialAPI()
{

}
//打开端口的方法
HANDLE CSerialAPI::openPort(char *port, char *dataSet)
{
     
    hComm = CreateFile(port, 
                    GENERIC_READ | GENERIC_WRITE,
                    0,
                    0,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED,
                    0);
     if (hComm == INVALID_HANDLE_VALUE)
  {
   AfxMessageBox("打开串口失败!!!");
  }
  else
  {
         AfxMessageBox("成功打开串口!!!");
  }
     //设置为1024字节的缓冲区
  SetupComm(hComm,1024,1024);
  COMMTIMEOUTS TimeOuts;
     //设定读超时
    TimeOuts.ReadIntervalTimeout=MAXDWORD;
    TimeOuts.ReadTotalTimeoutMultiplier=MAXDWORD;
    TimeOuts.ReadTotalTimeoutConstant=63;
    //在读一次输入缓冲区的内容后读操作就立即返回,
    //而不管是否读入了要求的字符。
    //设定写超时
    SetCommTimeouts(hComm,&TimeOuts); //设置超时
     FillMemory(&dcb, sizeof(dcb), 0);
  dcb.DCBlength = sizeof(dcb);
  if (!BuildCommDCB(dataSet, &dcb))
  {  
         AfxMessageBox("不能成功的设置DCB!!!");
  }
  else
  {
   AfxMessageBox("DCB设置成功!!!");
   SetCommState(hComm, &dcb);
  }
  //清空
  PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
 return hComm;
}
//写数据
BOOL CSerialAPI::WriteABuffer(unsigned char *lpBuf, DWORD dwToWrite)
{
     OVERLAPPED osWrite = {0};//重叠方式
     DWORD dwWritten;
     DWORD dwRes;
     BOOL fRes;
  //写之前清除
  PurgeComm(hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
  osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (osWrite.hEvent == NULL)
     {
   AfxMessageBox("无法创建事件!!!");
   return FALSE;
  }
  //向指定的口写数据
  //如果这个时候不能及时返回的话,那么就会返回FALSE
  if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite))
  {
   //得到错误的代码,以下说明不是因为发送延时出错,报错
         if (GetLastError() != ERROR_IO_PENDING)
   {
            AfxMessageBox("发送数据到指定端口错误!!!");
   fRes = FALSE;
   return FALSE;

   }
   //如果发生的是因为写入数据时的延时错误
   else
   {
    //那么就等待信号,有两种,一种是有信号了,一种是超时
             dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
    //看返回值是什么以做下一步
    switch(dwRes)
    {
      //表明是有信号了
                  case WAIT_OBJECT_0:
        //得到重叠的结果,如果为真的话,那么发送成功
        if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))
        {
                           fRes = FALSE;
         AfxMessageBox("发送失败!!!");
         return FALSE;

        }
        //如果发送成功完成
        else
        {
        fRes = TRUE;
                          //AfxMessageBox("发送成功!!!");
        }
                       break;
        //其他处理
      default:

                       AfxMessageBox("发生不可预知错误!!!");
      
    }

   }

  }
  //出现这种情况说明立刻返回了
  else
  {
         AfxMessageBox("立即返回,发送成功!!!");
   fRes = TRUE;
  }
  //关闭事件
  CloseHandle(osWrite.hEvent);
     return fRes;
}

int CSerialAPI::receiveData(unsigned char * lpBuf)
{
 DWORD dwRead;
 DWORD dwRes;
 //错误标志
 COMSTAT ComStat;
 //错误
 DWORD dwErrorFlags;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = {0};
    //读之前清除缓冲区
 //
 //清除错误
 ClearCommError(hComm,&dwErrorFlags,&ComStat);
// unsigned char lpBuf;
 //创建一个事件
 osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 if (osReader.hEvent == NULL)
 {
  AfxMessageBox("创建事件失败!!!");
 }
 //如果并没有阻塞在读上面,那么执行以下代码
 if (!fWaitingOnRead)
 {
  //从串口中读入数据
  BOOL bk = ReadFile(hComm,lpBuf,65,&dwRead,&osReader);
  //如果读取不成功
  if(!bk){
   //如果读入不成功是因为阻塞了
   if(GetLastError() == ERROR_IO_PENDING){
    //fWaitingOnRead = TRUE;
    dwRes = WaitForSingleObject(osReader.hEvent,10);
      switch (dwRes)
      {
       case WAIT_OBJECT_0:
         if (!GetOverlappedResult(hComm, &osReader, &dwRead, TRUE))
      {
      // AfxMessageBox("读数据产生错误!!!");
       ::OutputDebugString("读数据产生错误!!!/n");
      }
      else
      {
       ::OutputDebugString("读数据成功!!!");
       //PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
       //i ++;
       //this->curentBufferData[i++] = lpBuf;
                           //AfxMessageBox("读数据成功!!!");
      }
      //fWaitingOnRead = FALSE;
                        break;
      //读写超时
       case WAIT_TIMEOUT:
        ::OutputDebugString("读超时!!!/n");
     
        //AfxMessageBox("读超时!!");
         break;
       default:
        ::OutputDebugString("出现不可预知错误!!!/n");
       // AfxMessageBox("出现不可预知错误!!!");
        break;
      }
   }
  }
  /*
  do
  {
        if (!ReadFile(hComm,&lpBuf[i],1, &dwRead,&osReader))
  {
   //AfxMessageBox("开始读数据!");
   if (GetLastError() != ERROR_IO_PENDING) 
   {
    ::OutputDebugString("出现读错误!!!/n");
    //AfxMessageBox("出现读错误!!!")
   }
   //否则说明数据在读的时候正在阻塞
   else
   { 
    ::OutputDebugString("读数据的时候发生了阻塞!!!/n");
               //AfxMessageBox("读数据的时候发生了阻塞!!!");
               fWaitingOnRead = TRUE;
    //看在等待的时候返回什么
               dwRes = WaitForSingleObject(osReader.hEvent,-1);
      switch (dwRes)
      {
       case WAIT_OBJECT_0:
         if (!GetOverlappedResult(hComm, &osReader, &dwRead, FALSE))
      {
      // AfxMessageBox("读数据产生错误!!!");
       ::OutputDebugString("读数据产生错误!!!/n");
      }
      else
      {
       ::OutputDebugString("读数据成功!!!");
       i ++;
       //this->curentBufferData[i++] = lpBuf;
                           //AfxMessageBox("读数据成功!!!");
      }
      fWaitingOnRead = FALSE;
                        break;
      //读写超时
       case WAIT_TIMEOUT:
        ::OutputDebugString("读超时!!!/n");
     
        //AfxMessageBox("读超时!!");
         break;
       default:
        ::OutputDebugString("出现不可预知错误!!!/n");
       // AfxMessageBox("出现不可预知错误!!!");
        break;
      }

   }


  }
  else
  {
            ::OutputDebugString("读数据成功!!!/n");
   i ++;
  // this->curentBufferData[i++] = lpBuf;
   //AfxMessageBox("读数据成功!!!");
  }
  
  //CString theString = lpBuf;
  //AfxMessageBox(lpBuf);
        //AfxMessageBox("读数据成功!!!");

  } while(dwRead);
  //如果很快就读完了并且返回了
  CloseHandle(osReader.hEvent);
       // return curentBufferData;
    */
 }
 //返回读入的字节
 CloseHandle(osReader.hEvent);
 //清空缓冲区
 PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
 return dwRead;
}

//用来接收数据
/*
unsigned char* CSerialAPI::receiveData()
{
 int i = 0;
 DWORD dwRead;
 DWORD dwRes;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = {0};
 unsigned char lpBuf;
 //创建一个事件
 osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 if (osReader.hEvent == NULL)
 {
  AfxMessageBox("创建事件失败!!!");
 }
 //如果并没有阻塞在读上面,那么执行以下代码
 if (!fWaitingOnRead)
 {
  do
  {
        if (!ReadFile(hComm,&lpBuf,1, &dwRead,&osReader))
  {
   //AfxMessageBox("开始读数据!");
   if (GetLastError() != ERROR_IO_PENDING) 
   {
    ::OutputDebugString("出现读错误!!!/n");
    //AfxMessageBox("出现读错误!!!")
   }
   //否则说明数据在读的时候正在阻塞
   else
   { 
    ::OutputDebugString("读数据的时候发生了阻塞!!!/n");
               //AfxMessageBox("读数据的时候发生了阻塞!!!");
               fWaitingOnRead = TRUE;
    //看在等待的时候返回什么
               dwRes = WaitForSingleObject(osReader.hEvent,10);
      switch (dwRes)
      {
       case WAIT_OBJECT_0:
         if (!GetOverlappedResult(hComm, &osReader, &dwRead, FALSE))
      {
      // AfxMessageBox("读数据产生错误!!!");
       ::OutputDebugString("读数据产生错误!!!/n");
      }
      else
      {
       ::OutputDebugString("读数据成功!!!");
       this->curentBufferData[i++] = lpBuf;
                           //AfxMessageBox("读数据成功!!!");
      }
      fWaitingOnRead = FALSE;
                        break;
      //读写超时
       case WAIT_TIMEOUT:
        ::OutputDebugString("读超时!!!/n");
        //AfxMessageBox("读超时!!");
         break;
       default:
        ::OutputDebugString("出现不可预知错误!!!/n");
       // AfxMessageBox("出现不可预知错误!!!");
        break;
      }

   }


  }
  else
  {
            ::OutputDebugString("读数据成功!!!/n");
   this->curentBufferData[i++] = lpBuf;
   //AfxMessageBox("读数据成功!!!");
  }
  
  //CString theString = lpBuf;
  //AfxMessageBox(lpBuf);
        //AfxMessageBox("读数据成功!!!");

  } while(dwRead);
  //如果很快就读完了并且返回了
  CloseHandle(osReader.hEvent);
        return curentBufferData;
 }
 return 0;
}
*/

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值