精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

樹莓派Pico如何使用PIO程序呢?

jf_zGNBEhbi ? 來源:趣無盡 ? 2023-11-14 15:06 ? 次閱讀

在這篇教程中,我們看到的代碼看起來與其他的部分的代碼非常不同。那是因為我們大多數時候不得不在 MCU 的底層處理事情。大多數時候,MicroPython 可以隱藏很多在微控制器上工作的復雜性。
當我們 print(“hello”) 的時候,我們不必擔心微控制器存儲字母的方式,或它們被發送到串行終端的格式,或串行終端所接受的時鐘周期的數量。這些都是在后臺處理的。然而,當我們進入可編程輸入和輸出時(PIO),我們需要在更低的層次上處理這些邏輯。

我們將簡要介紹 PIO,并介紹一些高級主題,以便你了解正在發生的事情,并希望了解 Pico 上的 PIO 相對于其他微控制器是如何突顯優勢的。但是,理解創建 PIO 程序所需的所有低級數據操作需要花時間來完全理解,所以如果它看起來有點不透明也不用擔心。如果你對處理這種低級編程感興趣,那么我們將幫助你入門。如果你更感興趣的是在更高的層次上工作,而寧愿把低層次的爭論留給其他人,我們將向你展示如何使用 PIO 程序。

數據輸入和數據輸出

樹莓派 Pico 不僅支持 SPI 和 I2C 控制器發送數據。它還有自己的特殊協議:可編程 IO。讓我們看一個例子:

from rp2 import PIO, StateMachine, asm_pio
from machine import Pin
import time


@asm_pio(set_init=PIO.OUT_LOW)
def led_quarter_brightness():
  set(pins, 0)[2]
  set(pins, 1)


@asm_pio(set_init=PIO.OUT_LOW)
def led_half_brightness():
  set(pins, 0)
  set(pins, 1)


@asm_pio(set_init=PIO.OUT_HIGH)
def led_full_brightness():
  set(pins, 1)


sm1 = StateMachine(1, led_quarter_brightness, freq=10000, set_base=Pin(25))
sm2 = StateMachine(2, led_half_brightness, freq=10000, set_base=Pin(25))
sm3 = StateMachine(3, led_full_brightness, freq=10000, set_base=Pin(25))


while(True):
  sm1.active(1)
  time.sleep(1)
  sm1.active(0)
  sm2.active(1)
  time.sleep(1)
  sm2.active(0)
  sm3.active(1)
  time.sleep(1)
  sm3.active(0)

這些方法實際上是運行在 PIO 狀態機上的小程序,且在不斷循環。例如,led_half_brightness() 會不斷地打開和關閉 LED,這樣 LED 就會有一半的時間是關閉的,一半的時間是打開的。led_full_brightness() 將類似地循環,但由于惟一的指令是打開 LED,這實際上并沒有改變任何東西。

這里稍微有點不尋常的是 led_quarter_brightness()。每個 PIO 指令只需要運行一個時鐘周期(可以通過設置頻率來更改時鐘周期的長度,稍后我們將看到)。但是,我們可以在一條指令之后用方括號添加一個 1 到 31 之間的數字,來告訴 PIO 狀態機在運行下一條指令之前暫停這個時鐘周期。

然后,在 led_quarter_brightness() 中,兩個 set 指令每個使用一個時鐘周期,延遲使用兩個時鐘周期,因此總循環使用四個時鐘周期。在第一行中,set 指令需要一個周期,延遲需要兩個周期,所以 GPIO 管腳在這四個周期中的三個是關閉的。這使得 LED 的亮度達到了持續亮燈的四分之一。

一旦設定了 PIO 程序,Pico 就需要將其加載到狀態機中。因為我們有三個程序,所以需要將它們加載到三個狀態機中(有 8 個狀態機可以使用,編號為 0-7)。這可以用下面一行來實現:

sm1 = StateMachine(1, led_quarter_brightness, freq=10000, set_base=Pin(25))

參數如下:
– 狀態機器編號
– PIO 程序加載
– 頻率(必須在 2000 到 125000000 之間)
– 狀態機器操縱的 GPIO 引腳

還有一些額外的參數,你會在其他程序中看到,我們這里不需要。一旦創建了狀態機,就可以使用 active 方法啟動和停止狀態機,1 表示啟動,0 表示停止。

