0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

樹莓派Pico的數(shù)字通信協(xié)議:I2C和SPI介紹

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

前面的章節(jié)中,我們已經(jīng)了解了如何使用一些常見的硬件,但隨著構(gòu)建的項(xiàng)目越來越多,你可能想要擴(kuò)展到使用各種不同的傳感器和顯示器。要如何與這些設(shè)備通信?

有時,你可能會發(fā)現(xiàn)有一個 MicroPython 庫可以使用,其中有人已經(jīng)將低級函數(shù)轉(zhuǎn)換為易于使用的接口。然而,情況并不總是這樣。幸運(yùn)的是,有一些連接低級數(shù)字設(shè)備的標(biāo)準(zhǔn)方法在 MicroPython 中通過 I2C 和 串行外設(shè)接口(SPI)得以實(shí)現(xiàn)。

I2C 和 SPI 在許多方面非常相似,因?yàn)樗鼈兌级x了一種將兩個設(shè)備之間的雙向接口連接的方式。事實(shí)上,許多部件都有這兩種版本接口,這樣你就可以選擇一個適合你的項(xiàng)目的接口。在這兩種情況下,都需要一個主控設(shè)備來控制通信(樹莓派 Pico)和一個或多個設(shè)備等待來自主控設(shè)備的指令。然而,也有一些不同之處。我們會時不時地對比這兩種協(xié)議幫助你從中作出合適的選擇

I2C

I2C 的通信在兩條線上進(jìn)行:一個時鐘(通常標(biāo)記為 SCL)和一個數(shù)據(jù)通道(通常標(biāo)記為SDA)。

65272854-82bb-11ee-939d-92fbcf53809c.png

這兩個引腳都必須連接到 Pico 的特定引腳上。Pico 上有兩個 I2C 總線(I2C0 和 I2C1),你可以使用其中一種。在我們的示例中,我們將使用 I2C0—GP0 用于 SDA,GP1 用于 SCL。

為了演示這些協(xié)議,我們將使用 SparkFun 的 SerLCD 模塊。這樣做的優(yōu)點(diǎn)是它同時擁有 I2C 和 SPI 接口,因此我們可以看到在相同的硬件下這兩種方法之間的區(qū)別。如果只使用 I2C 接口,也可以使用帶 I2C 接口的 LCD1602 液晶屏模塊替代。

這個液晶顯示器可以顯示兩行,每一行最多 16 個字符。它是一種有用的設(shè)備,可以輸出關(guān)于我們系統(tǒng)的信息。讓我們看看如何使用它。

將 Pico 上的 SDA 引腳與 LCD 上的 SDA 引腳連接,SCL 引腳與 LCD 上的 SCL 引腳連接。由于 I2C 處理通信的方式,還需要一個電阻連接 SDA 到 3.3V 和 SCL 到 3.3V。通常是 4.7kΩ。然而,我們的設(shè)備已經(jīng)包含了這些電阻,所以我們不需要添加任何額外的電阻。

653985d0-82bb-11ee-939d-92fbcf53809c.png

圖為 I2C 連接一個串行 LCD 模塊,編程讓它顯示信息非常簡單:

import machine
sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)
i2c.writeto(114, 'x7C')
i2c.writeto(114, 'x2D')
i2c.writeto(114, "hello world")

這段代碼并沒有做很多事情。它連接到 I2C 設(shè)備并發(fā)送一些數(shù)據(jù)。然而,也有一些看起來有點(diǎn)不尋常。writeto() 行中的 114 指的是 I2C 設(shè)備的地址。你可以將許多設(shè)備連接到 I2C 總線,每次要發(fā)送或接收數(shù)據(jù)時,都需要指定要與之通信的設(shè)備的地址。這個地址是硬連接到設(shè)備上的。

你應(yīng)該在設(shè)備的文檔中找到設(shè)備的地址,你也可以掃描 I2C 總線來查看當(dāng)前使用的地址。設(shè)置好 I2C 總線后,可以運(yùn)行 scan 方法輸出當(dāng)前使用的地址:

import machine
sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)
print(i2c.scan())

下一個看起來有點(diǎn)奇怪的位是寫入的 x7C 和 x2D 命令。每一個 I2C 設(shè)備需要以特定格式發(fā)送數(shù)據(jù)。這方面沒有標(biāo)準(zhǔn),所以你必須參考設(shè)備的文檔了解你正在設(shè)置的 I2C 設(shè)備。每一個開頭的 x 告訴 MicroPython,我們正在發(fā)送一個十六進(jìn)制字符串,這是一種常見的方式,以確保你正在發(fā)送你想要的確切數(shù)據(jù)。對于我們的液晶顯示器,7C 進(jìn)入命令模式,2D 清空液晶顯示器,并將光標(biāo)設(shè)置到開始。接下來,我們可以發(fā)送數(shù)據(jù)顯示到屏幕上:

