VC学习:Windows CE下的串口通讯类

小耳环0

小耳环0

2016-02-19 14:28

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

  串行通讯是目前计算机、通信和控制领域最基本的通信方式。在CSDN的“嵌入式开发/WINCE”社区中,经常有人提问该到哪找串口通讯类,其实这个问题我自己也问过。:)而一般的回答是给你提供一个Pocket PC 2002的SDK例子程序。但到底SDK的程序和MFC的结构有很大的不同,对于想用MFC编写通信程序的人来说也不是很便利。
  
  另一方面,由于Windows CE是一个基于Unicode的操作系统,并且Windows CE不支持Windows下常用的串行通信重叠I/O方式(OVERLAPPED),因此编写Windows CE下的串口通讯类有一些与桌面Windows不同的地方。
  
  以下是我从SDK程序改写而来的MFC类,希望能和致力于WINCE开发的朋友多多交流,由于本人才疏学浅,程序中有许多不完善的地方,请大家指正。我的程序是基于“主动发送请求,被动接收响应”的假设,因此我只设置了一个接收数据的线程。如果有朋友能提供有独立发送数据和接收数据线程的类,我将十分感激。我的E_mail:zhenxizhou@elong.com。
  
  感谢“嵌入式开发/WINCE”社区为我提供SDK例子的朋友,感谢CSDN上所有热心的朋友,祝愿中国的软硬件水平能早日挤身世界一流。
  
  头文件Serial.h
  
  // Serial.h: interface for the CSerial class.
  
  //
  
  /////////////////////////////
  
  #if !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
  
  #define AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_
  
  #if _MSC_VER 1000
  
  #pragma once
  
  #endif // _MSC_VER 1000
  
  DWORD WINAPI ReadPortThread(LPVOID lpvoid); //读数据线程
  
  class CSerial
  
  {
  
  public:
  
  BOOL InitCommTimeouts(); //设置超时参数
  
  BOOL InitDCB(); //配置串口

  BOOL m_bConnected;
  
  BOOL ClosePort(HANDLE hCommPort); //关闭串口
  
  DWORD WritePort(TCHAR *buf,DWORD dwBytesToWrite); //写数据
  
  BOOL OpenPort(LPTSTR lpszPortName); //打开串口
  
  CSerial();
  
  HANDLE hReadThread;
  
  virtual ~CSerial();
  
  };
  
  #endif // !defined(AFX_SERIAL_H__59575586_AAA9_4FEF_B2A7_E089553698EF__INCLUDED_)
  
  源文件:Serial.cpp
  
  // Serial.cpp: implementation of the CSerial class.
  
  //
  
  /////////////////
  

#include "stdafx.h"
  
  #include "Serial.h"
  
  #ifdef _DEBUG
  
  #undef THIS_FILE
  
  static char THIS_FILE[]=__FILE__;
  
  #define new DEBUG_NEW
  
  #endif
  
  HANDLE hPort;
  
  CString strInChar;
  
  //////////////////////////////////////////
  
  // Construction/Destruction
  
  /////////////////////////////////////////

  CSerial::CSerial()
  
  {
  
  }
  
  CSerial::~CSerial()
  
  {
  
  if(hPort != INVALID_HANDLE_VALUE)
  
  ClosePort(hPort);
  
  }
  
  BOOL CSerial::OpenPort(LPTSTR lpszPortName)
  
  {
  
  DWORD dwError,
  
  dwThreadID;

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  if(hPort)
  
  {
  
  return FALSE;
  
  }
  
  //打开串口
  
  hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,
  
  0, NULL, OPEN_EXISTING,0, NULL);
  
  //如果打开端口出错, 返回FALSE
  
  if ( hPort == INVALID_HANDLE_VALUE )
  
  {
  
  //不能打开端口
  
  CString strError;
  
  strError.Format(_T("Unable to open %s, Error No.=%d"),
  
  lpszPortName, GetLastError());
  
  MessageBox (NULL, strError,TEXT("Error"), MB_OK);
  
  return FALSE;
  
  }

