深入浅出VC++串口编程--第三方类
串口类
从本系列文章连载三、四可以看出,与通过WIN32 API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出OnComm消息)方式实现串口的异步访问。
尽管如此,MScomm控件的使用仍有诸多不便,譬如其发送和接收数据都要进行VARIANT类型对象与字符串的转化等。因此,国内外许多优秀的程序员自己编写了一些串口类,使用这些类,我们将可以更方便的操作串口。在笔者的《深入浅出Win32多线程程序设计之综合实例》(网址:http://dev.yesky.com)一文中,曾向读者展示了由Remon Spekreijse编写的CSerialPort串口类,而本文将向您展示由程序员llbird编写的cnComm(中国串口?)串口类。
llbird是一位优秀的程序员,他的代码风格简洁而紧凑,类的声明和实现都被定义在一个头文件中,使用这个类的朋友只需要在工程中包含这一头文件即可:
/* Comm Base Library(WIN98/NT/2000) ver 1.1 Compile by: BC++ 5; C++ BUILDER 4, 5, 6, X; VC++ 5, 6; VC.NET; GCC; copyright(c) 2004.5 - 2005.8 llbird wushaojian@21cn.com */ #ifndef _CN_COMM_H_ #define _CN_COMM_H_ #pragma warning(disable: 4530) #include <assert.h> //送到窗口的消息 WPARAM 端口号 class cnComm //------------------------------Construction----------------------------------- virtual ~cnComm() //----------------------------------Attributes---------------------------------- return ::ClearCommError(_hCommHandle, &dwError, &Stat) == TRUE ? Stat.cbInQue : (DWORD) - 1L; //----------------------------------Operations---------------------------------- if (!OpenCommPort()) if (!SetupPort()) return SetState(dwBaudRate); BindCommPort(dwPort); if (!OpenCommPort()) if (!SetupPort()) return SetState(szSetStr); COMSTAT Stat; if (::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0) unsigned long uReadLength = 0; dwBufferLength = dwBufferLength > Stat.cbInQue ? Stat.cbInQue :dwBufferLength; if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength,&_ReadOverlapped)) return uReadLength; char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime =20) DWORD dwError; if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0) unsigned long uWriteLength = 0; if (!::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength,&_WriteOverlapped)) return uWriteLength; return Write((void*)szBuffer, strlen(szBuffer)); DWORD dwError; DWORD uReadLength = 0; DWORD dwError; unsigned long uWriteLength = 0; va_list va; return Write(szBuffer); va_list va; return Write(szBuffer); EndThread(); _hCommHandle = INVALID_HANDLE_VALUE; DWORD id; _hThreadHandle = ::CreateThread(NULL, 0, CommThreadProc, this, 0,&id); return (_hThreadHandle != NULL); ::CloseHandle(_hThreadHandle); _hThreadHandle = NULL; return true; protected: DCB _DCB; //波特率,停止位,等 DWORD _dwIOMode; // 0 同步 默认 FILE_FLAG_OVERLAPPED重叠I/O异步 volatile HANDLE _hThreadHandle; //辅助线程 //初始化 memset(&_ReadOverlapped, 0, sizeof(_ReadOverlapped)); _ReadOverlapped.hEvent = ::CreateEvent(NULL, true, false, NULL); _WriteOverlapped.hEvent = ::CreateEvent(NULL, true, false, NULL); _hNotifyWnd = NULL; memset(&_WaitOverlapped, 0, sizeof(_WaitOverlapped)); if (_WriteOverlapped.hEvent != INVALID_HANDLE_VALUE) if (_WaitOverlapped.hEvent != INVALID_HANDLE_VALUE) char p[5]; _dwPort = dwPort; _hCommHandle = ::CreateFile(_szCommStr, GENERIC_READ | GENERIC_WRITE, 0, NULL, if (_fAutoBeginThread) if (!::SetupComm(_hCommHandle, 4096, 4096)) if (!::GetCommTimeouts(_hCommHandle, &_CO)) if (!::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR)) //---------------------------------------threads callback----------------------------------- virtual void OnDSR() virtual void OnCTS() virtual void OnBreak() virtual void OnTXEmpty() virtual void OnError() virtual void OnRing() virtual void OnRLSD() virtual DWORD ThreadFunc() COMSTAT Stat; for (DWORD dwLength, dwMask = 0; _fRunFlag && IsOpen(); dwMask = 0) if (dwMask == 0) switch (dwMask) case EV_TXEMPTY: case EV_DSR: case EV_RING: case EV_RLSD: case EV_BREAK: case EV_ERR: private: cnComm(const cnComm &); //base function for thread |
2.实例
程序的功能和界面(如下图)都与本文连载三、四中《基于WIN32 API的串口编程》和《基于控件的串口编程》相同,不同的只是本节的串口通信要以llbird定义的cnComm类来实现。
|
我们需要为串口的接收事件定义一个用户消息ON_COM_RECEIVE,因此对话框的消息映射为:
BEGIN_MESSAGE_MAP(CSerialPortClassDlg, CDialog) //{{AFX_MSG_MAP(CSerialPortClassDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton) ON_BN_CLICKED(IDC_SEND_BUTTON, OnSendButton) ON_MESSAGE(ON_COM_RECEIVE,OnCommRecv) //}}AFX_MSG_MAP END_MESSAGE_MAP() |
同时,我们需要在对话框类的头文件中定义cnComm类的成员变量com和接收数据消息处理函数OnCommRecv:
cnComm com; afx_msg void OnCommRecv(WPARAM wParam, LPARAM lParam); |
在对话框初始化时调用打开串口:
BOOL CSerialPortClassDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. CMenu *pSysMenu = GetSystemMenu(FALSE); // Set the icon for this dialog. The framework does this automatically // TODO: Add extra initialization here com.Open(1); //打开串口1并使用默认设置 return TRUE; // return TRUE unless you set the focus to a control |
发送字符串的过程很简单,只需要调用cnComm类的Write函数:
//"发送"按钮函数(完成数据的发送功能) void CSerialPortClassDlg::OnSendButton() { // TODO: Add your control notification handler code here UpdateData(true); com.Write(m_send); //发送字符串 |
接收字符串的过程也很简单,只需要调用cnComm类的ReadString函数:
void CSerialPortClassDlg::OnCommRecv(WPARAM wParam, LPARAM lParam) { UpdateData(true); //读取串口上的字符 UpdateData(false); |
读者朋友们这时一定会发出感慨:使用cnComm类后,进行串口数据收发的程序是多么简单啊!的确,串口的初始化、读写几乎都是用1~2条语句搞定的!
这就是我们要特别用一次连载来讲述使用第三方类来进行串口通信的原因。实际上,笔者在进行网络通信程序编程时,也不认为MS提供的CSocket类是最方便的选择,照样习惯使用第三方的网络通信类。它们的确有非常简洁明快的接口,这一点也是值得MS哥哥们学习的。
深入浅出VC++串口编程--第三方类相关推荐
- 深入浅出VC++串口编程--基于控件
深入浅出VC++串口编程之基于控件源代码下载 MSComm控件 Visual C++为我们提供了一种好用的ActiveX控件Microsoft Communications Control(即MSCo ...
- 深入浅出VC++串口编程--基本概念
引言 在PC机的主板上,有一种类型的接口可能为我们所忽视,那就是RS-232C串行接口,在微软的Windows系统中称其为COM.我们可以通过设备管理器来查看COM的硬件参数设置,如图1. 图1 在W ...
- 深入浅出VC++串口编程--短信应用开发
前面数次连载我们以较长的篇幅讲解了串口通信的硬件原理.DOS平台控制以及基于WIN32 API.控件和第三方类的串口编程.作为本系列文章的最后一次连载,本章将给出一个典型的应用实例:西门子短信服务模块 ...
- 深入浅出VC++串口编程之短信应用开发
前面数次连载我们以较长的篇幅讲解了串口通信的硬件原理.DOS平台控制以及基于WIN32 API.控件和第三方类的串口编程.作为本系列文章的最后一次连载,本章将给出一个典型的应用实例:西门子短信服务模块 ...
- 深入浅出VC++串口编程--基于Win32 API
1.API描述 在WIN32 API中,串口使用文件方式进行访问,其操作的API基本上与文件操作的API一致. 打开串口 Win32 中用于打开串口的API 函数为CreateFile,其原型为: H ...
- 深入浅出VC++串口编程之基于Win32 API
1.API描述 在WIN32 API中,串口使用文件方式进行访问,其操作的API基本上与文件操作的API一致. 打开串口 Win32 中用于打开串口的API 函数为CreateFile,其原型为: H ...
- 深入浅出Visual C++串口编程--深入浅出VC++串口编程之DOS的串口编程
在DOS平台下,操作串口主要有下列方式:通过BIOS调用.通过串口的硬件中断或通过对串口硬件进行轮询,本章将对以上三种方式进行具体的介绍并给出例子. 1.BIOS中断 在DOS操作系统下,IBM PC ...
- MFC 串口编程实例
MFC 串口编程实例 VC串口编程从实现方法上一般分为两种,一种使用MSCOMM控件,这种方法比较简单,软件的移植性较低,在这里介绍一种串口封装类的使用方法. 代码 先看代码 CommUtils.cp ...
- 一个由印度人编写的VC串口类
软件介绍 一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些基础知识,如怎么用VC打开串口,如何对串口进行配置,读串口.写串口等. 这个类有点特别,它没有 ...
最新文章
- 16.6 创建测试数据
- SharePoint安全 - SharePoint网站常用页面URL索引
- 数据源管理 | OLAP查询引擎,ClickHouse集群化管理
- 自己配置的WAMP环境,扩展oracle函数库(oci)
- python汉语读音_【学习】python 汉语转拼音
- MTK:屏幕模板机制
- 33. 数据类型转换
- LncRNADisease:IncRNA相关疾病数据库简介
- 微软智能云Azure在华新增数据中心区域正式启用
- 常见的直流稳压电源电容有哪些?及其详细介绍
- [组图]国外专家谈游戏制作
- Matlab中num2str函数的用法
- java 绘制动态的图形
- ZK-SNARKS | 创建第一个零知识snark电路
- rstudio运行python_RStudio网状Python
- Reloading current route in Angular 5 / Angular 6 / Angular 7
- 正则表达式\\s+ - 匹配任意空白字符
- matlab谐波含量,基于谐波检测中的数字低通滤波器的MATLAB设计
- java set 排序的_Set集合排序
- python封装继承多态_Python:封装、继承、多态、私有成员