file.close()

當(dāng)然,在屏幕上只顯示 Hello World 并沒有多大用處,所以讓我們看看如何把它變成一個更有用的東西——溫度計(jì)。在之前的系列教程中,我們學(xué)習(xí)了如何使用 Pico 的內(nèi)部溫度傳感器使用 ADC 讀取溫度?,F(xiàn)在,我們可以在此代碼的基礎(chǔ)上構(gòu)建一個獨(dú)立的溫度計(jì),它不需要計(jì)算機(jī)讀取輸出。在你的 LCD 仍然像之前一樣連接,運(yùn)行以下代碼:

import machine
import utime


sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)


adc = machine.ADC(4)
conversion_factor = 3.3 / (65535)


while True:
  reading = adc.read_u16() * conversion_factor
  temperature = 25 - (reading - 0.706)/0.001721
  i2c.writeto(114, 'x7C')
  i2c.writeto(114, 'x2D')
  out_string = "Temp: " + str(temperature)
  i2c.writeto(114, out_string)
  utime.sleep(2)

這看起來應(yīng)該很熟悉。對之前的溫度代碼的唯一細(xì)微變化是,在輸出計(jì)算結(jié)果之前,LCD 需要顯示字符,因此我們使用 str 函數(shù)將數(shù)字轉(zhuǎn)換為字符串。然后,我們可以將它與 “Temp:” 組合起來,將其構(gòu)建為一個信息更豐富的輸出。

如你所見,I2C 是一種將其他硬件鏈接到 Pico 的簡單方法。你需要確保你有任何你想要連接的設(shè)備的設(shè)備文檔,讓你知道什么命令做什么,但只要你知道這一點(diǎn),你可以很容易地添加各種各樣的比特和鮑勃到你的 Pico 和創(chuàng)建令人印象深刻的構(gòu)建。

串行外圍接口

我們已經(jīng)了解了 I2C 的工作原理,現(xiàn)在讓我們來看看 SPI。我們將使用完全相同的 LCD,因此命令和其他一切都是相同的,只是我們發(fā)送數(shù)據(jù)的協(xié)議不同 SPI 有四個連接:SCLK、MOSI、MISO 和 CS(有時標(biāo)記為SS)。SCLK 是時鐘,MOSI 是將數(shù)據(jù)從你的 Pico 到外圍設(shè)備。MISO 將數(shù)據(jù)從外圍設(shè)備發(fā)送到 Pico。CS 代表芯片選擇用于將多個設(shè)備連接到單個 SPI 總線。你可以把 CS 到 GPIO 引腳并切換這個開關(guān)來啟用和禁用顯示,但由于我們只有一個設(shè)備,我們可以簡單地將它連接到 GND,以保持它的啟用。因此,SerLCD 的電源線連接到 VBUS 和 GND,我們只需要連接 itsSDO 到 Pico 的 MISO (GP4/SPI0 RX),SDI 接到 MOSI (GP3/SPI0 TX),SCK 接到 SCLK(GP2/SPI0 TX),SCK 和 CS 接到 GND。

654d53a8-82bb-11ee-939d-92fbcf53809c.png

SPI 需要四個連接:一個從主服務(wù)器獲取數(shù)據(jù)設(shè)備到從設(shè)備,另一個在相反的方向上獲取數(shù)據(jù),加上電源和 GND。兩根數(shù)據(jù)線意味著數(shù)據(jù)可以同時在兩個方向上旅行。這些通常被稱為 Master Out Slave In (MOSI) 和 Master In Slave Out (MISO)。然而,你會見到不同的叫法。如果你看一下 Raspberry Pi Pico 引腳圖,它們被稱為 SPI TX(發(fā)送)和 SPI RX(接收)。這是因?yàn)?Pico 可以是兩者之一主設(shè)備或從設(shè)備,所以無論這些連接是 MOSI 還是 MISO,取決于 Pico 的當(dāng)前功能。在我們使用的液晶顯示器上,它們被標(biāo)記為 SDI(串行數(shù)據(jù)輸入)和 SDO(串行數(shù)據(jù)輸出)SPI 中沒有地址,所以我們可以直接寫代碼:

import machine


spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi_rx=machine.Pin(4)


spi=machine.SPI(0,baudrate=100000,sck=spi_sck, mosi=spi_tx, miso=spi_rx)


spi.write('x7C')
spi.write('x2D')
spi.write("hello world")

