摘要:上位机软件程序通过QT实现,采集输入信息,根据实际需要做出合适的串口通讯协议,实现效果如下图所示:

主要实现的功能:

1.串口基本参数可选,可调

2.显示区域可选择十六进制/asicii码显示,可根据自己的需求调整多少字节对齐,显示的比较工整,有利于解析协议

3.可自己制定协议头,其他子项内容都是以十进制输入,内置checksum自动计算

4.实时显示发送/接收字节数

5.可自己定制时间周期定时发送

6.实时显示时间

代码实现:

实现过程较为简单,主要是协议处理:

串口设备:新建串口对象 -> 寻找可用串口设置 -> 设置串口基本参数 -> 打开串口 ->监听串口

串口协议:LineEdit的内容是大端格式,所以使用的时候要将变量转换成大端,默认是小端

注意:

 QString("%1").arg(ui>lineEdit_S_num>text().toInt(),,,QChar(''))

 第一个参数 : 将Qstring转换为int型 第二个参数 : 需要将几个字符串转换成十六进制的,
如char型 :需要两个字符
short型 : 需要四个字符
int/long : 需要八个字符
第三个参数: 转换为多少进制
第四个参数: 不足位数的用0补齐
 //QByteArray里面的数据按照对应的通讯协议进行调整
void Widget::int_adjust(QByteArray &str,qint8 startcount)
{
qint8 temp1;
qint8 temp2;
temp1 = str[startcount];
temp2 = str[startcount+];
str[startcount] = str[startcount+];
str[startcount+] = str[startcount+];
str[startcount+] =temp2;
str[startcount+] =temp1;
}
void Widget::short_adjust(QByteArray &str,qint8 startcount)
{
qint8 temp1;
temp1 = str[startcount];
str[startcount] = str[startcount+];
str[startcount+] = temp1;
}
 //字符串转成十六进制实现
