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); // 寫數據