简单的小工具是VS2015 + Qt5.6.1实现的,界面部分是Qt实现,串口是封装的WinAPI,把串口收发模块封装成了个Serialport.dll 供Qt界面调用。

由于VS2015需要Universal CRT运行环境,因此把Qt编译成了静态的版本。

一、串口收发是封装的Win32,单独封装成了一个Serialport.dll.

包括串口通信类:

class CSerialport
{
public:
CSerialport();
~CSerialport();
BOOL openComm(const string & name);
BOOL closeComm();
BOOL setCommState(const DCB & dcb)const;
BOOL getCommState(DCB & dcb)const;
BOOL setCommTimeouts(const COMMTIMEOUTS & commtimeOuts)const;
BOOL purgeComm(DWORD flags = PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT)const;
BOOL setupComm(DWORD dwInQueue, DWORD dwOutQueue)const;
int readFile(vector<char> & buffer, DWORD nNumberOfBytesToRead,DWORD & lpNumberOfBytesRead, LPOVERLAPPED pLoverlapped = NULL);
int writeFile(vector<char> & buffer, DWORD nNumberOfBytesToRead, DWORD & lpNumberOfBytesRead, LPOVERLAPPED pLoverlapped = NULL);
string getPortName()const;
HANDLE getHandle()const;
//
private:
HANDLE m_hspCom;
string m_commName;
};

此类负责基本的串口通信。

线程类:

 class CBaseThread
{
public:
CBaseThread(void);
virtual ~CBaseThread(void);
public:
virtual void start(); //创建线程
virtual void end(); //结束线程
virtual void resume(); //重启线程
virtual void suspend(); //暂停线程
//
virtual int getThreadID() const; //获得线程ID
virtual BOOL isRun() const; //判断线程是否运行
virtual void runTask() = ; //子类实现此函数完成业务逻辑
//
static unsigned _stdcall threadFunc(void* pParam); //线程函数,调RunTask逻辑 protected:
HANDLE m_hEndEvent; //设置退出线程处理
HANDLE m_hExitEvent; //线程RunTask结束时设置,确保线程正常退出
HANDLE m_hThreadHandle;
unsigned int m_uThreadID;
//
};

线程基类,封装了_beginthreadex()。

串口线程调度线程:

typedef int (*pGET_DATA_CAAL_BACK)(list<char> &);

class CSerialportThread :
public CBaseThread
{
public:
CSerialportThread(void);
virtual ~CSerialportThread(void);
void setCommConfig(const char* com, int baudRate, char byteSize, char parity, char stopBits);
static CSerialportThread * getInstance();
int writeFile(const char * writeBuffer,int size);
void initCallBack(void *);
protected:
virtual void runTask();
void initComm();
protected:
CSerialport m_serialport;
//
string m_com;
int m_baudRate;
char m_byteSize;
char m_parity;
char m_stopBits;
bool m_bInit;
pGET_DATA_CAAL_BACK m_addDataCallBack;
};

继承CBaseThread实现runTask()线程函数,由CSerialport 类成员变量进行串口的通信的管理,并提供一个回调接口,将接收到的数据回调给接收数据维护的类。

串口数据接收维护类:

class CCommDataHolder
{
public:
CCommDataHolder();
~CCommDataHolder();
//
static std::shared_ptr<CCommDataHolder> getInstance();
static int getDataCallBackS(list<char> & buffer); int getCommData(char * buffer,int len);
protected:
int getDataCallBack(list<char> & buffer);
//
private:
static std::shared_ptr<CCommDataHolder> s_pInstance;
static std::mutex s_mt;
//
list<char> m_listData;
std::mutex m_mt;
};

数据维护类,上层应用来这里取数据即可。

Serialport.dll导出接口:

 #pragma once

 #define SERIALPORT_DLL_EXPORT __declspec(dllexport)

 #ifdef __cplusplus
extern "C"
{
#endif // SERIALPORT_DLL_EXPORT int commReadData(char* buffer,int size);
SERIALPORT_DLL_EXPORT int commWriteData(const char* buffer, int size);
SERIALPORT_DLL_EXPORT void setCommConfig(const char* com,int baudRate,char byteSize,char parity,char stopBits);
SERIALPORT_DLL_EXPORT void start();
SERIALPORT_DLL_EXPORT void end(); #ifdef __cplusplus
}
#endif //

二、Qt界面实现

界面实现主要是设置串口的通信的参数,然后设置串口通信的收发区域,这里使用textEdit控件,然后设置了一下数据的展现方式,分ASCII和HEX(16进制发送),

