在QT中,当我们编写的程序需要和硬件通讯时,一般常用串口的方式处理数据,别管是RS232还是RS485,对QT来说都是一样的,需要建立QSerialPort对象,至少需要包含#include <QtSerialPort/QtSerialPort>,然后建立对象,设置对象参数。
m_serial = new QSerialPort(); //m_serial 是对象名称,需要New出来
m_serial->setPortName(portName); //设置端口号,比如com3
m_serial->setBaudRate(baudRate); //设置波特率,常用9600/19200/38400/115200这几种,现在设备越来越先进,默认用115200的越来越多
m_serial->setParity(QSerialPort::NoParity); //设置奇偶校验,一般不设,用QSerialPort::NoParity参数
m_serial->setDataBits(QSerialPort::Data8); //数据位5、6、7、8,一般用Data8
m_serial->setStopBits(QSerialPort::OneStop); //停止位,常用1位,也有1.5和2位的,比较少
m_serial->setFlowControl(QSerialPort::NoFlowControl); //没有流控
m_serial->setReadBufferSize(1024); //设置一个最大缓存1024字节,其实如果你数据处理的过来,设置成你最大数据包的两三倍就够了
参数设置完成后,需要打开串口,这样才算完成串口的创建。
m_serial->open(QSerialPort::ReadWrite) // bool QSerialPort::open(QIODevice::OpenMode mode)
可以根据open函数的返回值是true或者false判断端口建否建立成功,如果系统含有该串口并且该串口没有被其他程序绑定,那么一般会绑定成功的。
QT接收串口数据可以存在char数组或者QByteArray里边,接收数据一般用QSerialPort::readyRead信号,然后绑定槽函数,利用m_serial->readAll()接收数据,readAll函数默认返回的是QByteArray类型,所以常用QByteArray接收和处理串口传过来的数据,
connect(m_serial,&QSerialPort::readyRead,this,&MainSerial::receiveData);
void MySerial::receiveData()
{
QByteArray data;
data = m_serial->readAll();
//然后根据项目需要,处理data数据
}
然后进入正题,如果是公司开发的单片机程序,在数据传输稳定且数据量不是太大的情况下,好多都是用和校验的方式校验数据的完整性,虽然没有CRC16那么严格,但是也算比较简单好用的一种校验方式,下面直接上代码,说一下串口发过来的QByteArray数据,如何进行和校验确认数据完整性:
bool sumCheck(QByteArray data)
{
int sum = 0;
for(int i = 0; i < data.size()-1; i++)
{
sum += data.at(i);
}
quint8 lastSum = sum;
return (lastSum == (quint8)(data.at(data.size()-1))) ? true : false;
}
发送过来的数据,存到一个QByteArray之后,可以传入上边的函数进行和校验,返回值为true,则校验成功,false为检验失败,数据不是完整数据,一般校验失败后数据废弃不用。
这个方法是QByteArray最后一位数据前边的所有数据for循环加和,求得的和sum为4位的int类型,而校验和一般为1位数据,所以一般只取int的最低位,然后求得的和lastSum和data的最后一位数据比较大小,两个数值相同返回true,表明校验成功。
同样,在我们给单片机通过串口发送消息时,我们也要把数据的最后一位加上校验和,然后发送出去,校验和计算和上边很像,也是通过一个for循环计算出QByteArray所有数据的和,和校验通常大于255,我们只取最后一位数据,直接把int赋值给quint8就行了,参考下边的代码:
quint8 addSum(QByteArray data)
{
int i_sum = 0;
for(int i = 0; i < data.size()-1; i++)
{
i_sum += data.at(i);
}
quint8 b_sum = i_sum;
return b_sum;
}
返回值直接是一个一位的quint8类型数据, 可以用memcpy函数复制到待发送数据QByteArray的最后一位上边去,然后直接用建立好的串口对象write出去就算完成串口数据发送了。