//指定端口监测的事件集

  SetCommMask (hPort, EV_RXCHAR);
  
  //分配设备缓冲区
    
  SetupComm(hPort,512,512);
  
  //初始化缓冲区中的信息
  
  PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
  
  //配置串行端口
  
  if(!InitDCB())
  
  return FALSE;
  
  //设置端口超时值
  
  if(!InitCommTimeouts())
  
  return FALSE;
  
  //设置端口上指定信号的状态
  
  // SETDTR: 发送DTR (data-terminal-ready)信号
  
  // SETRTS: 发送RTS (request-to-send)信号
  
  EscapeCommFunction (hPort, SETDTR);
  
  EscapeCommFunction (hPort, SETRTS);
  
  //创建一个从串口读取数据的线程
  
  if (hReadThread = CreateThread (NULL, 0, ReadPortThread, 0, 0,
  
  &dwThreadID))
  
  {
  
  }
  
  else
  
  {
  
  //不能创建线程
  
  MessageBox (NULL, TEXT("Unable to create the read thread"),
  
  TEXT("Error"), MB_OK);
  
  dwError = GetLastError ();
  
  return FALSE;
  
  }

  m_bConnected=TRUE;
  
  return TRUE;
  
  }
  
  DWORD CSerial::WritePort(TCHAR *buf,DWORD dwCharToWrite)
  
  {
  
  BOOL fWriteState;
  
  DWORD dwBytesWritten;

//写入数据
  
  fWriteState=WriteFile(hPort,buf,dwCharToWrite*sizeof  (TCHAR),&dwBytesWritten,NULL);
  
  if(!fWriteState)
  
  {
  
  //不能写数据
  
  MessageBox(NULL,TEXT("Can't Write String to Comm"),TEXT("Error"),MB_OK);
  
  dwBytesWritten=0;
  
  }

  return dwBytesWritten;
  
  }
  
  DWORD WINAPI ReadPortThread(LPVOID lpvoid)
  
  {
  
  BOOL fReadState;
  
  DWORD dwCommModemStatus;
  
  DWORD dwLength;
  
  COMSTAT ComStat;
  
  DWORD dwErrorFlags;
  
  while (hPort != INVALID_HANDLE_VALUE)
  
  {
  
  //等待串口的事件发生
  
  WaitCommEvent (hPort, &dwCommModemStatus, 0);
  
  if (dwCommModemStatus & EV_RXCHAR)
  
  {

  ClearCommError(hPort,&dwErrorFlags,&ComStat);

  //cbInQue返回在串行驱动程序输入队列中的字符数
  
  dwLength=ComStat.cbInQue;
  
  if(dwLength0)
  
  {
  
  //从串口读取数据
  
  TCHAR* buf=new TCHAR[256];
  
  fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
  
  if(!fReadState)
  
  {
  
  //不能从串口读取数据
  
  MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
  
  }
  
  else
  
  {

//把数据赋值给全局变量
  
  strInChar=buf;
  
  }
  
  delete[] buf;
  
  }
  
  }
  
  GetCommModemStatus (hPort, &dwCommModemStatus);
  
  }
  
  return 0;
  
  }
  
  BOOL CSerial::ClosePort(HANDLE hCommPort)
  
  {
  
  if (hCommPort != INVALID_HANDLE_VALUE)
  
  {
  
  //设置连接属性为FALSE

  m_bConnected=FALSE;
  
  //结束线程中WaitCommEvent的等待
  
  SetCommMask(hPort,0);
  
  //阻塞至线程停止
  
  if(hReadThread)
  
  {
  
  TerminateThread(hReadThread,0);
  
  CloseHandle(hReadThread);

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  }
  
  //清除端口上指定信号的状态
  
  EscapeCommFunction(hPort,CLRDTR);
  
  EscapeCommFunction(hPort,CLRRTS);
  
  //清除驱动程序内部的发送和接收队列
  
  PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
  
  //关闭串口
  
  CloseHandle (hCommPort);
  
  hCommPort = INVALID_HANDLE_VALUE;

展开更多 50%)
分享

猜你喜欢

VC学习:Windows CE下的串口通讯类

编程语言 网络编程
VC学习:Windows CE下的串口通讯类

VC++ 的串口通讯

编程语言 网络编程
VC++ 的串口通讯

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

VC++下用MSComm控件实现串口通讯

编程语言 网络编程
VC++下用MSComm控件实现串口通讯

Visual Basic串口通讯调试方法

电脑网络
Visual Basic串口通讯调试方法

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

VC6.0下利用消息实现内部进程通讯

编程语言 网络编程
VC6.0下利用消息实现内部进程通讯

linux之间如何进行串口通讯

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
linux之间如何进行串口通讯

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

怎么查看电脑cpu的温度

怎么查看电脑cpu的温度

在ListCtrl中进行排序

在ListCtrl中进行排序
下拉加载更多内容 ↓