16进制发送的形式应该为: 61 25 AA 7A 5B的这种形式,然后选择Hex选项,发送。

串口列表:自动枚举系统的所有已存在串口enumPort(QStringList & strList)

 void SerialPortTools::enumPort(QStringList & strList)
{
HKEY hKey;
LPCTSTR lpSubKey = _T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\"); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, , KEY_READ, &hKey) != ERROR_SUCCESS)
{
return;
}
WCHAR szValueName[] = { };
WCHAR szPortName[] = { };
LONG status;
DWORD dwIndex = ;
DWORD dwSizeValueName = ;
DWORD dwSizeofPortName = ;
DWORD Type;
dwSizeValueName = ;
dwSizeofPortName = ;
do
{
status = RegEnumValue(hKey, dwIndex++, szValueName, &dwSizeValueName, NULL, &Type, (PUCHAR)szPortName, &dwSizeofPortName);
if ((status == ERROR_SUCCESS))
{
QString tmp = CCodecUtils::str2qstr(CEcoder::wstringToString(szPortName));
strList << tmp;
}
dwSizeValueName = ;
dwSizeofPortName = ;
} while ((status != ERROR_NO_MORE_ITEMS));
RegCloseKey(hKey);
}

设置好串口参数,串口号,波特率,数据位,校验位,停止位等参数后setCommConfig(com.c_str(), baudRate, byteSize, parity, stopBit);

,打开串口start();开启调度串口通信线程。

打开串口需要引用Serialport.dll的接口函数

 void SerialPortTools::openPort()
{
QString strCom = ui.comboBox->currentText();
QString strBaudRate = ui.comboBox_2->currentText();
QString strByteSize = ui.comboBox_3->currentText();
//
string com = CCodecUtils::qstr2str(strCom);
int baudRate = strBaudRate.toInt();
int byteSize = strByteSize.toInt();
int parity = ui.comboBox_4->currentIndex();
int stopBit = ui.comboBox_5->currentIndex();
setCommConfig(com.c_str(), baudRate, byteSize, parity, stopBit);
//
start();
m_timer.start();
MessageBoxInfo(tr("提示"), tr(" 串口打开成功 "));
ui.openaction->setEnabled(false);
ui.closeaction->setEnabled(true);
}

数据接收的实现是设置了一个定时器,不断去调用commReadData(char* buffer,int size) 去读取dll数据缓存区的数据,读到之后更新到数据接收区的界面。

发送则很简单,获取数据发送区的内容,点击发送,直接调用commWriteData(const char *buffer,int size)发送串口数据。

定时器:

     m_timer.setInterval();
connect(&m_timer, SIGNAL(timeout()), this, SLOT(reciveData()));

数据收:

 void SerialPortTools::reciveData()
{
char szRead[] = { };
memset(&szRead, , );
int nRet = commReadData(szRead, );
m_strRec = CCodecUtils::qstr2str(ui.textEdit->toPlainText());
if (nRet != )
{
string str = szRead;
m_strRec += str;
if (ui.radioButton->isChecked())
{
ui.textEdit->setText(CCodecUtils::str2qstr(m_strRec));
}
else if (ui.radioButton_2->isChecked())
{
char sz[];
memset(&sz, , );
ui.textEdit->setText(CCodecUtils::str2qstr(CCodecUtils::byte2HexCpp(m_strRec)));
}
}
}

数据发:

 void SerialPortTools::sendData()
{
QString str = ui.textEdit_2->toPlainText();
string strSend = CCodecUtils::qstr2str(str);
if (!strSend.empty())
{
//
if (ui.radioButton_3->isChecked())
{
commWriteData(strSend.c_str(), strSend.length() + );
}
else if (ui.radioButton_4->isChecked())
{
string strtmp = CCodecUtils::hexStr2Str(CCodecUtils::eraseSpace(strSend));
commWriteData(strtmp.c_str(),strtmp.length()+);
//
}
}
}

串口关闭end();

 void SerialPortTools::closePort()
{
end();
ui.openaction->setEnabled(true);
ui.closeaction->setEnabled(false);
}

软件运行:

用虚拟串口工具打开COM1和COM2两个串口对,打开两次SerialPortTools.exe ,分别打开COM1和COM2,进行简单的数据通信测试。

源码地址:https://github.com/karllen/SerialPortTools

