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

头文件声明如下:

 #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. 【斜率DP】BZOJ 1010:玩具装箱

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7537  Solved: 2888[Submit][St ...

  2. iOS开发之loadView、viewDidLoad及viewDidUnload的关系

    iOS开发之loadView.viewDidLoad及viewDidUnload的关系 iOS开发之loadView.viewDidLoad及viewDidUnload的关系    标题中所说的3个方 ...

  3. UIALertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法

    首先,视图控制器必须得实现协议UIAlertViewDelegate中的方法,并指定delegate为self,才能使弹出的Alert窗口响应点击事件. 具体代码如下: ViewController. ...

  4. adobe 蛋疼的套装, 想安装一个Flash Professional CS6,标准版还没有...

    产品比较 查看内容 查看各 Creative Suite 6 版本的组件. Design Standard Design & Web Premium Production Premium Ma ...

  5. 安装TokuDB引擎

    前言:TokuDB 是一个高性能.支持事务处理的 MySQL 和 MariaDB 的存储引擎.TokuDB 的主要特点是高压缩比,高 INSERT 性能,支持大多数在线修改索引.添加字段,非常适合日志 ...

  6. 摄像头(2)调用系统拍照activity来录像

    import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager ...

  7. JS计算字符串所占字节数

    最近项目有个需求要用js计算一串字符串写入到localStorage里所占的内存,众所周知的,js是使用Unicode编码的.而Unicode的实现有N种,其中用的最多的就是UTF-8和UTF-16. ...

  8. C#中的多文档的使用

    1.首先,新建一个窗体,设置窗体的IsMdiContainer = true; 窗体的大小为700*600  长700  高600 2.在窗体的Load事件中添加如下代码 private void F ...

  9. C++中巧妙的位运算

    位运算要多想到与预算和异或运算,并常常将两个数对应位上相同和不同分开处理 一.x&(x-1)消除x二进制中最右边的一个1. 这个比较厉害,比如统计某个 二.与和异或的巧妙结合的思想 与运算可以 ...

  10. 基于邻接表的广度优先搜索遍历(bfs)

    题目:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2142&cid=1186 #include<stdio.h> #incl ...