用QT做串口通讯,自己用的是一所的身份证模块
首先说明QT里面用作串口通讯的是 QSerialPort ,QSerialPortInfo
按照流程
1:检索串口,找到电脑上可以用的串口号
2:打开串口
3:找卡—>选卡—>读卡——>解析
首先这是ui界面
1:检索串口
void Widget::search_seriaport()//检索串口
{
seriaport = new QSerialPort;//new一个串口类对象出来
if(seriaport != NULL)
{
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {//检索可用的串口,并将它显示在ui里面的combobox里面
QSerialPort seria_port;
seria_port.setPort(info);
if(seria_port.open(QIODevice::ReadWrite))
{
if(ui->comboBox->count() != 0)
{
for(int i=0;i<ui->comboBox->count();i++)
{
if(ui->comboBox->itemText(i).compare(seria_port.portName()) == 0)
ui->textEdit->append(QString::fromLocal8Bit("端口已经找到,并且已经显示"));
else
ui->comboBox->addItem(seria_port.portName());
}
}
else
ui->comboBox->addItem(seria_port.portName());
}
seria_port.close();
}
}
else
{
qDebug()<<"seriaport is null"<<endl;
}
}
2:打开串口
void Widget::openport()
{
if(seriaport == NULL)
seriaport = new QSerialPort;
if(seriaport->isOpen())
seriaport->close();
if(ui->comboBox->count() != 0)
{
seriaport->setPortName(ui->comboBox->currentText());//设置端口名
seriaport->setBaudRate(QSerialPort::Baud115200);//设置波特率
seriaport->setDataBits(QSerialPort::Data8);//设置位数
seriaport->setStopBits(QSerialPort::OneStop);//设置停止位数
seriaport->setParity(QSerialPort::NoParity);//设置奇偶性校验
seriaport->setFlowControl(QSerialPort::NoFlowControl);//设置控制流
seriaport->setReadBufferSize(1024);//设置读取的大小
if(!seriaport->open(QIODevice::ReadWrite))
qDebug()<<"seriaport open error"<<endl;
bool flag = connect(seriaport,SIGNAL(readyRead()),this,SLOT(hand_card()));
ui->textEdit->append(QString("%1").arg(flag));
qDebug()<<flag<<endl;
QByteArray array = QByteArray::fromHex("");//这里是一所的键入密令,这里不便给出
seriaport->write(array);
qDebug()<<QString::fromLocal8Bit("seriaport is open")<<ui->comboBox->currentText()<<endl;
CurrentType = OPEN;
}
}
3:找卡——>选卡——>读卡——>解析
这里要说一下,找卡,选卡,读卡代码都是差不多,只是写入seriaport里面的命令不一样而已,这里是上找卡的函数
void Widget::find_card()
{
if(seriaport->isOpen())
{
QByteArray array = QByteArray::fromHex("");//找卡的命令,按要求命令不便给出
char CHK_SUM = 0;
for(int i = 5;i<array.size();i++)//按要求进行按位异或
{
CHK_SUM ^= array.at(i);
}
array.append(CHK_SUM);
seriaport->write(array);
CurrentType = FIND;
}
}
后面就是获取的数据了
void Widget::hand_card()
{
SeriaPortData = seriaport->readAll();
sleep(5)//睡眠5秒是为了让获取的数据能读完
}
解析数据,是最为麻烦,也是最刺激的,因为老是有编码的原因,我们要将16进制的数据转换为中文或者数字,这里需要用到QChar,或者wchar_t,以及对应的QString::fromRawData(const QChar *unicode, int size)和QString::fromWCharArray(const wchar_t *string, int size = -1),还有要说一下因为第二个参数都是size,但是对于16进制的数来说,后面会有\0的,所以这里我们要用strlen()函数来求长度哦。
这里类比一个姓名
char ch[2048] = {0};
qDebug()<<"204"<<SeriaPortData<<endl;
qDebug()<<"207:"<<SeriaPortData.size()<<endl;
memcpy(ch,SeriaPortData,2048);
qDebug()<<"205"<<ch<<endl;
wchar_t name[30]={0};
memcpy(name,ch+14,30);
qDebug()<<"214"<<QString::fromWCharArray(name,strlen((const char*)name))<<endl;
最终的效果: