翻譯|行業(yè)資訊|編輯:顏馨|2023-04-21 14:28:21.590|閱讀 241 次
概述:本文將為大家介紹最新的Qt 6.5版本引入的許多新功能,歡迎下載相關(guān)組件體驗~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
Qt 是目前最先進、最完整的跨平臺C++開發(fā)工具。它不僅完全實現(xiàn)了一次編寫,所有平臺無差別運行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運用于超過70個行業(yè)、數(shù)千家企業(yè),支持數(shù)百萬設(shè)備及應(yīng)用。
The Qt Company是Digia Plc旗下的全資子公司。負責(zé)所有Qt活動,包括產(chǎn)品開發(fā),商業(yè)和開源授權(quán)模式以及在開放管理模式下的Qt工程。其許可、支持和服務(wù)能力能夠和開發(fā)者緊密合作以確保他們的Qt項目準(zhǔn)時部署,不超預(yù)算并擁有競爭優(yōu)勢。
Qt CAN總線模塊始終提供API用于CAN總線的高級操作:
CAN總線幀由幀ID和有效負載組成。在現(xiàn)有的 API 中,F(xiàn)rameId 表示為無符號整數(shù),有效負載只是一個保存一些原始字節(jié)的 QByteArray。
實際上,更高級別的協(xié)議應(yīng)用于CAN總線幀之上。這克服了任意有效負載和 FrameId 的通用定義,該定義將其替換為可能發(fā)生的總線設(shè)備、消息和信號類型的唯一標(biāo)識符,并為信號中的值提供類型信息。
在Qt 6.5之前,用戶必須提供自己的實現(xiàn)來提取這些值。在Qt 6.5中,我們引入了一組API來簡化此過程。
新的 API 提供了一種描述頂級協(xié)議的方法。稍后,這些規(guī)則可用于解碼傳入的CAN幀,以及在將數(shù)據(jù)發(fā)送到設(shè)備之前將數(shù)據(jù)編碼為CAN幀。
讓我們仔細看看 API:
QCanFrameProcessor 類使用其他新類提供的描述。它提供了兩種主要方法來編碼和解碼幀:
讓我們開發(fā)一個小示例來演示運行中的新 API。
讓我們考慮一個具有以下格式的協(xié)議:
可以使用下圖可視化此格式。
讓我們看看如何用新的 API 來描述這個協(xié)議。
唯一標(biāo)識符
讓我們從唯一標(biāo)識符開始。
QCanUniqueIdDescription uid; uid.setSource(QtCanBus::DataSource::FrameId); uid.setEndian(QSysInfo::Endian::LittleEndian); uid.setStartBit(0); uid.setBitLength(11);
我們定義源(FrameId),字節(jié)序(Little-Endian),起始位和唯一標(biāo)識符的位長度。
源定義了CAN幀的一部分,該幀將用于提取值。它可以是幀 ID 或有效負載。
信號和消息描述
接下來,讓我們定義信號描述。
QCanSignalDescription s0; s0.setName(u"signal 0"_s); s0.setDataSource(QtCanBus::DataSource::Payload); s0.setDataEndian(QSysInfo::Endian::LittleEndian); s0.setDataFormat(QtCanBus::DataFormat::UnsignedInteger); s0.setStartBit(0); s0.setBitLength(16); QCanSignalDescription s1; s1.setName(u"signal 1"_s); s1.setDataSource(QtCanBus::DataSource::Payload); s1.setDataEndian(QSysInfo::Endian::LittleEndian); s1.setDataFormat(QtCanBus::DataFormat::SignedInteger); s1.setStartBit(16); s1.setBitLength(32);
對于這兩個信號,我們定義信號名稱、源(有效載荷)、字節(jié)序(小端)、數(shù)據(jù)類型、起始位和位長度。請注意,對于整個有效負載,位編號是連續(xù)的。位 0 表示字節(jié) 0 的第一個位,位 63 表示字節(jié) 7 的最后一位。信號名稱在消息描述中必須是唯一的。信號名稱用于在解析幀時提供有意義的結(jié)果,并標(biāo)識將值編碼到新生成的幀中的正確規(guī)則。允許您指定更多參數(shù)。有關(guān)完整列表,請參閱文檔。
指定信號描述后,我們可以定義消息描述。
QCanMessageDescription msg; msg.setName(u"example message"_s); msg.setSize(8); msg.setUniqueId(QtCanBus::UniqueId{0x123}); msg.setSignalDescriptions({s0, s1});
對于消息描述,我們指定有效負載大小、此消息中包含的信號描述列表以及唯一標(biāo)識符。唯一標(biāo)識符將用于在解碼傳入CAN幀時選擇正確的消息描述。與信號描述一樣,QCanMessageDescription 類允許您指定更多參數(shù),因此請務(wù)必查看文檔。
幀處理器
一旦我們?yōu)槲ㄒ粯?biāo)識符和消息創(chuàng)建了描述,我們就可以創(chuàng)建 QCanFrameProcessor 的實例。
QCanFrameProcessor processor; processor.setUniqueIdDescription(uid); processor.setMessageDescriptions({msg});
幀處理器使用先前生成的唯一 ID 描述和消息描述列表進行初始化。在我們的例子中,列表只包含一個元素。
處理 CAN 幀
本節(jié)介紹如何使用上述消息描述來解析傳入幀和對新幀進行編碼。
為簡單起見,讓我們手動創(chuàng)建一個CAN幀。
QCanBusFrame frame(0x123, QByteArray::fromHex("ABCD123456780000"));
實際上,這樣的幀將從QCanBusDevice接收。請注意,框架具有與之前創(chuàng)建的消息描述的唯一標(biāo)識符匹配的唯一標(biāo)識符。
要解析此幀,只需調(diào)用 parseFrame() 方法:
QCanFrameProcessor::ParseResult result = processor.parseFrame(frame); qDebug() << Qt::hex << Qt::showbase << Qt::uppercasedigits << "Unique ID:" << result.uniqueId << Qt::endl << "Values:" << result.signalValues;
此方法返回一個 ParseResult 結(jié)構(gòu),其中包含一個唯一標(biāo)識符和一個保存信號名稱和信號值的映射。qDebug() 調(diào)用的輸出如下所示。
Unique ID: 0x123 Values: QMap(("signal 0", QVariant(qulonglong, 0xCDAB))("signal 1", QVariant(qlonglong, 0x78563412)))
要生成幀,我們需要調(diào)用 prepareFrame() 方法,并將唯一標(biāo)識符以及信號名稱和信號值的映射作為參數(shù)傳遞。信號名稱必須與信號描述的名稱匹配。對于此示例,我們將重用 parseFrame() 方法返回的值。
QCanBusFrame generated = processor.prepareFrame(result.uniqueId, result.signalValues); qDebug() << Qt::hex << Qt::showbase << Qt::uppercasedigits << generated.frameId() << generated.payload().toHex().toUpper();
生成的幀應(yīng)與初始幀相似。這就是我們在 qDebug() 輸出中看到的。
上一節(jié)中的示例演示如何手動指定CAN報文描述。這種方法相當(dāng)冗長且容易出錯。
我們能做得更好嗎?
幸運的是,已經(jīng)有一些眾所周知的描述CAN總線參數(shù)的標(biāo)準(zhǔn)。其中一個標(biāo)準(zhǔn)是DBC。它是一種基于文本的格式,廣泛用于各個行業(yè)。
在Qt 6.5中,我們引入了QCanDbcFileParser類。此類分析輸入 DBC 文件,并自動生成消息說明。DBC 格式還包含對唯一標(biāo)識符的明確定義要求,因此該類還具有生成唯一標(biāo)識符描述的靜態(tài)方法。
此示例可以說明使用此類的典型模式。
QCanDbcFileParser dbcParser; if (dbcParser.parse("path/to/file.dbc")) { QCanFrameProcessor processor; processor.setUniqueIdDescription(QCanDbcFileParser::uniqueIdDescription()); processor.setMessageDescriptions(dbcParser.messageDescriptions()); // Do the actual processing } else { // Failed to extract data from DBC file qDebug() << "Got error:" << dbcParser.error(); qDebug() << "Error details:" << dbcParser.errorString(); }
如果DBC文件解析成功,我們可以使用生成的消息和唯一標(biāo)識符描述來創(chuàng)建幀處理器并開始處理。如果解析失敗,API 會提供一些方便的方法來處理錯誤。
歡迎下載|體驗更多Qt相關(guān)組件
獲取更多信息請咨詢 ;Qt技術(shù)交流群:166830288
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn