大地资源网视频在线观看新浪,日本春药精油按摩系列,成人av骚妻潮喷,国产xxxx搡xxxxx搡麻豆

您現在的位置:智能制造網>技術中心>Kvaser | 如何使用Excel發送和接收CAN報文數據

直播推薦

更多>

企業動態

更多>

推薦展會

更多>

Kvaser | 如何使用Excel發送和接收CAN報文數據

2025年06月16日 07:13:44人氣:1來源:廣州智維電子科技有限公司

從1980年代,Kvaser就開始CAN產品的研發,在相關產品開發領域有近40多年的經驗,對CAN和相關總線技術有著非常深入的研究。我們將分享一些有趣的發現和一些特定情況的技術處理,歡迎關注!


所有人的電腦上都有Microsoft Office,平時我們用它列表和計算,除此之外,它還可以被用來進行CAN總線數據收發的工作,進而輔助你進行其他工作。本文就分享如何巧用Excel進行該操作。

我們可以利用Windows電腦上的Microsoft Office Excel進行如下操作:


?從工作表中的任意單元格向CAN總線發送數據

?以工作表的任意單元格從CAN總線接收數據


Kvaser CANlib可用于Visual Basic for Applications (VBA)。此多功能庫支持Kvaser的所有適配器,并輔助你編寫高級和創新的解決方案。

有這么多其他語言可以用,為什么還要使用VBA呢?

首先,如果你平時使用Microsoft Office,那么使用它會更容易。Excel使用廣泛,通過VBA,你可應用Excel的所有功能,以及你自己的創意和創新想法。另外,使用Excel不會產生額外成本,也更方便與他人或其他公司分享數據。

本文我們會簡要介紹如何在Microsoft Excel中使用CANlib、VBA向CAN總線發送/接收數據。

應用此方法,你需要:


根據本文的步驟,你需要使用Kvaser CANlib和Excel VBA。任意版本的Microsoft Office都可以,但是Office 2010,因為VBA 7是在2010年推出的。64位和32位Office均可使用。本文中,使用的是Office 365和Excel(版本2202 Build 16.0.14931.20116)64位。


你還需要安裝“用于Windows的Kvaser驅動程序”。請聯系廣州智維版本CANlib并依照其步驟進行安裝。如果你需要進一步使用CANlib,我們建議下載Kvaser CANlib SDK。


VBA介紹



VBA(Visual Basic for Applications)是Visual Basic的一種宏語言,是在其桌面應用程序中執行通用的自動化(OLE)任務的編程語言。主要能用來擴展Windows的應用程序功能,特別是Microsoft Office軟件。它也可以說是一種應用程式視覺化的 Basic 腳本。


VBA是Microsoft編程語言Visual Basic 6的一個子集,它使用同一編輯器的精簡版本以及類似的調試功能。因此,如果你了解VB6,也就能了解VBA的使用方法。Visual Basic是為了簡化編程而創建的,VBA編程的過程不難,使用它就類似于用英語的語句來告訴電腦該做什么。


Application.ActiveDocument.SaveAs ("New Document Name.docx")

將活動文檔另存為 “New Document Name.docx”


需要注意的是,VBA是單線程的,這意味著它將一次執行一個任務。(請參閱下文“VBA示例”中的“多任務處理”內容)


默認情況下,Office不顯示開發工具”選項卡,你必須通過如下步驟啟用它:


1??從“File文件”選項卡中,選擇“Options選項”打開對話框。

2??選擇對話框左側的“Customize Ribbon自定義功能區”。

3??在對話框左側的“Choose Commands From從中選擇命令”中,選擇“Common Commands常用命令”。

4??在右側的“Customize the ribbon自定義功能區”中,從下拉列表中選擇“Main Tab主選項卡”,然后選擇“Developer開發工具”復選框。

5??選擇OK。


從“開發工具”選項卡,你可以打開編輯器并創建按鈕、下拉菜單等。或者,你可以在Office應用程序中使用快捷鍵:ALT+F11


如果你還是不了解如何操作,可以在網上進行VBA示例搜索,即使需求不相同,你也能從中參考到類似的步驟。


VBA實例



個示例將顯示當某個單元出現更改時如何作出反應,并將該值發送到CAN總線。

在VBA編輯器中,雙擊你需要對其作出反應的單元格所在的工作表,然后選擇該工作表的“更改(Change)”步驟。


圖片