void Widget::StringToHex(QString str, QByteArray &senddata)
{ int hexdata,lowhexdata; int hexdatalen = ; int len = str.length(); senddata.resize(len/); char lstr,hstr; for(int i=; i<len; )
{
//char lstr,
hstr=str[i].toLatin1();
if(hstr == ' ')
{
i++;
continue;
}
i++;
if(i >= len)
break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if((hexdata == ) || (lowhexdata == ))
break;
else
hexdata = hexdata*+lowhexdata;
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
} char Widget::ConvertHexChar(char ch)
{
if((ch >= '') && (ch <= ''))
return ch-0x30;
else if((ch >= 'A') && (ch <= 'F'))
return ch-'A'+;
else if((ch >= 'a') && (ch <= 'f'))
return ch-'a'+;
else return (-); }

要点,易错点基本已经指出,其他的比较简单,这里不再赘叙

 #include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QDateTime>
#include <QMessageBox>
static int CountBase = ;
static int SENDNUMSIZE = ;
static int recvCount = ;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
serial = new QSerialPort;
/* regester software timer*/
atimer = new QTimer();
atimer->setInterval();
atimer->start(); cycletime = new QTimer();
cycletime->setInterval(ui->lineEdit_cycletime->text().toInt()); QObject::connect(atimer,&QTimer::timeout,this,&Widget::timer_handle); //查找可用的串口
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->comBox->addItem(serial.portName());
serial.close();
}
}
//设置波特率下拉菜单默认显示第0项
ui->baudBox->setCurrentIndex();
ui->baudBox->setEnabled(false);
ui->stopbitBox->setEnabled(false);
ui->databitBox->setEnabled(false);
ui->checkBox->setEnabled(false);
ui->comBox->setEnabled(false);
} Widget::~Widget()
{
delete ui;
}
void Widget::timer_handle(void)
{ QDateTime current_date_time =QDateTime::currentDateTime();
QString current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss ddd");
// ui->textBrowser_date
ui->label_date->setText(current_date); } void Widget::on_pushButton_oprea_clicked()
{
if(ui->pushButton_oprea->text() == tr("串口已关闭"))
{
serial = new QSerialPort;
//设置串口名
serial->setPortName(ui->comBox->currentText());
//打开串口
serial->open(QIODevice::ReadWrite);
//设置波特率
serial->setBaudRate(QSerialPort::Baud115200);//设置波特率为115200
//设置数据位数
switch (ui->databitBox->currentIndex())
{
case :
serial->setDataBits(QSerialPort::Data8);//设置数据位8
break;
default:
break;
}
//设置校验位
switch (ui->checkBox->currentIndex())
{
case :
serial->setParity(QSerialPort::NoParity);
break;
default:
break;
}
//设置停止位
switch (ui->stopbitBox->currentIndex())
{
case :
serial->setStopBits(QSerialPort::OneStop);//停止位设置为1
break;
case :
serial->setStopBits(QSerialPort::TwoStop);
default:
break;
}
//设置流控制
serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制 //关闭设置菜单使能
ui->baudBox->setEnabled(true);
ui->stopbitBox->setEnabled(true);
ui->databitBox->setEnabled(true);
ui->checkBox->setEnabled(true);
ui->comBox->setEnabled(true);
ui->pushButton_oprea->setText(tr("串口已打开")); //连接信号槽
QObject::connect(serial,&QSerialPort::readyRead,this,&Widget::ReadData);
}
else
{
cycletime->stop();
//关闭串口
serial->clear();
serial->close();
serial->deleteLater(); //恢复设置使能
ui->baudBox->setEnabled(false);
ui->stopbitBox->setEnabled(false);
ui->databitBox->setEnabled(false);
ui->checkBox->setEnabled(false);
ui->comBox->setEnabled(false);
ui->pushButton_oprea->setText(tr("串口已关闭"));
}
}
//读取接收到的信息
void Widget::ReadData()
{
QByteArray temp;
if(ui->HEX_SHOW->isChecked())
{
SENDNUMSIZE = ui->lineEdit_duiqi->text().toInt();
temp = serial->readAll();
QDataStream out(&temp,QIODevice::ReadWrite); //将字节数组读入
while(!out.atEnd())
{
qint8 outChar = ;
static qint8 datacount = ;
recvCount++;
out>>outChar; //每字节填充一次,直到结束
datacount++;
//十六进制的转换
QString str = QString(" %1").arg(outChar&0xFF,,,QLatin1Char(''));
ui->textBrowser->insertPlainText(str);
ui->label_recvvalue->setNum(recvCount);
if(SENDNUMSIZE+ == datacount)
{
datacount = ;
ui->textBrowser->insertPlainText("\n");
ui->textBrowser->moveCursor(QTextCursor::End);
}
}
}
else
{ temp += serial->readAll();
if(!temp.isEmpty())
{
ui->textBrowser->append(temp);
ui->textBrowser->moveCursor(QTextCursor::End);
}
temp.clear();
} }
short Widget::checksum(QByteArray ba)
{
short i = ,sumValue = ; for(i=;i<(ba.length());i++)
{
sumValue+=ba.at(i);
}
return sumValue;
} void Widget::on_send_clicked()
{
short checkValue = ;
QString str;
QByteArray senddata;
if(ui->pushButton_oprea->text() == tr("串口已关闭"))
{
QMessageBox::information(this, "warning", "串口没打开", QMessageBox::Yes); }
if(ui->radio_dash->isChecked())
{
str = ui->lineEdit_head->text()
+ QString("%1").arg(ui->lineEdit_infopage->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_menu->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_speed->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_FP->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_BP->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_gear->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_hour->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_minute->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_TemP->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_trip->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_C_Trip->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_odo->text().toInt(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_LF_Press->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_LB_Press->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_RF_Press->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_RB_Press->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_oil_cost->text().toInt(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_C_oilcost->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_AV_oil_cost->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_can_warning->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_icon->text().toShort(),,,QChar(''))//
+ QString("%1").arg(ui->lineEdit_backlight->text().toShort(),,,QChar(''));
/*************** 调整short 和 init 数据类型字节发送顺序 ****************/
StringToHex(str,senddata);//将str字符串转换为16进制的形式
short_adjust(senddata,);
short_adjust(senddata,);
short_adjust(senddata,);
int_adjust(senddata,);
short_adjust(senddata,);
short_adjust(senddata,);
short_adjust(senddata,);
short_adjust(senddata,);
int_adjust(senddata,);
short_adjust(senddata,);
}
else{
str = ui->lineEdit_head->text()
+ QString("%1").arg(ui->lineEdit_ST_Page->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_menu_level->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_cursor->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_C_selcet->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_num->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_num->text().toInt(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_hour->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_minute->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_year->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_month->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_day->text().toShort(),,,QChar(''))
+ QString("%1").arg(ui->lineEdit_S_backlight->text().toShort(),,,QChar(''));
/*************** 调整short 和 init 数据类型字节发送顺序 ****************/
StringToHex(str,senddata);//将str字符串转换为16进制的形式
int_adjust(senddata,);
short_adjust(senddata,);
} checkValue = checksum(senddata);
senddata.append((char)(checkValue));
serial->write(senddata);//发送到串口
CountBase+=senddata.length(); ui->label_sendvalue->setNum(CountBase);
}
void Widget::int_adjust(QByteArray &str,qint8 startcount)
{
qint8 temp1;
qint8 temp2;
temp1 = str[startcount];
temp2 = str[startcount+];
str[startcount] = str[startcount+];
str[startcount+] = str[startcount+];
str[startcount+] =temp2;
str[startcount+] =temp1;
}
void Widget::short_adjust(QByteArray &str,qint8 startcount)
{
qint8 temp1;
temp1 = str[startcount];
str[startcount] = str[startcount+];
str[startcount+] = temp1;
} void Widget::StringToHex(QString str, QByteArray &senddata)
{ int hexdata,lowhexdata; int hexdatalen = ; int len = str.length(); senddata.resize(len/); char lstr,hstr; for(int i=; i<len; )
{
//char lstr,
hstr=str[i].toLatin1();
if(hstr == ' ')
{
i++;
continue;
}
i++;
if(i >= len)
break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if((hexdata == ) || (lowhexdata == ))
break;
else
hexdata = hexdata*+lowhexdata;
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
} char Widget::ConvertHexChar(char ch)
{
if((ch >= '') && (ch <= ''))
return ch-0x30;
else if((ch >= 'A') && (ch <= 'F'))
return ch-'A'+;
else if((ch >= 'a') && (ch <= 'f'))
return ch-'a'+;
else return (-); } void Widget::on_pushButton_clicked()
{
ui->textBrowser->clear();
CountBase = ;
ui->label_sendvalue->setNum();
recvCount = ;
ui->label_recvvalue->setNum();
}
void Widget::cycletime_handle(void)
{
on_send_clicked();
}
void Widget::on_lineEdit_duiqi_editingFinished()
{
SENDNUMSIZE = ui->lineEdit_duiqi->text().toInt();
} void Widget::on_checkBox_TIMER_stateChanged(int arg1)
{
if(ui->checkBox_TIMER->isChecked())
{
cycletime->start();
QObject::connect(cycletime,&QTimer::timeout,this,&Widget::cycletime_handle);
}
else
{
cycletime->stop();
} }

all code

qt实现串口通讯的更多相关文章

  1. 树莓派中QT实现串口通讯

    树莓派中QT实现串口通讯 开发平台为QT 此博客QT使用的为WiringPi驱动 我使用的串口调试助手为 cutecom 先简单说一些开发过程中需要注意的问题 Linux 下设备为 tty ,对应在 ...

  2. QSerialPort-Qt串口通讯

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSerialPort-Qt串口通讯     本文地址:http://techieliang. ...

  3. 嵌入式Linux学习笔记(六) 上位机QT界面实现和串口通讯实现

    目录 (1).参考资料 (2).QT界面布局实现 (3).数据和操作逻辑 在上一章我们实现了下位机的协议制定,并通过串口通讯工具完成了对设备内外设(LED)的状态修改,下面就要进行上位机软件的实现了( ...

  4. Qt之先用了再说系列-串口通讯(单串口单线程)

    QT 串口通讯(单串口单线程) 串口通讯在我们写程序的时候或多或少会用到,借此在这记录一下QT是如何使用串口来通讯的.本次先侃侃在单线程下使用1个串口来通讯过程.好了,废话不多说,直接看步骤,我们的宗 ...

  5. Qt实现串口通信总结

    Qt实现串口通信总结 注意: Qt5发布之前,Qt实现串口通信一般是采用第三方类库qextserialport.Qt5发布后自带了QtSerialPort 能够支持串口通信. 1.Qextserial ...

  6. Qt 编写串口调试助手

    一.成品图展示 成品图如下所示: 二.串口通讯步骤 1.在工程文件(.pro)中添加串口通信相关运行库:QT += serialport 2.在头文件中添加: #include <QSerial ...

  7. C#串口通讯实例

    本文参考<C#网络通信程序设计>(张晓明  编著) 程序界面如下图: 参数设置界面代码如下: using System; using System.Collections.Generic; ...

  8. delphi之动态库调用和串口通讯

    串口通讯: Spcomm 控件属性: CommName  :表示COM1,COM2等串口的名字: BaudRate:设定波特率9600,4800等 StartComm StopComm 函数Write ...

  9. 用SPCOMM 在 Delphi中实现串口通讯 转

      用Delphi 实现串口通讯,常用的几种方法为:使用控件如MSCOMM和SPCOMM,使用API函数或者在Delphi 中调用其它串口通讯程序.利用API编写串口通信程序较为复杂,需要掌握大量通信 ...

随机推荐

  1. Web之-----弹出确认框控件应用

    引用文件!-------- <link rel="stylesheet" type="text/css" href="@Url.FrontUrl ...

  2. CSS——样式表的引入

    1.内部样式表 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  3. 会用python把linux命令写一遍的人,进大厂有多容易?

    看过这篇<2000字谏言,给那些想学Python的人,建议收藏后细看!>的读者应该都对一个命令有点印象吧?没错,就是 linux 中经常会用到的 ls 命令. 文章中我就提到如何提升自己的 ...

  4. 21 (OC) 数据持久化

    概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...

  5. .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用

    书接上文,继续搭建我们基于.netCore 的开发框架.首先是我们的项目分层结构. 这个分层结构,是参考张老师的分层结构,但是实际项目中,我没有去实现仓储模型.因为我使用的是EFCore ,最近也一直 ...

  6. RDD基本操作之Action

    Action介绍 在RDD上计算出来一个结果 把结果返回给driver program或保存在文件系统,count(),save 常用的Action reduce() 接收一个函数,作用在RDD两个类 ...

  7. Beescms_v4.0 sql注入漏洞分析

    Beescms_v4.0 sql注入漏洞分析 一.漏洞描述 Beescms v4.0由于后台登录验证码设计缺陷以及代码防护缺陷导致存在bypass全局防护的SQL注入. 二.漏洞环境搭建 1.官方下载 ...

  8. 【linux】【PostgreSQL】PostgreSQL安装

    前言 PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统.POSTGR ...

  9. Python + opencv 实现图片文字的分割

    实现步骤: 1.通过水平投影对图形进行水平分割,获取每一行的图像: 2.通过垂直投影对分割的每一行图像进行垂直分割,最终确定每一个字符的坐标位置,分割出每一个字符: 先简单介绍一下投影法:分别在水平和 ...

  10. Regex分组与Pattern正则表达式对象

    1.正则规则:        1.String  regex  =  "[1-9]"          表示单个字符的取值范围是 1~9,注意是单个字符的取值范围        2 ...