这几天一直再看串口相关知识,对于其总结为如下串口类:
头文件声明如下:
#pragma once // 声明当串口接收到线程的时候调用的函数指针
// 参数: 1,接收到的数据; 2,数据长度; 3,发送的目标地址
typedef void (*DataArriveProc)(char *data, int len, DWORD dest); /***********************************
1,实现一个串口类,用于进行串口的通信;
2,其中的特性是,主动发送数据,被动接受
做出响应,其中开辟一个线程进型串口读取;
3,线程函数响应时,应该将接受到的数据转
发给使用此串口的上层应用;
************************************/
class CSerialPort
{
public:
CSerialPort(void);
virtual ~CSerialPort(void); // 串口操作函数
BOOL OpenPort(LPCTSTR portName, DWORD baudRate, int dataBits, int stopBits, int parity, DataArriveProc proc, DWORD dest);
BOOL ClosePort(); // 关闭串口
DWORD WritePort(char *data, DWORD size); // 往串口写数据 // 串口读操作线程的操作函数
static UINT AFX_CDECL ReadPortProc(LPVOID lpParam);// 往串口读数据的线程函数
BOOL Activate(); // 激活串口的读操作
BOOL Deactivate(); // 取消串口的读操作
BOOL IsActivate(); // 窗口是否已经准备好进行读操作 private:
HANDLE m_hPortHandle; // 串口句柄
HANDLE m_hReadThread; // 读线程
BOOL m_bReading; // 读线程是否处于工作状态
DCB m_dcbPort; // 串口的工作参数
COMMTIMEOUTS m_tmOut; // 串口通信超时参数 DataArriveProc m_pDataArriveProc; // 接收到数据后的调用的方法
DWORD m_dwDestAddress; // 数据发送的目的地址
};
源文件定义如下:
#include "StdAfx.h"
#include "SerialPort.h"
#include "Resource.h" CSerialPort::CSerialPort(void)
{
m_hPortHandle = INVALID_HANDLE_VALUE;
m_hReadThread = INVALID_HANDLE_VALUE;
m_bReading = FALSE;
} CSerialPort::~CSerialPort(void)
{
if(INVALID_HANDLE_VALUE != m_hPortHandle){
ClosePort();
}
if(INVALID_HANDLE_VALUE != m_hReadThread){
Deactivate();
}
} // 打开串口
// 1,打开串口文件;
// 2,设置串口属性
// 3,完成操作;
BOOL CSerialPort::OpenPort(LPCTSTR portName, DWORD baudRate, int dataBits, int stopBits, int parity, DataArriveProc proc, DWORD dest)
{
if(INVALID_HANDLE_VALUE != m_hPortHandle){
// 串口已经打开
return TRUE;
} CString temp; // 保存数据到达后的响应地址,及目的地
m_pDataArriveProc = proc;
m_dwDestAddress = dest; // 1, 打开串口文件
m_hPortHandle = ::CreateFile(portName, GENERIC_READ | GENERIC_WRITE, , NULL, OPEN_EXISTING, , NULL);
if(INVALID_HANDLE_VALUE == m_hPortHandle){
temp.LoadString(IDS_OPENPORT_FAIL);
AfxMessageBox(temp);
return FALSE;
} // 2, 获取串口的工作参数并重新赋值
GetCommState(m_hPortHandle, &m_dcbPort);
m_dcbPort.BaudRate = baudRate; // 设置波特率(外部设置)
m_dcbPort.ByteSize = dataBits; // 通信字节位数
m_dcbPort.fParity = ; // 奇偶校验使能,1可以
m_dcbPort.Parity = parity; // 校验方式:外设
m_dcbPort.StopBits = stopBits;// 停止位
m_dcbPort.fBinary = ;
m_dcbPort.fDtrControl = ;
m_dcbPort.fRtsControl = ;
m_dcbPort.fOutX= m_dcbPort.fInX= m_dcbPort.fTXContinueOnXoff=; // 3,设置一组监视串口设备的事件,什么信息到达时通知
SetCommMask(m_hPortHandle, EV_RXCHAR);
// 4,设置串口的通信参数,主要是缓冲区大小
SetupComm(m_hPortHandle, , );
// 5,设置工作参数
if(!SetCommState(m_hPortHandle, &m_dcbPort)){
temp.LoadString(IDS_SETSTATE_FAIL);
AfxMessageBox(temp);
ClosePort();
return FALSE;
} // 6,获取通信超时信息并重新设置
GetCommTimeouts(m_hPortHandle, &m_tmOut);
m_tmOut.ReadIntervalTimeout = ;
m_tmOut.ReadTotalTimeoutConstant = ;
m_tmOut.ReadTotalTimeoutMultiplier = ;
m_tmOut.WriteTotalTimeoutMultiplier = ;
m_tmOut.WriteTotalTimeoutConstant = ;
if(!SetCommTimeouts(m_hPortHandle, &m_tmOut)){
temp.LoadString(IDS_SETTTMOUT_FAIL);
AfxMessageBox(temp);
ClosePort();
return FALSE;
} // 7,清空串口缓冲区
PurgeComm(m_hPortHandle, PURGE_RXCLEAR | PURGE_TXCLEAR);
return TRUE;
}
// 关闭串口
// 1,清空通信设备监听事件;
// 2,清空串口缓冲区;
// 3,关闭串口文件句柄;
BOOL CSerialPort::ClosePort()
{
if(INVALID_HANDLE_VALUE != m_hPortHandle){
SetCommMask(m_hPortHandle, );
PurgeComm(m_hPortHandle, PURGE_RXCLEAR | PURGE_TXCLEAR);
CloseHandle(m_hPortHandle);
m_hPortHandle = INVALID_HANDLE_VALUE;
return TRUE;
} return TRUE;
} // 往串口写数据
// 1,首先检查串口是否处于工作状态;
// 2,向串口写入内容;
// 3,返回写入的内容大小;
DWORD CSerialPort::WritePort(char *data, DWORD size)
{
if(INVALID_HANDLE_VALUE == m_hPortHandle){
return ;
} DWORD writeLen = ;
BOOL ret = FALSE; ret = WriteFile(m_hPortHandle, data, size*sizeof(char), &writeLen, NULL); return writeLen;
} // 激活串口的读操作
// 1,判断串口是否已经打开;
// 2,判断串口读线程是否已经创建;
// 3,设置成员变量;
BOOL CSerialPort::Activate()
{
if(INVALID_HANDLE_VALUE == m_hPortHandle){
return FALSE;
} if(!m_bReading){
m_hReadThread = AfxBeginThread(ReadPortProc, this);
m_bReading = TRUE;
} if(INVALID_HANDLE_VALUE !=m_hReadThread){
// ResumeThread(m_hReadThread);
return TRUE;
}else{
m_bReading = FALSE;
return FALSE;
} return FALSE;
}
// 取消串口的读操作
// 1, 判断串口是否已经打开;
// 2,判断读线程是否已经创建;
// 3,设置成员变量;
BOOL CSerialPort::Deactivate()
{
if(INVALID_HANDLE_VALUE == m_hPortHandle){
return FALSE;
} if(INVALID_HANDLE_VALUE == m_hReadThread){
return FALSE;
} if(m_bReading){
WaitForSingleObject(m_hReadThread, INFINITE);
CloseHandle(m_hReadThread);
m_hReadThread = INVALID_HANDLE_VALUE;
m_bReading = FALSE;
return TRUE;
} return FALSE;
}
// 窗口是否已经准备好进行读操作
BOOL CSerialPort::IsActivate()
{
return m_bReading;
} // 往串口读数据的线程函数
// 对于线程处理函数需要是一个全局的或者静态的
// 所以你需要知道你当前需要知道你用的是哪个串口
// 实例,顾此函数参数为串口实例指针
UINT CSerialPort::ReadPortProc(LPVOID lpParam)
{
// 1, 变量准备
CSerialPort *pPort = (CSerialPort*)lpParam;
CString temp;
char *buffer = NULL;
int buferSize = ;
DWORD dwRead = ;
BOOL bRead = FALSE; // 2,基本条件判断
buffer = new char[buferSize];
while((pPort->m_hPortHandle != INVALID_HANDLE_VALUE) && (pPort->m_bReading)){
bRead = ReadFile(pPort->m_hPortHandle, buffer, buferSize, &dwRead, NULL);
if(!bRead){
temp.LoadString(IDS_READFILE_FAIL);
AfxMessageBox(temp);
}else{
if( != dwRead)
pPort->m_pDataArriveProc(buffer, buferSize, pPort->m_dwDestAddress);
}
} return ;
}
对于上述代码已编译通过,但是具体的还未测试,等后续完善!
谢谢支持!
mfc的一个串口类的更多相关文章
-
mfc 创建一个C++ 类
类创建向导 添加一个C++类 #pragma once的作用 认识类视图 一.类创建向导 二.添加一个C++类 认识类创建向导: 创新一个处理文字信息的类CMessage CMessa ...
-
一个由印度人编写的VC串口类
http://www.cnblogs.com/lwngreat/p/4098374.html 软件介绍 一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些 ...
-
C运行时库(C Run-time Library)详解(提供的另一个最重要的功能是为应用程序添加启动函数。Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)
一.什么是C运行时库 1)C运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“ ...
-
MFC中如何在一个类中调用另一个类的控件
学习记录: 两个类,一个为主类 1个为:CCkDlg,主类 1个为: Https,用来做HTTPS请求获得页面状态. 测试界面如下: CCkDlg 类里定义函数 void CCkDlg::printf ...
-
谢欣伦 - OpenDev原创教程 - 串口类CxSerial
这是一个精练的串口类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. 串口类CxSerial的使用如下(以某个叫做CSomeClass ...
-
使用libzplay库封装一个音频类
装载请说明原地址,谢谢~~ 前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...
-
MFC下对串口的操作以及定时器的调用
最近研究了一下MFC下对串口的操作,测试了一下对设备的读写. 1.打开串口 GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(FALSE); m_hComm = ...
-
MFC学习之CWinApp类
CWinApp是一个基类,你通过它来继承Windows应用程序对象.应用程序对象为你提供了初始化应用程序(以及它的每一个实例 和运行应用程序所需的成员函数.它实现主事件循环并把事件分发给MFC中其他类 ...
-
MFC中的CString类使用方法指南
MFC中的CString类使用方法指南 原文出处:codeproject:CString Management [禾路:这是一篇比较老的资料了,但是对于MFC的程序设计很有帮助.我们在MFC中使用字符 ...
随机推荐
-
Java中传值与传引用
不管Java参数类型是什么,一律传递参数的副本. <Thinking In Java>:“When you're passing primitives into a method,you ...
-
JAVA学习笔记 -- 数据结构
一.数据结构的接口 在Java中全部类的鼻祖是Object类,可是全部有关数据结构处理的鼻祖就是Collection和Iterator接口,也就是集合与遍历. 1.Collection接口 Colle ...
-
appach-maven-3.5.0配置与下载
今天需要搭建javaweb开发的环境,需要配置maven.弄了半天终于配置好了.蛋疼的一批.楼主用的是win10的系统.不知道Linux下的也是不是这么坑! 首先,需要把maven的包下载下来.进入h ...
-
Elixir东游记/上:intro/1
1. 为啥前面还在搞haxe,现在又换到elixir了? erlang本来我就在用,用elixir不过是方便顺手给人科普而已. 2. so,接下来你打算用elixir干嘛? 很简单,写一个简单的解释器 ...
-
[Fatal Error] :3:13: Open quote is expected for attribute ";{1}"; associated with an element type ";id";.
用DOM解析XML时出现了如下错误: [Fatal Error] :3:13: Open quote is expected for attribute "{1}" associa ...
-
posix 条件变量与互斥锁 示例生产者--消费者问题
一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行. 在pthr ...
-
stderr: xcode-select: error: tool &#39;xcodebuild&#39; requires Xcode, but active developer directory &#39;/Library/Developer/CommandLineTools&#39; is a command line tools instance
错误提示: (1). stderr: xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer direc ...
-
socket--接受大数据
一.简单ssh功能 1.1 实现功能 在前面的一篇博客中,我们已经实现了一个简单的类似Linux服务器ssh功能的小程序,可以输入系统命令来返回命令运行结果,今天我们也以此开始,看看socket如何来 ...
-
<;/p>;标题设置
333333333333333333333333333333 border-top-left-radius: 3px; border-top-right-radius: 3px; border-bot ...
-
WEB前端研发工程师编程能力成长之路(2)
四.[入微] 最强解决方案.你能够走在需求的前面,将当前需求里有的.没有直接提出来的.现在暂时没有但将来可能有的等等,及前端编程潜规则等各个方方面面都综合考虑,给出最优方案.以一招胜万招. var s ...