//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
isOpen = false;
//遍历可用的串口
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
//串口可打开则放到列表选项上
if (serial.open(QIODevice::ReadWrite))
{
ui->PortComboBox->addItem(info.portName());
serial.close();
}
}
my_serialport= new QSerialPort();//初始化串口
QObject::connect(ui->OpenButton,SIGNAL(clicked(bool)),this,SLOT(set_SerialPort())); //打开按钮按下时触发
QObject::connect(my_serialport,SIGNAL(readyRead()),this,SLOT(my_readData())); //接收到数据时触发
QObject::connect(ui->SendButton,SIGNAL(clicked(bool)),this,SLOT(my_sendData())); //发送按钮按下时触发
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::my_readData()
{
QByteArray requestData;
requestData = my_serialport->readAll(); //读取数据
if(requestData!= NULL)
{
if(ui->HexCheckBox->isChecked())
{
ui->ReceiveTextEdit->append(tr(requestData.toHex())); //使用16进制显示
}
else
{
ui->ReceiveTextEdit->append(tr(requestData));
}
}
requestData.clear();
}
void MainWindow::set_SerialPort()
{
if(!isOpen)
{
isOpen = true;
my_serialport->setPortName(ui->PortComboBox->currentText()); //设置端口号
my_serialport->open(QIODevice::ReadWrite); //要先打开才能设置,否则出错
my_serialport->setBaudRate(ui->BaudComboBox->currentText().toInt()); //设置波特率
switch(ui->DataBitComboBox->currentIndex()) //设置数据位
{
case 0: my_serialport->setDataBits(QSerialPort::Data8);break;
case 1: my_serialport->setDataBits(QSerialPort::Data7);break;
case 2: my_serialport->setDataBits(QSerialPort::Data6);break;
}
switch(ui->StopBitComboBox->currentIndex()) //设置停止位
{
case 0: my_serialport->setStopBits(QSerialPort::OneStop);break;
case 1: my_serialport->setStopBits(QSerialPort::TwoStop);break;
}
my_serialport->setParity(QSerialPort::NoParity); //校验位
my_serialport->setFlowControl(QSerialPort::NoFlowControl); //流控
ui->OpenButton->setText("关闭串口");
connect(my_serialport,SIGNAL(readyRead()),this,SLOT(my_readData())); //可以接收串口数据了
}
else
{
isOpen = false;
ui->OpenButton->setText("打开串口");
my_serialport->close();
}
}
void MainWindow::my_sendData()
{
if(ui->HexSendCheckBox->isChecked())
{
QByteArray sendData;
String2Hex(ui->SendTextEdit->toPlainText(),sendData); //16进制发送
my_serialport->write(sendData);
}
else
{
my_serialport->write(ui->SendTextEdit->toPlainText().toLatin1());
}
}
//将一个字符串转换成字节数组
void MainWindow::String2Hex(QString str, QByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen = 0;
int len = str.length(); //字符串长度
senddata.resize(len/2); //两个字符转成一个字节的16进制,所以先预定一个大小
char lstr,hstr;
for(int i=0; i<len; )
{
hstr=str[i].toLatin1(); //将每个字符都转成ASCII码
if(hstr == ' ') //判断是否为空格
{
i++;
continue;
}
i++;
if(i >= len)
break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr); //字符转换成16进制数
lowhexdata = ConvertHexChar(lstr);
if((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata*16+lowhexdata; //两个字符转成一个字节的16进制数
i++;
senddata[hexdatalen] = (char)hexdata; //保存到字节数组中
hexdatalen++;
}
senddata.resize(hexdatalen); //设置实际的字节数组大小
}
//将一个字符转换成16进制数
char MainWindow::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 (-1);
}