qt实现socketCAN
一.初始化Init函数
1.点击 连接CAN 按键(默认为连接CAN,点击一次变为断开CAN)--->进入connectDevice函数
1.1按键为连接CAN:根据当前选择的可用接口,比特率初始化CAN
QString cmd1=tr("ifconfig %1 down").arg(ui->comboBox_2->currentText());
QString cmd2=tr("ip link set up %1 type can bitrate %2 restart-ms 100").arg(ui->comboBox_2->currentText()).arg(ui->comboBox_3->currentText());
system(cmd1.toStdString().c_str());
system(cmd2.toStdString().c_str());
1.2以设置的插件名与接口实例化canDevice
QCanBusDevice作用:1.连接断开CAN总线设备
connectDevice()
: 尝试连接到CAN总线设备
disconnectDevice()
: 断开与CAN总线设备的连接。
2.读取发送帧
readFrames(int maxNumberOfFrames)
: 从CAN总线读取数据帧
writeFrames(const QList<QCanBusFrame> &frames)
: 向CAN总线写入数据帧。
3.错误处理
errorOccurred(QCanBusDevice::Error error)
: 当CAN总线设备发生错误时发出信号。 errorString() const
: 返回描述错误的字符串。
canDevice = QCanBus::instance()->createDevice(ui->comboBox->currentText(),ui->comboBox_2->currentText(),&errorString);
canDevice创建成功:连接CAN canDevice->connectDevice()连接成功之后进行按键使能与失能。进行接收消息帧,错误处理
接收消息帧
connect(canDevice,&QCanBusDevice::framesReceived,[=](){
this->receivedFrames();
});
错误处理 connect(canDevice,&QCanBusDevice::errorOccurred,this,&MainWindow::canDeviceErrors);
void MainWindow::receivedFrames()
{
if(!canDevice)
return;
//读取帧
while(canDevice->framesAvailable())
{
QString view;
const QCanBusFrame frame = canDevice->readFrame();
//检查读取的帧是否是错误帧frame.frameType()返回帧的类型
if(frame.frameType()==QCanBusFrame::ErrorFrame)
{
view=canDevice->interpretErrorFrame(frame);
}
else
{
view=frame.toString();
}
//设置时间戳
const QString time=QString::fromLatin1("%1.%2 ").arg(frame.timeStamp().seconds(),10,10,QLatin1Char(' ')).arg(frame.timeStamp().microSeconds()/100,4,10,QLatin1Char('0'));
const QString flags=frameFlags(frame);
//追加显示接收到的消息
ui->textBrowser->insertPlainText(time+flags+view+"\n");
}
}
static QString frameFlags(const QCanBusFrame &frame)
{
QString res=QString(" --- ");
if(frame.hasBitrateSwitch())
res[1]=QLatin1Char('B');
if(frame.hasErrorStateIndicator())
res[2]=QLatin1Char('E');
if(frame.hasLocalEcho())
res[3]=QLatin1Char('L');
return res;
}
//错误处理
void MainWindow::canDeviceErrors(QCanBusDevice::CanBusError error) const
{
switch (error)
{
case QCanBusDevice::ReadError:
case QCanBusDevice::WriteError:
case QCanBusDevice::ConnectionError:
case QCanBusDevice::ConfigurationError:
case QCanBusDevice::UnknownError:
ui->label_4->setText(canDevice->errorString());
break;
default:
break;
}
}
发送信息:
void MainWindow::sendMsg()
{
if(!canDevice)
return;
QString str=ui->lineEdit->text();
/* 以空格分隔lineEdit的内容,并存储到字符串链表中 */
QStringList strList=str.split(' ');
QString strTmp=nullptr;
for(int i=1;i<strList.count();++i)
{
strTmp+=strList[i];
}
//将strTmp中的信息转为QByteArray进行发送
//strTemp.toLatin1():这个调用将QString转换为QByteArray
QByteArray data0 = strTmp.toLatin1();
//fromHex() 函数将16进制转换成二进制数据
QByteArray data = QByteArray::fromHex(data);
//以16进制读取要发送的帧内容里第一个数据,并作为帧ID
bool ok;
int framId = strList[0].toInt(&ok,16);
QCanBusFrame fram = QCanBusFrame(framId,data);
//发送帧
canDevice->writeFrame(fram);
}