在我們的循環中,我們循環三個不同的狀態機。

一個真實的例子

讓我們通過一個實際示例來看看使用 PIO 的方法。WS2812B LED 燈條是一種包含三個 LED(一個紅色、一個綠色、一個藍色)和一個小型微控制器的燈組。它們由一根數據線控制,帶有計時相關協議。
LED 的接線很簡單,可能有一個插座,可以把頭部電線推進去,或者你可能需要自己焊接它們。

你需要注意的是從 Pico 上的 5V 引腳獲得的功率是有限的,如果無限擴展這個燈條,則需要額外給燈條供電。

5cf26ab8-82bb-11ee-939d-92fbcf53809c.png

現在我們已經把燈條和 Pico 連接好了,讓我們看看如何用 PIO 來控制它:

import array, time
from machine import Pin
import rp2
from rp2 import PIO, StateMachine, asm_pio


# Configure the number of WS2812 LEDs.
NUM_LEDS = 10


@asm_pio(sideset_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():
  T1 = 2
  T2 = 5
  T3 = 3
  label("bitloop")
  out(x, 1).side(0)[T3 - 1]
  jmp(not_x, "do_zero").side(1)[T1 - 1]
  jmp("bitloop").side(1)[T2 - 1]
  label("do_zero").side(0)[T2 - 1]
  nop()


# Create the StateMachine with the ws2812 program, outputting on Pin(22).
sm = StateMachine(0, ws2812, freq=8000000, sideset_base=Pin(0))


# Start the StateMachine, it will wait for data on its FIFO.
sm.active(1)

它的基本邏輯是每秒發送 800,000 位數據(注意頻率是 8000000,程序的每個周期是 10 個時鐘周期)。每一位數據都是一個脈沖——一個短脈沖表示 0,一個長脈沖表示 1。這個程序和我們之前的 程序之間的一個很大的區別是,MicroPython 需要能夠向這個程序發送數據 PIO 的程序。

數據進入狀態機有兩個階段。第一個是稱為先進先出(FIFO)的內存。這是我們的主 Python 程序發送數據到的地方。第二個是輸出移位寄存器(OSR)。這就是 out() 指令獲取數據的地方。兩者通過拉指令連接,拉指令從 FIFO 獲取數據并將其放在 OSR 中。然而,由于我們的程序設置了啟用 autopull 的閾值為 24,所以每次我們從 OSR 讀取 24 位時,它將從 FIFO 重新加載指令 out(x,1) 從 OSR 中獲取一位數據,并將其放入名為 x 的變量中(PIO 中只有兩個可用變量:x 和 y)。

jmp 指令告訴代碼直接移動到特定的標簽,但是它可以有一個條件。指令 jmp(not_x,”do_zero”) 告訴代碼,如果 x 的值為 0(或者,在邏輯術語中,如果 not_x 為真,并且 not_x 是 x 的 反面——在 pio 級別中,0 為假,任何其他數字為真),則移動到 do_zero。

這里我們一直忽略的一個方面是 .side() 位。它們與 set() 類似,但它們與另一條指令同時發生。這意味著 out(x,1) 發生時,.side(0) 設置側集引腳的值為 0。

哇,對于這么小的一個程序來說,這實在是太多了?,F在我們已經激活了它,讓我們看看如何使用它。下面的代碼需要在程序中位于上述代碼之下,以便將數據發送到 PIO 程序。

# Display a pattern on the LEDs via an array of LED RGB values.
ar = array.array("I", [0 for _ in range(NUM_LEDS)])


print("blue")
for j in range(0, 255):
  for i in range(NUM_LEDS):
    ar[i] = j
  sm.put(ar,8)
  time.sleep_ms(100)


print("red")
for j in range(0, 255):
  for i in range(NUM_LEDS):
    ar[i] = j<<8
  sm.put(ar,8)
  time.sleep_ms(100)


print("green")


for j in range(0, 255):
  for i in range(NUM_LEDS):
    ar[i] = j<<16
  sm.put(ar,8)
  time.sleep_ms(100)


print("white")
for j in range(0, 255):
  for i in range(NUM_LEDS):
    ar[i]=j<<16+j<<8+j
  sm.put(ar,8)
  time.sleep_ms(100)

在這里,我們跟蹤一個名為 ar 的數組,它保存了我們希望 LED 擁有的數據。數組中的每個數字都包含了一盞燈上所有三種顏色的數據。格式有點奇怪,因為它是二進制的。使用 PIO 的一個問題是,你經常需要處理單個數據位。每一位數據 都是 1 或 0,數字可以通過這種方式建立,所以以 10 為基數的 2 就是二進制的 10。以 10 為基數的 3 在二進制中等于 11。二進制數的 8 位中最大的數是 11111111,或者以 10 為基數的 255。我們不會在這里深入討論二進制。讓人更困惑的是,我們實際上把三個數字存儲在一個數字中。這是因為在 MicroPython 中,整數存儲在 32 位,但每個數字只需要 8 位。最后還有一點空閑空間,因為我們只需要 24 位,不過沒關系。

前八位是藍色,后八位是紅色,最后八位是綠色。8 位最多可以存儲 255 個數字,所以每個 LED 都有 255 個亮度級別。我們可以使用移位運算符 << 來實現這一點。這將在一個數字的末尾加上一 定數量的 0,所以如果我們想讓 LED 的紅色、綠色和藍色亮度達到 1 級,我們將每個值都設為 1,然后將它們移動到合適的位數。對于綠色,我們有:

1 << 16 = 10000000000000000

對于紅色,我們有:

1 << 8 = 100000000

對于藍色,我們根本不需要移位位,所以我們只有 1。如果我們把所有這些加在一起, 我們得到以下(如果我們把前面的位加起來,得到一個 24 位的數):

000000010000000100000001

最右邊的八位是藍色的,接下來的八位是紅色的,最左邊的八位是綠色的。最后一點可能看起來有點令人困惑的是這行:

ar = array.array("I", [0 for _ in range(NUM_LEDS)])

這創建了一個數組,第一個值是 I,然后每個 LED 都是 0。在開頭有一個I的原因是它告訴 MicroPython 我們使用的是一系列 32 位的值。但是,對于每個值,我們只需要將 24 位發送給 PIO,所以我們告訴 put 命令刪除 8 位:

sm.put(ar,8)

相關說明

PIO 狀態機使用的語言非常簡潔,所以只有少量的指令。除了我們已經看過的,你還可以使用:
in():移動 1 到 32 位到狀態機)與out()類似,但相反)。
push():將數據發送到連接狀態機和主存的內存中 MicroPython 程序。
pull():從連接狀態機和主存的內存塊中獲取數據 MicroPython 程序。這里我們沒有使用它,因為通過在程序中包含 autopull=True,當我們使用 out() 時,會自動發生這種情況。
mov():在兩個位置之間移動數據(例如 x 和 y 變量)。
irq():控制中斷。如果你需要觸發一個特定的東西以在程序的 MicroPython 端運行,就可以使用這些。
wait():暫停直到發生一些事情(例如 IO pin 更改了一個設定值或中斷發生)。