每當該工作表中發生更改時,都會執行工作表更改事件,將其縮小到特定的一個單元格,我使用VBA中的Intersect()函數。此函數確定更改的單元格是否與我們指定的單元格“匹配”。為了簡化此示例,我假設工作表處于活動狀態,并且我們要發送的值介于0-255之間。有關canWrite中使用的參數,以及如何從CAN總線接收數據的更多信息,請見下一個示例。

另一個示例中,我已將一個記錄文件導入Excel(在此示例中,它是一個.ASC文件)。我這樣做只是為了向CAN總線發送數據。


圖片


當然,你的數據可以是來自任何地方的,在VBA中打開一個文件,也可以在Excel中編寫幾個具體應發送的幀等。


在這里,不會深入探討CANlib,這個示例主要是啟發你可以如何利用VBA和CANlib。在本文,我將演示如何使用Kvaser CANlib從Excel中的任意單元格發送數據,以及如何以Excel中的任意單元格接收數據。

編碼


CANlib API - 和句柄聲明

Option Explicit 'Force explicit variable declaration so that an undeclared variable generates error.



#If VBA7 Then

Private Declare PtrSafe Sub canInitializeLibrary Lib "CANLIB32.DLL" ()

Private Declare PtrSafe Function canUnloadLibrary Lib "CANLIB32.DLL" () As Long

Private Declare PtrSafe Function canGetNumberOfChannels Lib "CANLIB32.DLL" (ByRef channelCount As Long) As Long

Private Declare PtrSafe Function canGetChannelData Lib "CANLIB32.DLL" (ByVal channel As Long, ByVal item As Long, ByRef buffer As Any, ByVal bufsize As Long) As Long

Private Declare PtrSafe Function canOpenChannel Lib "CANLIB32.DLL" (ByVal handle As Long, ByVal Flags As Long) As LongPtr

Private Declare PtrSafe Function canClose Lib "CANLIB32.DLL" (ByVal handle As LongPtr) As Long

Private Declare PtrSafe Function canBusOn Lib "CANLIB32.DLL" (ByVal handle As LongPtr) As Long

Private Declare PtrSafe Function canBusOff Lib "CANLIB32.DLL" (ByVal handle As LongPtr) As Long

Private Declare PtrSafe Function canSetBusParams Lib "CANLIB32.DLL" (ByVal handle As LongPtr, ByVal freq As Long, ByVal tseg1 As Long, ByVal tseg2 As Long, ByVal sjw As Long, ByVal noSamp As Long, ByVal syncMode As Long) As Long

Private Declare PtrSafe Function canWrite Lib "CANLIB32.DLL" (ByVal handle As LongPtr, ByVal id As Long, ByRef msg As Any, ByVal dlc As Long, ByVal flag As Long) As Long

Private Declare PtrSafe Function canReadWait Lib "CANLIB32.DLL" (ByVal handle As LongPtr, ByRef id As Long, ByRef msg As Any, ByRef dlc As Long, ByRef flag As Long, ByRef time As Long, ByRef timeout As Long) As Long

#Else

Private Declare Sub canInitializeLibrary Lib "CANLIB32.DLL" ()

Private Declare Function canUnloadLibrary Lib "CANLIB32.DLL" () As Long

Private Declare Function canGetNumberOfChannels Lib "CANLIB32.DLL" (ByRef channelCount As Long) As Long

Private Declare Function canGetChannelData Lib "CANLIB32.DLL" (ByVal channel As Long, ByVal item As Long, ByRef buffer As Any, ByVal bufsize As Long) As Long

Private Declare Function canOpenChannel Lib "CANLIB32.DLL" (ByVal handle As Long, ByVal Flags As Long) As Long

Private Declare Function canClose Lib "CANLIB32.DLL" (ByVal handle As Long) As Long

Private Declare Function canBusOn Lib "CANLIB32.DLL" (ByVal handle As Long) As Long

Private Declare Function canBusOff Lib "CANLIB32.DLL" (ByVal handle As Long) As Long

Private Declare Function canSetBusParams Lib "CANLIB32.DLL" (ByVal handle As Long, ByVal freq As Long, ByVal tseg1 As Long, ByVal tseg2 As Long, ByVal sjw As Long, ByVal noSamp As Long, ByVal syncMode As Long) As Long

Private Declare Function canWrite Lib "CANLIB32.DLL" (ByVal handle As Long, ByVal id As Long, ByRef msg As Any, ByVal dlc As Long, ByVal flag As Long) As Long