在這種情況下,我們使用的是 SPI0,一組可用的引腳是 GP2、GP3 和 GP4。大多數(shù)類型的串行通信有一個速度或波特率,這基本上是多少每秒可以通過信道傳輸?shù)臄?shù)據(jù)位。很多事情都會影響這個,比如連接的兩個設(shè)備的能力和它們之間的連接(多長時間)如果有其他設(shè)備的干擾。如果你發(fā)現(xiàn)數(shù)據(jù)錯誤或丟失問題,那么你可能需要減少它。對于我們的小屏幕,我們只發(fā)送一個字節(jié)的數(shù)據(jù)字符,因此我們發(fā)送它的速度并不重要,但是對于其他一些SPI設(shè)備,微調(diào)波特率可能很重要。

讓我們看看下面我們的使用的溫度計(jì)代碼:

import machine
import utime


spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi_rx=machine.Pin(4)


spi=machine.SPI(0,baudrate=100000,sck=spi_sck, mosi=spi_tx, miso=spi_rx)


adc = machine.ADC(4)
conversion_factor = 3.3 / (65535)


while True:
  reading = adc.read_u16() * conversion_factor
  temperature = 25 - (reading - 0.706)/0.001721
  spi.write('x7C')
  spi.write('x2D')
  out_string = "Temp: " + str(temperature)
  spi.write(out_string)
  utime.sleep(2)

正如你所看到的,I2C 和 SPI 之間的代碼實(shí)際上差別很小。一旦你完成了電路和代碼,唯一的真正改變是與 I2C 你指定的地址發(fā)送數(shù)據(jù)。

那么,既然它們?nèi)绱讼嗨疲跇?gòu)建項(xiàng)目時你應(yīng)該選擇哪種協(xié)議呢?有需要考慮的幾個因素。第一個是你想要附加的東西的可用性。有時,一個傳感器只能支持 I2C 或 SPI,所以你必須使用它。但是,如果你有選擇的話對于硬件來說,當(dāng)你使用多個額外的設(shè)備時,影響最大。通過 I2C 你可以在一個 I2C 總線上連接多達(dá) 128 個設(shè)備;然而,它們都需要有一個單獨(dú)的地址。這些地址是硬連接的。如果你想要更多相同類型的傳感器,你可能會受到傳感器的 I2C 地址數(shù)量的限制。在本例中,SPI 也許是更好的選擇。

另外,SPI 可以有無限數(shù)量的設(shè)備連接;然而,每一個都必須有自己的 CS 引腳。在 Pico 上,有 26 個 GPIO 引腳。所以這意味著有 23 哥可用的 CS 引腳。這是假設(shè)你不需要任何其他東西。如果可用的 GPIO 非常緊缺,那么你可能需要考慮 I2C。

實(shí)際上,對于許多項(xiàng)目,你都可以隨意地使用其中任何一種協(xié)議,你可能會發(fā)現(xiàn)這選擇使用哪一個更多的是與你在零件箱里找到的零件有關(guān),而不是兩者在技術(shù)上的區(qū)別。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    899

    瀏覽量

    40348
  • 樹莓派
    +關(guān)注

    關(guān)注

    117

    文章

    1710

    瀏覽量

    105750

原文標(biāo)題:樹莓派 Pico 的數(shù)字通信協(xié)議:I2C 和 SPI

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

