DSCAnalysisTool/src/serialport/serialport.cpp

344 lines
9.1 KiB
C++
Raw Normal View History

2025-03-05 09:33:46 +00:00
#include "serialport.h"
#include <qdebug.h>
#include <qdatetime.h>
#include <iostream>
#include <cstring>
2025-03-11 09:31:15 +00:00
#include <QSerialPortInfo>
2025-03-05 09:33:46 +00:00
#include "protocol.h"
2025-03-11 09:31:15 +00:00
#include "defines.h"
2025-03-05 09:33:46 +00:00
using namespace std;
2025-03-11 09:31:15 +00:00
const u16 conVid = 1155; // 0x0483
const u16 conPid = 22336; //0x5740
2025-03-05 09:33:46 +00:00
SerialPort::SerialPort(QObject*parent)
:QObject(parent)
,_sp(nullptr)
{
2025-03-11 09:31:15 +00:00
// displayPortInfo();
openSp();
#if 0
2025-03-05 09:33:46 +00:00
// 1.初始化
_sp = new QSerialPort();
_sp->setPortName(conSPName);
if(_sp == nullptr){
qDebug()<<"sp is null.";
exit(0);
return;
}
// 3.设置
//设置波特率和读写方向
_sp->setBaudRate(QSerialPort::Baud115200,
QSerialPort::AllDirections);
_sp->setDataBits(QSerialPort::Data8); //数据位为8位
_sp->setFlowControl(QSerialPort::NoFlowControl);//无流控制
_sp->setParity(QSerialPort::NoParity); //无校验位
_sp->setStopBits(QSerialPort::OneStop); //一位停止位
//4.连接信号槽
connect(_sp,&QSerialPort::readyRead,
this,&SerialPort::slotReadData);
// 2.打开串口
if(false == _sp->open(QIODevice::ReadWrite)){
qDebug()<<"open failed."
<<_sp->error();
exit(0);
}
else{
qDebug()<<"open succ.";
// 设置 DTR 信号为就绪状态true 表示低电平)
_sp->setDataTerminalReady(true);
}
//写数据定时器
// startTimer(500);
#endif
#if 0
sendCmd(e_zero);
for(int i = 0; i < 9; i++){
sendCmd(e_back);
}
#endif
}
SerialPort *SerialPort::instance()
{
static SerialPort ins;
return &ins;
}
SerialPort::~SerialPort()
{
if(_sp->isOpen()){
_sp->clear();
_sp->close();
}
delete _sp;
_sp=nullptr;
}
void SerialPort::timerEvent(QTimerEvent *event)
{
}
void SerialPort::slotReadData()
{
2025-03-06 07:25:37 +00:00
QByteArray data = _sp->readAll();
2025-03-05 09:33:46 +00:00
// 将 QByteArray 转换为十六进制字符串
2025-03-11 09:31:15 +00:00
QString hexData = data.toHex(' '); // ' ' 作为分隔符,可选参数
qDebug() << "receive info (hex):" << hexData;
#if 0
2025-03-06 07:25:37 +00:00
CommonData *serialPortData =
reinterpret_cast<CommonData*>(const_cast<char*>(&data.data()[6]));
2025-03-05 09:33:46 +00:00
2025-03-06 07:25:37 +00:00
// 格式化输出 double 类型,保留三位小数
QString formattedSampleTemp = QString::number(serialPortData->sample_temp, 'f', 3);
qDebug() << "sample temp:" << formattedSampleTemp;
2025-03-05 09:33:46 +00:00
2025-03-06 07:25:37 +00:00
QString formattedColdTemp = QString::number(serialPortData->cold_temp, 'f', 3);
qDebug() << "cold temp:" << formattedColdTemp;
2025-03-05 09:33:46 +00:00
2025-03-06 07:25:37 +00:00
emit sigSendSerialPortData(*serialPortData);
2025-03-11 09:31:15 +00:00
#endif
2025-03-05 09:33:46 +00:00
}
2025-03-11 09:31:15 +00:00
void SerialPort::openSp()
2025-03-05 09:33:46 +00:00
{
2025-03-11 09:31:15 +00:00
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
2025-03-05 09:33:46 +00:00
{
2025-03-11 09:31:15 +00:00
u16 pid = info.productIdentifier();
u16 vid = info.vendorIdentifier();
2025-03-05 09:33:46 +00:00
2025-03-11 09:31:15 +00:00
if((pid == conPid) && (vid == conVid)){
2025-03-05 09:33:46 +00:00
_sp = new QSerialPort(info);
break;
}
2025-03-11 09:31:15 +00:00
}
#if 0
if(!_sp->isOpen()){
qDebug()<<"Com open failed.";
return;
}else{
qDebug()<<"Com open succ.";
}
2025-03-05 09:33:46 +00:00
#endif
2025-03-11 09:31:15 +00:00
//设置波特率和读写方向
_sp->setBaudRate(QSerialPort::Baud115200,
QSerialPort::AllDirections);
_sp->setDataBits(QSerialPort::Data8); //数据位为8位
_sp->setFlowControl(QSerialPort::NoFlowControl);//无流控制
_sp->setParity(QSerialPort::NoParity); //无校验位
_sp->setStopBits(QSerialPort::OneStop); //一位停止位
//4.连接信号槽
connect(_sp,&QSerialPort::readyRead,
this,&SerialPort::slotReadData);
// 2.打开串口
if(!_sp->open(QIODevice::ReadWrite)){
qDebug()<<"open failed."<<_sp->error();
exit(0);
}
else{
qDebug()<<"open succ.";
//设置 DTR 信号为就绪状态true 表示低电平)
_sp->setDataTerminalReady(true);
2025-03-05 09:33:46 +00:00
}
}
void SerialPort::sendCmd(const SerialPort::E_CMD_TYPE e)
{
#if 1
int length = 20;
char in_char[21] = {'\0'};
if(e == e_zero){
// char data[10] = {'55','aa','0b','0a','20',
// '4e','00','00','00','c3'};
2025-03-06 07:25:37 +00:00
const char *data = "55aa0b0a204e000000c3";
2025-03-05 09:33:46 +00:00
memcpy(in_char,data,length);
}else if(e == e_back){
// char data[10] = {'55','aa','08','10','27',
// 'f0','d8','ff','ff','c3'};
2025-03-06 07:25:37 +00:00
const char *data = "55aa081027f0d8ffffc3";
2025-03-05 09:33:46 +00:00
memcpy(in_char,data,length);
}else if(e == e_forward){
// char data[10] = {'55','aa','08','10','27',
// '10','27','00','00','c3'};
2025-03-06 07:25:37 +00:00
const char *data = "55aa08102710270000c3";
2025-03-05 09:33:46 +00:00
memcpy(in_char,data,length);
}
#endif
// char in_char[] = "55aa0b0a204e000000c3";
char out_char[21] = {'\0'};
int hex_length = 10;
to_hex(in_char, hex_length, out_char);
int num = _sp->write(out_char,
hex_length);
if(num == -1){
qDebug()<<"write failed.";
}else{
qDebug()<<"write ok|num:"<<num;
}
}
void SerialPort::to_hex(char* in_char, int char_length, char* out_char)
{
while (char_length--)
{
*out_char = (*in_char & 0x40 ? *in_char + 9 : *in_char) << 4;
++in_char;
*out_char |= (*in_char & 0x40 ? *in_char + 9 : *in_char) & 0xF;
++in_char;
++out_char;
}
}
2025-03-11 09:31:15 +00:00
void SerialPort::displayPortInfo()
{
// 获取系统中所有可用的串口信息
QList<QSerialPortInfo> serialPorts = QSerialPortInfo::availablePorts();
// 遍历每个串口信息
for (const QSerialPortInfo &portInfo : serialPorts) {
qDebug()<<"================================================";
// 打印串口的名称
qDebug() << "串口名称: " << portInfo.portName();
// 打印串口的描述信息
qDebug() << "描述信息: " << portInfo.description();
// 打印串口的制造商信息
qDebug() << "制造商: " << portInfo.manufacturer();
// 打印串口的序列号
qDebug() << "序列号: " << portInfo.serialNumber();
// 打印串口的系统位置
qDebug() << "系统位置: " << portInfo.systemLocation();
// 打印是否有虚拟调制解调器
qDebug() << "是否有虚拟调制解调器: " << (portInfo.hasVendorIdentifier() ? "" : "");
// 打印是否有产品标识符
qDebug() << "是否有产品标识符: " << (portInfo.hasProductIdentifier() ? "" : "");
// 如果有虚拟调制解调器,打印其标识符
if (portInfo.hasVendorIdentifier()) {
qint16 vid = portInfo.vendorIdentifier();
qDebug() << "虚拟调制解调器标识符: " << vid;
QString hexStr = QString("0x%1").arg(vid, 4, 16, QChar('0')).toUpper();
qDebug()<<"vid 0x"<< hexStr;
}
// 如果有产品标识符,打印其标识符
if (portInfo.hasProductIdentifier()) {
qint16 pid = portInfo.productIdentifier();
qDebug() << "产品标识符: " << pid;
QString hexStr = QString("0x%1").arg(pid, 4, 16, QChar('0')).toUpper();
qDebug()<<"pid 0x"<< hexStr;
}
}
}
2025-03-05 09:33:46 +00:00
void SerialPort::parserTest()
{
const uchar data[] = {0xa5,0x5a,0x2d,0x83,
0x00,0x00,
0x00,0x01,0x23,0x23,
0x23,0x23,0x23,0x23,0x23,
0x23,0x07,0xbc,0xb5,0xf2,0xc8,0x57,0x38,0x40,0x1b,0x63,0x27,0xbc,0x04,0xa7,0xf2,0x3f,0x55,0x55,0x55,0xd5,0x04,0xf3,0xab,0xbf,0xfa,0x2b,0xcd,0x41,0x00,0x00,0x93,0xba};
CommonData *serialPortData = nullptr;
qDebug()<<"data length:"<<sizeof(data)/sizeof(uchar);
// serialPortData = (CommonData)&data[4];
2025-03-06 07:25:37 +00:00
serialPortData = reinterpret_cast<CommonData*>(const_cast<uchar*>(&data[6]));
2025-03-05 09:33:46 +00:00
qDebug()<<"run type:"<<serialPortData->run_type;
// qDebug()<<"run time:"<<serialPortData->add_run_time;
// qDebug()<<"sample temp:"<<serialPortData->sample_temp;
// 格式化输出 float 类型,保留两位小数
QString formattedRunTime = QString::number(serialPortData->add_run_time, 'f', 2);
qDebug() << "run time:" << formattedRunTime;
// 格式化输出 double 类型,保留三位小数
QString formattedSampleTemp = QString::number(serialPortData->sample_temp, 'f', 3);
qDebug() << "sample temp:" << formattedSampleTemp;
2025-03-06 07:25:37 +00:00
QString formattedColdTemp = QString::number(serialPortData->cold_temp, 'f', 3);
qDebug() << "cold temp:" << formattedColdTemp;
2025-03-05 09:33:46 +00:00
2025-03-06 07:25:37 +00:00
#if 0
2025-03-05 09:33:46 +00:00
// 定义小端序的 4 字节数据
unsigned char bytesLittle[] = {0x23, 0x23, 0x01, 0x00};
// 调用函数进行转换
float result = 0.0f;
std::memcpy(&result, bytesLittle, sizeof(float));
// float floatValue = bytesToFloatLittleEndian(bytesLittle);
// 输出转换后的浮点数
2025-03-06 07:25:37 +00:00
std::cout << "result: " << result << std::endl;
#endif
2025-03-05 09:33:46 +00:00
}
2025-03-11 09:31:15 +00:00
void SerialPort::slotSendData(const QByteArray &ba)
{
qDebug()<<"slotSendData:"<<ba.size();
_sp->write(ba);
// 将 QByteArray 转换为十六进制字符串
QString hexData = ba.toHex(' '); // ' ' 作为分隔符,可选参数
qDebug() << "send info (hex):" << hexData;
}
2025-03-05 09:33:46 +00:00