这几天一直再看串口相关知识,对于其总结为如下串口类:

头文件声明如下:

 #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的一个串口类的更多相关文章

  1. mfc 创建一个C++ 类

     类创建向导  添加一个C++类  #pragma once的作用  认识类视图 一.类创建向导 二.添加一个C++类 认识类创建向导: 创新一个处理文字信息的类CMessage CMessa ...

  2. 一个由印度人编写的VC串口类

    http://www.cnblogs.com/lwngreat/p/4098374.html 软件介绍 一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些 ...

  3. C运行时库(C Run-time Library)详解(提供的另一个最重要的功能是为应用程序添加启动函数。Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)

    一.什么是C运行时库 1)C运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“ ...

  4. MFC中如何在一个类中调用另一个类的控件

    学习记录: 两个类,一个为主类 1个为:CCkDlg,主类 1个为: Https,用来做HTTPS请求获得页面状态. 测试界面如下: CCkDlg 类里定义函数 void CCkDlg::printf ...

  5. 谢欣伦 - OpenDev原创教程 - 串口类CxSerial

    这是一个精练的串口类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. 串口类CxSerial的使用如下(以某个叫做CSomeClass ...

  6. 使用libzplay库封装一个音频类

    装载请说明原地址,谢谢~~      前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...

  7. MFC下对串口的操作以及定时器的调用

    最近研究了一下MFC下对串口的操作,测试了一下对设备的读写. 1.打开串口 GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(FALSE); m_hComm = ...

  8. MFC学习之CWinApp类

    CWinApp是一个基类,你通过它来继承Windows应用程序对象.应用程序对象为你提供了初始化应用程序(以及它的每一个实例 和运行应用程序所需的成员函数.它实现主事件循环并把事件分发给MFC中其他类 ...

  9. MFC中的CString类使用方法指南

    MFC中的CString类使用方法指南 原文出处:codeproject:CString Management [禾路:这是一篇比较老的资料了,但是对于MFC的程序设计很有帮助.我们在MFC中使用字符 ...

随机推荐

  1. chardet安装

    1.下载 chardet-2.2.1.tar.gz (md5)   https://pypi.python.org/pypi/chardet#downloads 2.解压至C:\Python27\Li ...

  2. c++实现文本中英文单词和汉字字符的统计

    源代码下载:http://download.csdn.net/detail/nuptboyzhb/4987141 1.统计文本中汉字的频数,为后续的文本分类做基础.对于汉字的统计,需要判断读取的是否为 ...

  3. MVC项目总结(别人的好文章)

    引用 http://www.cnblogs.com/xling/archive/2012/07/11/2587002.html

  4. java 串口通信 代码

    下面是我自己实现的串口接收的类,串口发送比较简单,就直接发送就可以了.下面的这个类可以直接使用. package com.boomdts.weather_monitor.util; import ja ...

  5. editplus的配置文件来支持sql语法高亮【转】

      editplus默认是没有sql语法高亮的,原因是它的内部没有sql.stx的这样一个语法文件 我们自己在 EditPlus 的安装目录下面新建一个文件名为sql.stx,然后打开editplus ...

  6. 锋利的JQuery-Jquery中DOM操作

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  7. javascript里的post和get有什么区别

    FORM中的get post方法区别Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法.二者主要区别如下: 1.Get是用来从服务器上获得数据,而Post ...

  8. 2434: [Noi2011]阿狸的打字机

    ac自动机,bit,dfs序. 本文所有的stl都是因为自己懒得实现.   首先x在y里面出现,就意味y节点可以顺着fail回去. 反向建出一个fail数,然后搞出dfs序列.找出x对应的区间有多少个 ...

  9. Unity3D之如何创建正确的像素比在屏幕上

    关于这篇文章的命名,实在不知道怎么命名好,大概功能就是:比如一张宽高为100x100的图片显示在屏幕上,那2D摄像头的Size值为多少时,屏幕上显示出来图片大小和图片的实际像素一致. 这里涉及到一个G ...

  10. [ACdream 1099] 瑶瑶的第K大

    瑶瑶的第K大 Time Limit: 4000/2000MS (Java/Others) Memory Limit: 256000/128000KB (Java/Others) Problem Des ...