收藏 人收藏

    評論

    相關(guān)推薦

    數(shù)字通信協(xié)議中,什么是I2CSPI總線協(xié)議

    現(xiàn)今,在低端數(shù)字通信應(yīng)用領(lǐng)域,我們隨處可見IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是這兩種
    的頭像 發(fā)表于 11-12 09:28 ?1.2w次閱讀
    <b class='flag-5'>數(shù)字通信協(xié)議</b>中,什么是<b class='flag-5'>I2C</b>和<b class='flag-5'>SPI</b>總線<b class='flag-5'>協(xié)議</b>?

    i2c通信協(xié)議

    1.1 i2c通信協(xié)議通信協(xié)議:用來實(shí)現(xiàn)數(shù)據(jù)傳輸。i2c物理總線:SCL(時鐘線) SDA(數(shù)據(jù)線)i2c
    發(fā)表于 03-06 16:15

    SPII2C、UART串行總線協(xié)議

    串口通訊通信協(xié)議UART,以及常用外設(shè)通信協(xié)議 SPI、I2C介紹與他們之間的區(qū)別
    發(fā)表于 11-30 11:28 ?95次下載

    實(shí)驗(yàn)八-I2C通信協(xié)議

    實(shí)驗(yàn)八-I2C通信協(xié)議,感興趣的可以瞧一瞧。
    發(fā)表于 09-22 16:42 ?2次下載

    spii2c總線協(xié)議的對比分析

    現(xiàn)今,在低端數(shù)字通信應(yīng)用領(lǐng)域,我們隨處可見I2C (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是這兩種
    發(fā)表于 12-06 11:57 ?2518次閱讀

    I2C通信協(xié)議應(yīng)該如何學(xué)習(xí)

    我最近剛做完I2C通信協(xié)議的編寫與調(diào)試,下面介紹一下我從一開始理解夏老師的程序,修改程序,直到下板調(diào)試整個的學(xué)習(xí)過程,希望對大家學(xué)習(xí) I2C 有一定的幫助。一、 分析源代碼學(xué)習(xí)
    發(fā)表于 04-28 08:00 ?21次下載
    <b class='flag-5'>I2C</b><b class='flag-5'>通信協(xié)議</b>應(yīng)該如何學(xué)習(xí)

    什么是I2C通信協(xié)議?

    在本教程中,我們將學(xué)習(xí)如何在Raspberry Pi Pico中使用I2C引腳并遍歷I2C掃描器代碼。
    的頭像 發(fā)表于 04-26 15:08 ?7821次閱讀
    什么是<b class='flag-5'>I2C</b><b class='flag-5'>通信協(xié)議</b>?

    linux移植MPU6050的I2C驅(qū)動

    有MPU6050的例程,測試后很好用,如下圖(夢幻聯(lián)動一下:樹莓PICO+freeRTOS)因?yàn)?b class='flag-5'>pico上有現(xiàn)成的能用的例程,所以改一改之后直接移植到linux上首先
    發(fā)表于 12-06 14:21 ?10次下載
    linux移植MPU6050的<b class='flag-5'>I2C</b>驅(qū)動

    SPI通信協(xié)議講解

    SPI通信協(xié)議講解SPI通信概念SPI通信SPI
    發(fā)表于 12-22 19:19 ?26次下載
    <b class='flag-5'>SPI</b><b class='flag-5'>通信協(xié)議</b>講解

    i2cspi通信協(xié)議的概念與區(qū)別 I2C/SPI總線通信協(xié)議你搞懂沒有

    計(jì)劃第四期:硬聲UP主@硬件研究獅 從工程實(shí)踐的角度,給大家拆解I2CSPI。 ? ? 四分鐘搞定通信協(xié)議的分類 簡介: 同步通信與異步通信
    的頭像 發(fā)表于 06-23 17:19 ?3708次閱讀

    Arduino與樹莓之間的I2C通信

    電子發(fā)燒友網(wǎng)站提供《Arduino與樹莓之間的I2C通信.zip》資料免費(fèi)下載
    發(fā)表于 12-22 15:47 ?0次下載
    Arduino與<b class='flag-5'>樹莓</b><b class='flag-5'>派</b>之間的<b class='flag-5'>I2C</b><b class='flag-5'>通信</b>

    I2C通信協(xié)議:了解I2C Primer、 PMBus和SMBus

    I2C,即Inter-Integrated Circuit,是一種常用的串行通信協(xié)議,用于在器件之間——特別是兩個或兩個以上不同電路之間建立通信。I2C Primer是最常用的
    的頭像 發(fā)表于 06-15 15:29 ?5880次閱讀
    <b class='flag-5'>I2C</b><b class='flag-5'>通信協(xié)議</b>:了解<b class='flag-5'>I2C</b> Primer、 PMBus和SMBus

    UART、SPI、I2C比較 串口通信介紹

    ,較少用于遠(yuǎn)距離通信SPI實(shí)現(xiàn)要簡單一些,UART需要固定的波特率,就是說兩位數(shù)據(jù)的間隔要相等,而SPI則無所謂,因?yàn)樗怯袝r鐘的協(xié)議。 I2C
    的頭像 發(fā)表于 11-09 18:06 ?1495次閱讀
    UART、<b class='flag-5'>SPI</b>、<b class='flag-5'>I2C</b>比較 串口<b class='flag-5'>通信</b><b class='flag-5'>介紹</b>

    SPII2C通信協(xié)議:應(yīng)用與區(qū)別

    本文深入解析了SPII2C這兩種通信協(xié)議的特點(diǎn)、工作原理和應(yīng)用場景。SPI適用于高速數(shù)據(jù)傳輸,常用于存儲器芯片和顯示器驅(qū)動等領(lǐng)域;I2C
    的頭像 發(fā)表于 04-22 16:45 ?1906次閱讀

    簡單認(rèn)識I2C通信協(xié)議

    I2C(Inter-Integrated Circuit)通信協(xié)議是由飛利浦公司(現(xiàn)為恩智浦半導(dǎo)體)開發(fā)的一種簡單、雙向二線制同步串行總線協(xié)議。自1982年發(fā)布以來,I2C
    的頭像 發(fā)表于 07-25 18:06 ?1583次閱讀