1.概述
因为项目需要,对Qt的串口通信进行了一些学习,这个项目的一个需求是将一个测温仪器的数据读取到电脑进行处理,根据这个仪器的通信协议,每次读取前都需要对它写入命令。这里用到了Qt进行了读写操作,其中遇到了关于十六进制Write问题并得以解决。使用到的Qt库:QtSerialPort
2.详细
首先需要在mainwindow.h中添加头文件和串口类的声明,并写一个槽函数用来读取数据:
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
....
private slots:
void readData();
....
QSerialPort *serial;
然后在构造函数中进行初始化:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { serial = new QtserialPort; serial->setPortName((QString)"COM13"); // 指定端口 serial->setBaudRate(QSerialPort::Baud19200); // 设置波特率 serial->setDataBits(QSerialPort::Data8); // 设置位数 serial->setParity(QSerialPort::EvenParity); // 设置偶校验 serial->setStopBits(QSerialPort::OneStop); // 设置一个停止位 serial->setFlowControl(QSerialPort::NoFlowControl); // 设置无流控制
serial->open(QIODevice::ReadWrite); // 读写模式打开串口
connect(serial,SIGNAL(readyRead()),this,SLOT(readData())); // 连接串口的信号和槽函数
ui->setupUi(this); }
然后在槽函数中进行读取数据:
QByteArray buf; buf = serial->readAll(); // serial->readAll().toHex() 转换成16进制形式 qDebug()<<buf;
根据设备的通信协议,我进行写数据的时候总是得不到应答数据,根据协议我应该发送 "00em"加回车来获取数据,但是直接发送字符串得不到结果。后来我在串口助手上使用16进制发送,得到了数据,也就是需要发送的内容是"30 30 65 6d 0d",由于这个发送内容是从输入框中获得的,所以需要将其转换成十六进制发送,下面是转换的函数:
char ConvertHexChar(char ch) // 中间函数 { if((ch >= '0') && (ch <= '9')) return ch-0x30; else if((ch >= 'A') && (ch <= 'F')) return ch-'A'+10; else if((ch >= 'a') && (ch <= 'f')) return ch-'a'+10; else return ch-ch; } void StringToHex(QString str, QByteArray &senddata) // 转换函数 { int hexdata,lowhexdata; int hexdatalen = 0; int len = str.length(); senddata.resize(len/2); char lstr,hstr; for(int i=0; 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 == 16) || (lowhexdata == 16)) break; else hexdata = hexdata*16+lowhexdata; i++; senddata[hexdatalen] = (char)hexdata; hexdatalen++; } senddata.resize(hexdatalen); }
接下来就是发送数据了,在一个按钮的槽函数中:
QByteArray buf; QString buf_; buf_ = ui->lineEdit->text(); StringToHex(buf_,buf); serial->write(buf); // 写数据