Private Declare Function canReadWait Lib "CANLIB32.DLL" (ByVal handle As Long, ByRef id As Long, ByRef msg As Any, ByRef dlc As Long, ByRef flag As Long, ByRef time As Long, ByRef timeout As Long) As Long

#End If


'Constant declarations

Private Const canOK = 0

Private Const canOPEN_ACCEPT_VIRTUAL = &H20

Private Const canBITRATE_250K = -3

Private Const canCHANNELDATA_CARD_SERIAL_NO = 7



'Declaration of CAN handles

#If VBA7 Then

Private hnd0, hnd1 As LongPtr

#Else

Private hnd0, hnd1 As Long

#End If


這些聲明是必要的,以便指定哪些dll調用可用,并指出此dll的位置。通過Kvaser的安裝程序安裝時,CANlib32.dll位于系統路徑中。這就是說你不必指定它的具體位置。

[ Public | Private ] Declare Sub name Lib “libname” [ ( [ arglist ] ) ]

[ Public | Private ] Declare Function name Lib “libname” [ ( [ arglist ] ) ] [ As type ]

使用Private表明,只有在聲明它的模塊中才能訪問它。

Kvaser CANlib SDK目前不包含任何VB或VBA聲明,因此你必須根據需要編寫這些聲明。


有任何問題,你可以聯系我們的技術支持人員,本文結尾處提供了。

調用 CANlib API


初始化CANlib并獲取可用通道數

Sub CANLib_Start()

Dim chCount, stat, i As Long

Dim buffer As String

Dim myArr(32) As Byte

Dim ws As Worksheet


canInitializeLibrary

stat = canGetNumberOfChannels(chCount)

If stat <> canOK Then GoTo ErrorHandler


在使用任何其他函數之前,必須先調用canInitializeLibrary函數。它將初始化驅動程序。

canGetNumberOfChannels, 此函數將返回電腦中可用CAN通道的數量。虛擬通道包括在此通道數中。


準備工作表以讀取一些設備信息

Sheets.Add(Before:=Sheets(1)).name = "Device info" ' Add a sheet called "Device info" to the first position


Range("A1").Value = "Nof channels"

Range("B1").Value = chCount


在這里,我們給個位置添加一個新的工作表,并在該工作表的單元格B1中寫入可用通道數。


讀取每個可用通道的一些設備信息

For i = 0 To chCount - 1

stat = canGetChannelData(i, canCHANNELDATA_CARD_SERIAL_NO, myArr(0), 32)

buffer = StrConv(myArr(), vbUnicode)

If buffer <> Empty Then

Cells(i + 2, 1).Value = "Serial"

Cells(i + 2, 2).Value = buffer

End If

Next i


在這里,我們查看每個可用的通道,并詢問設備的序列號,并且我們將其寫入每個通道的第二列中的新行(即B)。


打開通道,設置參數并啟動總線

hnd0 = canOpenChannel(0, canOPEN_ACCEPT_VIRTUAL)

hnd1 = canOpenChannel(1, canOPEN_ACCEPT_VIRTUAL)

stat = canSetBusParams(hnd0, canBITRATE_250K, 0, 0, 0, 0, 0)

If stat <> canOK Then GoTo ErrorHandler

stat = canSetBusParams(hnd1, canBITRATE_250K, 0, 0, 0, 0, 0)

If stat <> canOK Then GoTo ErrorHandler


stat = canBusOn(hnd0)

If stat <> canOK Then GoTo ErrorHandler

stat = canBusOn(hnd1)

If stat <> canOK Then GoTo ErrorHandler


在這里,我們打開個和第二個通道,以獲得所有其他調用所需的句柄。我們繼續準備這兩個打開的通道,為它們設置相同的比特率。


為讀取數據準備工作表

DeleteSheet ("Read data")

Set ws = Sheets.Add()

ws.name = "Read data"

ws.Cells(1, 1).Value = "ID"

ws.Cells(1, 2).Value = "Data1"

ws.Cells(1, 3).Value = "Data2"

ws.Cells(1, 4).Value = "Data3"

ws.Cells(1, 5).Value = "Data4"

ws.Cells(1, 6).Value = "Data5"

ws.Cells(1, 7).Value = "Data6"

ws.Cells(1, 8).Value = "Data7"

ws.Cells(1, 9).Value = "Data8"

這里我們準備一個工作表來存儲讀取的數據。我首先刪除“讀取數據(Read data)”表,如果它已經存在。然后我創建此工作表并命名,同時添加一些標題注釋,以便更好地理解輸出內容。


發送、接收和填充單元格

Sub CANlib_Traffic()

