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

头文件声明如下:

 #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. 图片流滚动效果html代码(复制)

    <!doctype html> <html> <head>     <meta charset="utf-8" />     < ...

  2. HeadFirst设计模式之组合模式

    一. 1.The Composite Pattern allows us to build structures of objects in the form of trees that contai ...

  3. ANDROID_MARS学习笔记_S01_005CheckBox

    一. 1.checkbox_layout.xml <?xml version="1.0" encoding="utf-8"?> <Linear ...

  4. (转)Android系统自带样式(@android:style/)

    在AndroidManifest.xml文件的activity中配置 1.android:theme="@android:style/Theme" 默认状态,即如果theme这里不 ...

  5. Silverlight之Styles和Behaviors

    本文简介 1.定义简单的Style 2.应用Style到元素 3.动态加载Style资源文件 4.Style的继承 5.组织内编写Style(在元素内) 6.自动应用Style到指定类型元素 7.St ...

  6. android SharedPreferences 使用

    除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值 对数据,通常用来存储一些简单的配置信息.其存储位置在/dat ...

  7. 更新Windows ActiveX,Ios

    两天内连续更新Windows ActiveX,和IOS两个平台. Windows ActiveX更新主要是添加加密流在线播放支持. IOS是优化渲染视频. Windows ActiveX 相关地址:h ...

  8. SequenceSum

    SequenceSum Sum of 'n' Numbers sum_of_n (or SequenceSum.sumOfN in Java, SequenceSum.SumOfN in C#) ta ...

  9. Angularjs中input的指令和属性

    建议添加 novalidate属性(可无值)到form标签上,这样可以保证在表单不合法的情况下阻止浏览器继续提交数据. 可以给表单元素 input 添加 required 属性(可无值),让该表单成为 ...

  10. 十条常用nmap命令行格式

    十条常用nmap命令行格式 ) 获取远程主机的系统类型及开放端口 nmap -sS -P0 -sV -O <target> 这里的 < target > 可以是单一 IP, 或 ...