Pico擁有一組PIO協處理器。它們是實時控制器,能夠以確定的時序執行邏輯。非常適合運行嚴格定時的序列和狀態機,以及實現額外的外設(如這里的CAN)。序列和狀態機,以及實現額外的外設(如這里的CAN)。
PIO引擎不易編程,也不易學習。但有一些很好的示例可供參考。我正在復習Kevin O'Connor精彩的can2040庫。
在這篇文章中:我將創建一個測試平臺,并證明我可以接收CAN通信。
這篇博客的目的不是編寫PIO(可編程輸入輸出)開發者教程。我試圖回溯開發者如何使用PIO指令實現一個標準協議。我使用的工具包括C語言、CMake、VSCode和Pico C SDK。預期的技能水平是:你能夠構建和運行官方的pico-examples。
在通常情況下(這里跳過OSI模型),CAN(控制器局域網)有兩層:
邏輯層:TTL、5V、3.3V等數字信號,由一些智能元件實現,如外設、控制器位操作,本例中為PIO狀態機。
總線層:物理層,通常通過驅動器/收發器IC實現。我將在這里使用一個物理驅動器IC,這是我自己設計的一個小東西,我經常使用。你也可以僅使用普通電阻和二極管制作一個簡易的CAN驅動器。
作為通信對等體,我使用另外兩個具備CAN能力的設備:一個帶有CAN外設的衍生設備和一個Microchip CAN總線分析儀。一個帶有CAN屏蔽板的Arduino(MKR)同樣適用。
這篇文章不深入代碼。它只是一個測試平臺,讓我看看是否能建立一個CAN通信。
獲取can2040庫
從Kevin的Kevin's github克隆或下載源代碼。
設置一個環境變量指向這個位置。這將確保我們可以創建一個不依賴于你存放第三方代碼位置的make腳本。我使用的是VSCode,并將在那里定義環境變量。你也可以在你的操作系統設置、shell腳本等中設置。
項目文件夾
我創建了一個包含CMake文件和src文件夾的目錄,src文件夾包含了一個非常簡單的測試文件(從這里獲取的,但我在項目中引用了can2040源代碼而不是導入它們)。
src/main.c
// source: https://gitea.predevolution-technologies.de/anme/CAN2040_Test
#include #include #include "pico/stdlib.h"#include "pico/binary_info.h"#include "hardware/irq.h"#include "can2040.h"#include "RP2040.h"
static struct can2040 cbus;
static void can2040_cb(struct can2040 *cd, uint32_t notify, struct can2040_msg *msg){ // Add message processing code here...}
static void PIOx_IRQHandler(void){ can2040_pio_irq_handler(&cbus);}
void canbus_setup(void){ uint32_t pio_num = 0; uint32_t sys_clock = 125000000, bitrate = 125000; uint32_t gpio_rx = 14, gpio_tx = 15;
// Setup canbus can2040_setup(&cbus, pio_num); can2040_callback_config(&cbus, can2040_cb);
// Enable irqs irq_set_exclusive_handler(PIO0_IRQ_0_IRQn, PIOx_IRQHandler); NVIC_SetPriority(PIO0_IRQ_0_IRQn, 1); NVIC_EnableIRQ(PIO0_IRQ_0_IRQn);
// Start canbus can2040_start(&cbus, sys_clock, bitrate, gpio_rx, gpio_tx);}
int main(void){
const uint LED_PIN = PICO_DEFAULT_LED_PIN; gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); int32_t ledState = 0; stdio_init_all(); canbus_setup();
while(1){ printf("bla\n"); gpio_put(LED_PIN, ledState); if (ledState == 0){ ledState = 1; } else{ ledState = 0; } sleep_ms(1000); }}
./CMakeList.txt
cmake_minimum_required(VERSION 3.13)
# Pull in SDK (must be before project)include(pico_sdk_import.cmake)
project(can2040_project0 C CXX ASM)set(CMAKE_C_STANDARD 11)set(CMAKE_CXX_STANDARD 17)
#I've set this to allow breakpoints on any source lineset(PICO_DEOPTIMIZED_DEBUG=1)
pico_sdk_init()
add_executable(can2040_project0 source/main.c $ENV{CAN2040_LIB_PATH}/src/can2040.c )
target_include_directories(can2040_project0 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/source $ENV{CAN2040_LIB_PATH}/src )
target_link_libraries(can2040_project0 pico_stdlib cmsis_core)
pico_add_extra_outputs(can2040_project0)
側邊欄:Pico PIO和其他預測性、時間關鍵型協處理器
Pico PIO狀態機是小型協控制器,它們以可預測的速度執行每條指令。這類控制器從不會被中斷,不會監聽中斷(但可以觸發中斷)。它們只是可靠地時鐘同步并執行它們的小程序。通常,它們可以快速訪問一些GIO引腳。
還有其他一些控制器和處理器具有類似的功能:TI(德州儀器)的Hercules微控制器具有高端定時器。它與Pico PIO引擎非常相似,但Hercules指令額外支持角度、相位等(這些是用于多相電源和電機驅動的功能)。(同樣來自TI的)BeagleBone具有PRU(可編程實時單元),這也與Pico PIO引擎的功能非常接近。PRU可以直接訪問內存和DMA引擎。這三者共同的特點是,它們不僅能夠產生精確定時的信號,還能夠采樣輸入信號。并且它們是超靈活的定時器,可以處理計數、相位移動、正交編碼等功能。
測試
我啟動了一個調試會話,在can2040_cb()回調函數處設置了斷點。然后,從我的另一臺設備發送了一條CAN消息:
RP2040在斷點處停止,我可以看到消息ID、DLC(長度)和有效載荷:
我附上了我的VSCode項目的ZIP文件。別忘了下載can2040源代碼并設置環境變量。
-
CAN
+關注
關注
57文章
2901瀏覽量
467055 -
Pico
+關注
關注
0文章
181瀏覽量
17577 -
樹莓派
+關注
關注
121文章
1966瀏覽量
107117
發布評論請先 登錄
樹莓派Pico的相關資料分享
使用樹莓派Pico開發板的一些思考與應用實踐資料分享
樹莓派Pico的相關資料推薦
樹莓派也出MCU了?樹莓派Pico來了!

樹莓派Pico開發板硬件擴展接口及電源模塊解析

樹莓派Pico:僅4美元的MCU

評論