Dim tb As ListObject

Dim iCol, iRow As Integer

Dim sData(1 To 8), sCol As String

Dim bDataTx(1 To 8) As Byte

Dim bDataRx(1 To 8) As Byte

Dim stat, lID, lDlc, lFlags, lTime As Long



Worksheets("Imported ASC").Activate

Set tb = ActiveSheet.ListObjects("TestLog")


For iRow = 1 To tb.Range.Rows.Count

lDlc = tb.DataBodyRange.Cells(iRow, tb.ListColumns("DLC").Index) ' Get how many data bytes

For iCol = 1 To lDlc

sCol = "Data" + Trim(Str(iCol)) 'Create the headline to read from

sData(iCol) = tb.DataBodyRange.Cells(iRow, tb.ListColumns(sCol).Index)

bDataTx(iCol) = CByte("&H" & sData(iCol)) ' Convert the Hex value to decimal

Next iCol

' Send the byte stream of CAN data on the first channel

stat = canWrite(hnd0, CLng(iRow), bDataTx(1), lDlc, 0)

DoEvents

' Read out the received data on the second channel

stat = canReadWait(hnd1, lID, bDataRx(1), lDlc, lFlags, lTime, 50)

If stat = canOK Then

With Worksheets("Read data") ' Populate cells in Excel with read CAN data

.Cells(lID + 1, 1).Value = lID

' .Cells(lID + 1, 2).Value = CStr(Hex(bDataRx(1))) ' Use this if value should be in hexadecimal

.Cells(lID + 1, 2).Value = bDataRx(1)

.Cells(lID + 1, 3).Value = bDataRx(2)

.Cells(lID + 1, 4).Value = bDataRx(3)

.Cells(lID + 1, 5).Value = bDataRx(4)

.Cells(lID + 1, 6).Value = bDataRx(5)

.Cells(lID + 1, 7).Value = bDataRx(6)

.Cells(lID + 1, 8).Value = bDataRx(7)

.Cells(lID + 1, 9).Value = bDataRx(8)

End With

End If

Next iRow


MsgBox "Traffic done!"

End Sub


首先確定要讀取的工作表已激活。在我的示例中,我將導入數據的工作表命名為TestLog,并將其設置為ListObject變量。我這樣做是為了在獲取要發送的值時更容易循環操作,這樣我可以使用工作表的標題來指定我正在讀取的列。個循環設置為讀取導入數據的整個范圍。我讀取數據長度代碼(dlc)值,以了解還要讀取和稍后發送的字節數。第二個循環迭代數據字節,將它們從文本格式的十六進制轉換為十進制值,并將值存儲在字節數組中。


然后,通過調用CANlib函數canWrite,將CAN數據的字節數組與報文id(在本例中為行號)和數據長度代碼(dlc)一起發送。


DoEvents可以更輕松地停止正在運行的宏。DoEvents函數允許中斷執行代碼,并允許計算機處理器同時運行其他任務。使用DoEvents會延長執行時間,但另一方面,它也會讓宏停止運行。


canReadWait從接收緩沖區讀取報文。如果沒有可用的報文,則該函數將等待報文到達或超時。


最后,用該讀取值填充之前創建的“讀取數據”工作表并使用報文id指定單元格行。通過在寫入單元格時使用命名工作表,我不必激活該工作表(Worksheets(“Read data”). Cells (Row, Column).Value),同時能保持保存導入數據的工作表處于活動狀態。


操作后清理

Sub CANLib_Stop()

canBusOff (hnd0)

canBusOff (hnd1)

canUnloadLibrary

MsgBox "CANlib is unloaded!"

End Sub


canBusOff把指定句柄關閉。如果同一通道上沒有其他句柄處于活動狀態,則也將把此通道關閉。canUnloadLibrary將釋放分配的內存,卸載已加載的DLL canlib32.,并取消初始化數據結構。

結果



本示例的結果如下圖所示:


圖片


如果選擇將輸出數據格式化為十六進制,這樣更便于比較,然后將單元格格式化為文本: ws.Columns(“A:I”).NumberFormat = “@”,當將值放入這些單元格時,需要進行如下轉換:Cells(col, row).Value = CStr(Hex(MyDecValue))。


但在本次操作中,為了讓后續分析更方便,我選擇了十進制。(也可以使用十六進制值,但有時需要進行轉換,因為VBA和Excel中的圖表對象需要其值為十進制格式。)


可使用Excel圖表可視化數據,例如:


圖片


