串口通讯是最常见、最简单的通讯方式,能够方便的在计算机和设备之间建立连接。在QT中,提供了QSeriaPort类专门负责串口通讯的编程实现, QtSerialPort模块是Qt5库的附加部分,为硬件和虚拟的串口提供了统一的接口。在使用QSeriaPort前,需要在工程文件设置中添加Serial Port支持,否则编译会报错。
一、串口初始化和参数设置
1. 建立QT工程,工程的窗体基类选为Wdigets,在工程中增加Serial Port支持。添加include 串口类头文件。
#include
#include
定义串口对象
QSerialPort *m_pSerialPort;
初始化串口对象
m_pSerialPort = new QSerialPort();
2. 检查计算机中存在的串口并选择其中一个进行串口初始化
QStringList m_PortList;
foreach(const QSerialPortInfo &Info, QSerialPortInfo::availablePorts())
{
QSerialPort availablePort;
availablePort.setPortName(Info.portName());
if (availablePort.open(QIODevice::ReadWrite))
{
m_PortList.push_back(Info.portName());
availablePort.close();
}
}
3. 初始化串口并设置串口参数
m_pSerialPort->setPortName(m_PortList[(int)portNo]);
if (m_pSerialPort->open(QIODevice::ReadWrite))
{
m_pSerialPort->setBaudRate(QSerialPort::Baud9600);
m_pSerialPort->setParity(QSerialPort::EvenParity);
m_pSerialPort->setDataBits(QSerialPort::Data8);
m_pSerialPort->setStopBits(QSerialPort::OneStop);
connect(m_pSerialPort, SIGNAL(readyRead()), this, SLOT(_SerialRead()));
}
4. 串口初始化成功后可以添加串口数据读取函数,connect(m_pSerialPort, SIGNAL(readyRead()), this, SLOT(_SerialRead()));当串口上有数据输入时,自动调用函数模块_SerialRead()。
二、串口发送数据
void _writeChr(QString dataStr)
{
QByteArray sendData = dataStr.toUtf8();
if (!sendData.isEmpty() && !sendData.isNull()) {
m_pSerialPort->write(sendData);
}
}
2. 发送十六进制数
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) //字符串转换为十六进制数据0-F
{
int hexdata, lowhexdata;
int hexdatalen = 0;
int len = str.length();
senddata.resize(len / 2);
char lstr, hstr;
for (int i = 0; i < len; ) {
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);
}
void _SerialWriteHex(QString dataStr)
{
/ /如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
if (dataStr.length() % 2) {
dataStr.insert(dataStr.length() - 1, '0');
}
QByteArray sendData;
_StringToHex(dataStr, sendData);
m_pSerialPort->write(sendData);
}
三、 接收数据
void _SerialRead()
{
QByteArray temp = m_pSerialPort->readAll();
QString buf;
for (int i = 0; i < temp.count(); i++)
{
QString s;
s.sprintf("0x%02x, ", (unsigned char)temp.at(i));
buf += s;
}
QMessageBox::information(NULL, "info recieved data", buf);
}
四、退出程序,关闭串口
if (m_pSerialPort->isOpen())
{
m_pSerialPort->close();
}