Qt:串口通信

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); // 写数据

 

posted @ 2017-05-08 09:41  whlook  阅读(3820)  评论(0编辑  收藏  举报