發表文章

目前顯示的是 5月, 2021的文章

新唐火神板開箱實作(五):CAN通訊測試

圖片
一、前言     本篇要用Python寫程式,從個人電腦連接的Kvaser Leaf Light v2透過CAN傳送資料至NuMaker-Volcano接收,並從serial port觀測資料。 二、CAN bus的結構     如下圖,如果我們要使用CAN介面,需要有CAN Controller以及CAN Transceiver。CAN Controller負責的是CAN的通訊協定, CAN Controller會依序傳輸或接收資料,並且內建CRC、ACK、中斷等邏輯電路,CPU只需要存取他的暫存器即可進行收發。這一步當然可以用軟體刻出時序,不過有獨立硬體會讓CPU輕鬆一點。現在我們在做新的專案通常會直接挑有內建CAN Controller的MCU,像是新唐的M0A23、NUC131、M482、M453都有內建。NUC131目前已經有AEC-Q101的版本了,M0A23未來應該也會有。      CAN Controller輸出的都還只是共模信號,必須透過CAN Transceiver轉換電氣特性為差動信號。新一點的CAN Transceiver除了轉換電氣特性以外,還會有超時保護、突波及ESD防護,其中超時保護是為了避免該節點的軟體或硬體出現問題,使TXD長時間保持在LOW的時候,CAN Transceiver會把輸出級的電晶體給釋放掉,避免該節點長時間保持在顯性信號占用並阻斷其他節點的通訊。     此外為了因應 很多新出的MCU工作電壓都是3.3V,再新一點的CAN Transceiver也會將bus端的5V (VCC)與CAN TX/RX端的電源(VIO)區隔開來。幾個推薦的系列: NXP TJA1051T、TI TCAN1042、Microchip MCP2551。TJA1051T和TCAN1042有分不同版本(速度、VIO、EN等等),記得要去讀一下datasheet,看一下尾數的涵義。MCP2551就很經典很便宜,不過他就沒有VIO。     現在帶VIO的1051、1042市場都缺料,交期都排到好幾個月。好在新唐的M0A23工作電壓可以到5V,做東西用MCP2551就可以了~ 三、行前準備 1. NuMaker-Volcano要焊上排針,以利我們用杜邦線連接到CAN Transceiver 2. 準備CAN Transceiver模組,兩年前還很好

新唐火神板開箱實作(四):Kvaser USB/CAN adapter於Linux環境下的使用筆記

圖片
    電腦要接上CAN bus勢必要一個介面卡了,這回我們選用Kvaser Leaf Light v2這張USB to CAN的介面卡,於Ubuntu 18.04作業系統中使用python3開發通訊。     這邊我們就會用到第一篇所提到的 Kvaser Python module和Kvaser Linux Drivers and SDK,在Kvaser的網站可以下載。 https://www.kvaser.com/download/      下載後分別會是這兩個壓縮檔,pycanlib.zip和linuxcan.tar.gz,我都先將這兩個壓縮檔解壓縮。點開pycanlib/docs/index.html,裡面有完整的安裝步驟和範例。其中Installation告訴我們pip install canlib-x.y.z-py2.py3-none-any.whl可以自動安裝python的函式庫,其中x, y, z是版本號碼,可以在pycablib目錄下確認一下完整檔名。      不過安裝檔有使用到f-string,要用python3才能正常執行。因此在這之前要安裝一下python3與pip3。 sudo apt install python3 sudo apt install python3-pip     安裝完畢後用pip3來安裝。沒意外應該是能直接安裝成功。 pip3 install canlib-1.17.748-py2.py3-none-any.whl     再來就是驅動程式的部分,可以開啟 linuxcan/README參考。     實際上做這幾步就可以了。 sudo apt install build-essential make sudo make install      最後建立一份文字檔取名為listdev.py,然後將這段程式複製進去。要注意tab的部分。 from canlib import canlib num_channels = canlib.getNumberOfChannels() print("Found %d channels" % num_channels) for ch in range(0, num_channels): chdata = canlib.ChannelData(ch)