圖表可以在VBA代碼中生成,也可以在以后使用Excel的工具欄生成。

32位與64位Microsoft Office



兩個Office版本都可用,但VBA版本7中添加了一些新的64位功能。


圖片


VBA中除數據類型Byte外,沒有無符號數據類型。但這并不是不可行 – 可以在VBA中讀取無符號值,例如本例介紹了如何對2147483647以上的值使用雙精度類型。


Private Const MAX_UINT32 = 4294967296#

Private Const MAX_INT32 = 2147483647

Function LongToUnsigned(ByVal Value As Long) As Double

If Value < 0 Then

LongToUnsigned = Value + MAX_UINT32

Else

LongToUnsigned = Value

End If

End Function

Function UnsignedToLong(ByVal Value As Double) As Long

If Value < 0 Or Value >= MAX_UINT32 Then Error 6

If Value <= MAX_INT32 Then

UnsignedToLong = Value

Else

UnsignedToLong = Value - MAX_UINT32

End If

End Function

多任務處理



VBA是單線程的,這意味著它將一次執行一個任務。仍然可以創建一個線程或使用回調函數,如CANlib中的kvSetNotifyCallback,但我不建議這樣做。如果關閉一個線程并在主線程中等待,則創建一個線程是可以的,但創建更多線程或嘗試寫入主線程外的單元格,可能會導致Excel凍結并關閉。為了避免麻煩和花費額外時間,建議保持它的簡單性和主線程。


對于那些有使用VBA經驗的用戶,有一些方法可以解決這個問題,例如從代碼中的循環中啟動一個新的Excel實例,并從該新實例調用主工作簿中的一個過程。


我的建議是保持在主線程里。

結論



在本文中,我們簡要介紹了如何在Microsoft Excel中使用CANlib和VBA向CAN總線發送和從CAN總線接收數據。希望此示例可讓你了解如何操作可行,并輔助你進一步分析數據或編寫解決方案。

關鍵詞:CAN開發工具RTU
全年征稿/資訊合作 聯系郵箱:1271141964@qq.com

免責聲明

  • 凡本網注明"來源:智能制造網"的所有作品,版權均屬于智能制造網,轉載請必須注明智能制造網,http://m.xashilian.com。違反者本網將追究相關法律責任。
  • 企業發布的公司新聞、技術文章、資料下載等內容,如涉及侵權、違規遭投訴的,一律由發布企業自行承擔責任,本網有權刪除內容并追溯責任。
  • 本網轉載并注明自其它來源的作品,目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網站或個人從本網轉載時,必須保留本網注明的作品來源,并自負版權等法律責任。
  • 如涉及作品內容、版權等問題,請在作品發表之日起一周內與本網聯系,否則視為放棄相關權利。

<
更多 >

工控網機器人儀器儀表物聯網3D打印工業軟件金屬加工機械包裝機械印刷機械農業機械食品加工設備制藥設備倉儲物流環保設備造紙機械工程機械紡織機械化工設備電子加工設備水泥設備海洋水利裝備礦冶設備新能源設備服裝機械印染機械制鞋機械玻璃機械陶瓷設備橡塑設備船舶設備電子元器件電氣設備


我要投稿
  • 投稿請發送郵件至:(郵件標題請備注“投稿”)1271141964.qq.com
  • 聯系電話0571-89719789
工業4.0時代智能制造領域“互聯網+”服務平臺
智能制造網APP

功能豐富 實時交流

智能制造網小程序

訂閱獲取更多服務

微信公眾號

關注我們

抖音

智能制造網

抖音號:gkzhan

打開抖音 搜索頁掃一掃

視頻號

智能制造網

公眾號:智能制造網

打開微信掃碼關注視頻號

快手

智能制造網

快手ID:gkzhan2006

打開快手 掃一掃關注
意見反饋
關閉
企業未開通此功能
詳詢客服 : 0571-87858618
主站蜘蛛池模板: 富民县| 鸡东县| 佛学| 红安县| 黄浦区| 德庆县| 天台县| 和平区| 老河口市| 五寨县| 华安县| 南雄市| 临潭县| 桦川县| 山东省| 桃园县| 佛坪县| 宜兰市| 会泽县| 青铜峡市| 镇宁| 利辛县| 浦东新区| 永顺县| 新兴县| 远安县| 沂南县| 海盐县| 图们市| 永嘉县| 柘城县| 高安市| 富阳市| 九台市| 高碑店市| 余姚市| 堆龙德庆县| 尉氏县| 安达市| 伊宁县| 当阳市|