雖然只有少量的指令,但可以實現大量的通信協議。大多數指令都是用于以某種形式移動數據。如果你需要以任何特定的方式準備數據,例如操縱你希望 LED 的顏色,這應該在你的主 MicroPython 程序中完成,而不是在 PIO 程序中。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7489

    瀏覽量

    151048
  • 狀態機
    +關注

    關注

    2

    文章

    492

    瀏覽量

    27478
  • I2C協議
    +關注

    關注

    0

    文章

    26

    瀏覽量

    8456
  • 樹莓派
    +關注

    關注

    116

    文章

    1699

    瀏覽量

    105524

原文標題:樹莓派 Pico 之可編程 IO(PIO)

文章出處:【微信號:趣無盡,微信公眾號:趣無盡】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    樹莓Pico RP2040上怎樣使用MicroPython?

    RP2040 是一款由樹莓公司設計的 32 位雙核 ARM Cortex-M0+ 微控制器芯片,于 2021 年 1 月發布,作為樹莓 Pico
    的頭像 發表于 11-08 14:29 ?3103次閱讀
    在<b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b> RP2040上怎樣使用MicroPython<b class='flag-5'>呢</b>?

    樹莓pico入門學習筆記(一)相關資料推薦

    樹莓pico入門學習筆記選擇自己熟悉的編程語言樹莓pico提供C/C++和micropyth
    發表于 07-01 09:28

    樹莓pico如何入門?

    樹莓pico如何入門?
    發表于 10-13 08:11

    樹莓Pico的相關資料分享

    關注、星標公眾號,直達精彩內容1月22日,樹莓基金會最新發布一款低成本、高性能的微控制器開發板Raspberry Pi Pico,新產品相比普通樹莓
    發表于 11-03 08:44

    樹莓Pico的相關資料推薦

    1月22日,樹莓基金會最新發布一款低成本、高性能的微控制器開發板Raspberry Pi Pico,新產品相比普通樹莓體積更小,售價僅4
    發表于 02-07 07:37

    樹莓也出MCU了?樹莓Pico來了!

    關注、星標公眾號,直達精彩內容1月22日,樹莓基金會最新發布一款低成本、高性能的微控制器開發板Raspberry Pi Pico,新產品相比普通樹莓
    發表于 10-28 10:36 ?11次下載
    <b class='flag-5'>樹莓</b><b class='flag-5'>派</b>也出MCU了?<b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b>來了!

    樹莓不講武德,自研雙核MCU Pico,STM32哭暈在廁所!

    PIO架構,能否開創MCU市場全新領域,STM,兆易創新,STC,全志,樂鑫等一票國產MCU能否跟上?樹莓派發布雙核基于M0的MCU近日,樹莓派發布了自研的40nm雙核MCU,嵌入式MCU市場又要迎來真正的新氣象.一如之前發布的
    發表于 10-28 20:20 ?14次下載
    <b class='flag-5'>樹莓</b><b class='flag-5'>派</b>不講武德,自研雙核MCU <b class='flag-5'>Pico</b>,STM32哭暈在廁所!

    樹莓Pico:僅4美元的MCU

    1月22日,樹莓基金會最新發布一款低成本、高性能的微控制器開發板Raspberry Pi Pico,新產品相比普通樹莓體積更小,售價僅4
    發表于 12-04 13:06 ?13次下載
    <b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b>:僅4美元的MCU

    樹莓pico入門學習筆記(一)

    樹莓pico入門學習筆記選擇自己熟悉的編程語言樹莓pico提供C/C++和micropyth
    發表于 12-17 18:42 ?21次下載
    <b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>pico</b>入門學習筆記(一)

    距離檢測報警使用樹莓Pico

    電子發燒友網站提供《距離檢測報警使用樹莓Pico.zip》資料免費下載
    發表于 11-09 11:49 ?0次下載
    距離檢測報警使用<b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b>

    基于樹莓pico的可編程游戲手柄設計

    方案介紹組件12x12x7.3mm 瞬時觸覺按鈕按鈕樹莓Pico通用 D1286464 OLED 顯示屏操縱桿模塊 PS210 歐姆電阻?組裝將樹莓
    發表于 12-26 15:10 ?0次下載

    使用樹莓Pico制作USB麥克風

    本指南將教你如何使用樹莓 Pico 和外部數字麥克風制作屬于自己的 USB 麥克風。本項目通過 RP2040 微控制器(MCU)的編程 I/O(PIO)、直接存儲器訪問(DMA)和通
    的頭像 發表于 08-17 10:12 ?2834次閱讀
    使用<b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b>制作USB麥克風

    樹莓PICO pio使用

    樹莓 Pico 小小的板子上總是能讓我們發現一些驚喜。其所使用的RP2040芯片還具備8個可編程I/O(PIO)狀態機,用于自定義外圍設備
    的頭像 發表于 10-18 15:17 ?1539次閱讀

    樹莓Pico Flash驅動踩坑記錄

    樹莓 pico 帶有 2MB 的 Flash 資源,以下是我基于官方 Pico C/C++ SDK 對接 Flash 驅動時踩到的一些坑和解決辦法。
    的頭像 發表于 10-20 11:44 ?1460次閱讀

    如何在樹莓Pico上使用紅外線接收模塊?

    樹莓 Pico 上使用紅外線接收模塊(HX1838 型),我們采用開源的 pico_ir 庫。
    的頭像 發表于 11-30 09:08 ?2121次閱讀
    如何在<b class='flag-5'>樹莓</b><b class='flag-5'>派</b><b class='flag-5'>Pico</b>上使用紅外線接收模塊?