VS2015 +Qt5 串口工具的更多相关文章

  1. 【转】 Ubuntu下配置USB转串口及串口工具配置--不错

    原文网址:http://blog.csdn.net/dreambegin/article/details/6985028 注意:默认情况下ubuntu已经安装了USB转串口驱动(pl2303).我的是 ...

  2. 好久没来了,重出江湖,共享个python34+pyqt+pyserial串口工具源码

    真的是好久没来了,写博客对我来说还真是难坚持下来,热度一过就忘了,就算什么时候想起来也懒得去敲一个字,这次真不知道能坚持多久,随心吧,想写写,不想写也不勉强自己. 最近由于工作调试需要自己写了一个带图 ...

  3. VS2015集成新潮工具4

    VS2015集成新潮工具(四)   本课程来源与微软connect视频教程,Modern Web Tooling in Visual Studio 2015 本课程主要讲下当下流行的前端工具 bowe ...

  4. Minicom串口工具安装及配置

    Minicom串口工具安装及配置 1. 简述 嵌入式开发多采用串口线连接电脑进行开发及调试. 2 安装及配置串口工具(以Minicom为例) Tiny4412开发板提供的有RS232电平的DB9公头接 ...

  5. tftp服务、串口工具minicom

    linux下安装tftp服务 参考这位仁兄的经验 确实百度上很多关于配置tftp服务的方法,但是这篇文章的介绍真的是很精简,对于一个刚接触纯linux环境的小白来说是很舒服的一件事. 首先是安装tft ...

  6. Windows下PythonQt编译(vs2015+Qt5.11.2+PythonQt 3.2)探索

    时间:2018年10月20日 笔者最近在做Qt方面的开发工作,需用到脚本程序对程序内部进行扩展,就很自然的想到了PythonQt,下面介绍PythonQt在Windows下的的安装编译心得,水平有限, ...

  7. 通过串口工具下发指令的Python脚本

    前言 最近一段时间在测试物联网相关的App自动化,涉及通过串口工具给硬件设备下发指令. 使用的串口工具:SecureCRT 解决办法 通过引用Python的第三方库:serial,通过编写Python ...

  8. vs2015 qt5.8新添加文件时出现“无法找到源文件ui.xxx.h”

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7147135.html vs2015 qt5.8新添加文件时出现“无法找到源文件ui.xxx.h” 暂时解决版本 ...

  9. 物联网架构成长之路(37)-基于C#开发串口工具

    0. 前言 作为物联网平台开发,最基础的工具链还是要有的.前几篇博客,介绍了用C#开发一个MQTT的客户端,用于模拟设备连接平台,并发送数据到平台.但是对于一些硬件来说,可能会用到串口uart来发送数 ...

随机推荐

  1. KafKa+Zookeeper+Flume部署脚本

    喜欢学习的朋友可以收藏 愿意了解框架技术或者源码的朋友直接加求求(企鹅):2042849237

  2. jsp中的request.setAttribute的使用

    1.第一个jsp页面 <form id="form1" method="post" action="first.jsp"> &l ...

  3. 9、JcomboBox下拉框事件监听

    9.JcomboBox下拉框事件监听 JComboBox()的事件监听类ItemListener.其范例代码如下: import java.awt.*; import java.awt.event.* ...

  4. StringBuffer类的使用

    //简单记录下Java中StringBuffer类的基本功能使用public class Test01{ public static void main(String[] args){ //New一个 ...

  5. CMT2300 收发一体 SUB 1G 支持灵活选频

    CMT2300A 是一款超低功耗,高性能,适用于各种140 至1020 MHz 无线应用的OOK,(G)FSK 射频收发器.它是CMOSTEK NextGenRFTM 射频产品线的一部分,这条产品线包 ...

  6. Comparing the contribution of NBA draft picks(转)

    When it comes to the NBA draft, experts tend to argue about a number of things: at which position wi ...

  7. Asp.Net Core MVC项目实现多语言(Globalization/Localization)

    正好最近手上在给一个Razor MVC项目实现一个多语言功能,叫Globalization也好,Localization也好,whatever.最终要实现的效果呢,就是一键切换全站语言,并且开发的时候 ...

  8. Java的必备开发工具

    身为一个Java开发的爱好者,你不得不承认需要安装以下软件 NO.1 Java开发工具包 Java JDK 可以说这个工具包不得不安装,因为这个工具包是开发Java程序的核心! Java JDK工具包 ...

  9. js添加多个样式属性cssText

    document.getElementById("box").style.cssText += ";color:red;font-size:20px"; 代码分 ...

  10. sql还原(.mdf文件还原)

    第一步: 把备份文件放到目录:C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA (默认)(这里用 MyDB.md ...