|
|
(57 dazwischenliegende Versionen des gleichen Benutzers werden nicht angezeigt) |
Zeile 14: |
Zeile 14: |
| | | |
| === Das SPI Konzept=== | | === Das SPI Konzept=== |
− | SPI arbeitet nach dem Master / Slave Konzept. Ein Master kontrolliert die Kommuniktion. | + | SPI arbeitet nach dem Master / Slave Konzept. Der Master kontrolliert die Kommuniktion. |
| <br> | | <br> |
| + | Die Hardware besteht im Prinzip aus einen 8-Bit Schieberegister. |
| + | <br><br> |
| + | [[file:SPI_konzept_1.png| SPI_Konzept_1]] |
| + | <br> |
| + | Quelle: https://www-user.tu-chemnitz.de/~heha/hsn/ATmegaX8.chm/19.htm |
| + | <br> |
| + | Die SPI Geräte können auf 2 Arten miteinander verbunden werden. Sie können parallel oder hintereinander (Dasy Chain) verbunden werden. |
| + | <br> |
| + | [[file:SPI_konzept_2.svg.png|SPI_konzept_2]] |
| + | <br> |
| + | [[file:SPI_konzept_3.svg.png||Daisychain]] |
| + | <br> |
| + | Quelle: https://de.wikipedia.org/wiki/Serial_Peripheral_Interface |
| + | ==== SPI Modes==== |
| | | |
− | === SPI des Pico===
| + | [[file:SPI_modes.svg.png|SPI_Modeses]] |
| | | |
| + | {| class="wikitable" style="margin:left" |
| + | |+ SPI Modes |
| + | |- |
| + | ! SPI Mode !! CPOL !! CPHA |
| + | |- |
| + | | 0|| 0 || 0 |
| + | |- |
| + | | 1|| 0|| 1 |
| + | |- |
| + | | 2|| 1|| 0 |
| + | |- |
| + | | 3 || 1|| 1 |
| + | |} |
| + | |
| + | Für die Taktfrequenz gibt es bei SPI keine Standards, wie bei I2C. Die maximal zulässigen Taktfrequenzen der SPI Ic's können dem Datenblatt entnommen werden. Sie können bis in den 2stelligen MHz Bereich gehen. |
| + | |
| + | === SPI Objekt erzeugen=== |
| + | Wie üblich in Micropython muss zuerst eine Instanz der Klasse SPI erzeugt werden. |
| ==== Hardware SPI==== | | ==== Hardware SPI==== |
| + | Der Pico hat 2 Hardware SPI Schnittstellen (ID = 0, 1)<br> |
| + | Die Klasse SPI unterstützt nur diese drei Leitungen: SCK, MOSI, MISO.<br> |
| + | Die D/C und CS Signale muss der Programmierer selbst steuern.<br> |
| + | Die Hardware SPI's können auf verschiedene Pins gelegt werden (s. Pinout)<br> |
| + | |
| Die default Einstellungen für Hardware SPI findet man so: | | Die default Einstellungen für Hardware SPI findet man so: |
| <pre> | | <pre> |
Zeile 29: |
Zeile 66: |
| SPI(1, baudrate=992063, polarity=0, phase=0, bits=8, sck=10, mosi=11, miso=8) | | SPI(1, baudrate=992063, polarity=0, phase=0, bits=8, sck=10, mosi=11, miso=8) |
| </pre> | | </pre> |
| + | SPI Instanz mit default Pins erstellen: |
| + | <pre> |
| + | from machine import Pin, SPI |
| + | spi = SPI(0) |
| + | </pre> |
| + | Für weitere Parameter gibt es noch folgende Möglichkeiten: |
| + | <pre> |
| + | spi = SPI(1, 10_000_000, sck=Pin(14), mosi=Pin(15), miso=Pin(12)) |
| + | spi = SPI(0, baudrate=80_000_000, polarity=0, phase=0, bits=8, sck=Pin(6), mosi=Pin(7), miso=Pin(4)) |
| + | </pre> |
| + | Wenn MISO nicht benötgt wird kann miso=None gesetzt werden. |
| | | |
| ==== Software SPI==== | | ==== Software SPI==== |
| + | Für eine SoftSPI Instanz sind weitere Angaben erforderlich: |
| + | |
| + | <pre> |
| + | from machine import Pin, SoftSPI |
| + | spi = SoftSPI(baudrate=500000, polarity=0, phase=0, bits=8, firstbit=SoftSPI.MSB, sck=Pin(2), mosi=Pin(3), miso=Pin(4)) |
| + | </pre> |
| + | |
| + | SoftSPI ist langsamer als die Hardwarevariante.<br> |
| + | |
| + | |
| + | ==== CS und D/C Handling==== |
| + | Aus ssd1306.py: |
| + | <pre> |
| + | def write_cmd(self, cmd): |
| + | self.spi.init(baudrate=self.rate, polarity=0, phase=0) |
| + | self.cs(1) |
| + | self.dc(0) |
| + | self.cs(0) |
| + | self.spi.write(bytearray([cmd])) |
| + | self.cs(1) |
| + | |
| + | def write_data(self, buf): |
| + | self.spi.init(baudrate=self.rate, polarity=0, phase=0) |
| + | self.cs(1) |
| + | self.dc(1) |
| + | self.cs(0) |
| + | self.spi.write(buf) |
| + | self.cs(1) |
| + | </pre> |
| + | |
| + | ==== SPI Methoden==== |
| + | |
| + | ; SPI.deinit() |
| + | : Schaltet den SPI Bus aus. |
| + | |
| + | ; SPI.read(nbytes, write=0x00) |
| + | : Liest nbytes Bytes ein und gibt dabei mit write angegebene Byte aus. |
| + | |
| + | ; SPI.readinto(buf, write=0x00) |
| + | : Liest Bytes in den Buffer und gibt dabei mit write angegebene Byte aus. |
| + | |
| + | ; SPI.write(buf) |
| + | : schreibt die in buf enthaltenen Bytes aus. |
| + | |
| + | ; SPI.write_readinto(write_buf, read_buf) |
| + | : schreibt die in write_buf enthaltenen Bytes aus und liest gleichzeitig Bytes in read_buf ein. |
| + | |
| + | Wie beim I2C Bus sind diese Methoden vor allem für das Schreiben von Treibern interessant.<br> |
| + | Wir gehen deshalb nicht weiter darauf ein. |
| + | |
| + | == Ein Beispiel mit dem BMP280 Sensor== |
| + | Auf dem Demoboard befindet sich der '''Temperatur- und Luftdruck-Sensor BMP280'''. Es handelt sich dabei um ein sehr komplexes IC. Wir können aber auf einige fertige Module zurückgreifen, so das die Handhabung für uns sehr einfach wird. Wichtig ist aber, dass die Dateien |
| + | * bmp280.py |
| + | * bmp280_configuration.py |
| + | * bmp280_spi.py |
| + | * bmp280_i2c.py |
| + | im Ordner '''/lib''' des Pico vorhanden sind. |
| + | <br> |
| + | |
| + | Wer sich intensiver mit diesem IC beschäftigen möchte findet hier https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf das Datenblatt.<br> |
| + | <br> |
| + | Weiter Informationen zum hier verwendeten BMP280-Modul gibt es hier: https://github.com/flrrth/pico-bmp280 |
| + | === Eine Instanz von bmp280 erzeugen=== |
| + | Die Anschlussbelegung ist folgendermaßen auf dem Demoboard realisiert: |
| + | * GPIO 16 - MISO |
| + | * GPIO 17 - CS |
| + | * GPIO 18 - SLK |
| + | * GPIO 19 - MOSI |
| + | DC wird hier nicht verwendet. |
| + | |
| + | <pre> |
| + | from machine import Pin, SPI |
| + | from utime import sleep |
| + | from bmp280_spi import BMP280SPI |
| + | |
| + | spi = SPI(0, sck=Pin(18), mosi=Pin(19), miso=Pin(16), polarity=1, phase=1) |
| + | # spi = SPI(0, polarity=1, phase=1) # funktioniert auch, da die default Belegung verwendet wird. |
| + | |
| + | spi_cs = Pin(17, Pin.OUT, value=1) |
| + | |
| + | bmp280_spi = BMP280SPI(spi, spi_cs) |
| + | </pre> |
| + | |
| + | === Werte holen=== |
| + | Das holen der Werte für Temperatur und Luftdruck gestaltet sich nun sehr einfach: |
| + | <pre> |
| + | readout = bmp280_spi.measurements |
| + | print(f"Temperature: {readout['t']} °C, pressure: {readout['p']} hPa.") |
| + | </pre> |
| + | Die Werte werden in einem Dictionary mit den Keys 't' und 'p' zurück gegeben. |
| + | <br> |
| + | Das Script '''12_SPI_BMP280_Demo.py''' zeigt diese einfache Methode. |
| + | <br> |
| + | Ein weiteres, aufwändigeres Script ist '''13_BMP280_OLED_Demo.py'''. Hierin erfolgt die Ausgabe auf dem Oled-Display. |
| + | |
| + | ==Navigation== |
| + | [[Micropython_Kurs_2023_-_Teil_2|Zurück zur "Micropython Kurs 2023 Teil 2" Startseite]]<br> |
| + | [[Micropython Kurs 2023|Zurück zur "Micropython Kurs 2023" Startseite]]<br> |
| + | [[Programmieren|Zurück zur Programmieren Startseite]]<br> |
| + | [[Attraktor_Wiki|Zurück zur Wiki Startseite]]<br> |
Aktuelle Version vom 21. Januar 2024, 12:24 Uhr
Das Serielle Periphere Interface
Dem Seriellen Peripheren Interface (SPI) liegt ein sehr einfaches Konzept zu Grunde. Dafür benötigt es mehr Leitungen als die I2C Schnittstelle:
- MOSI
- Master Out Slave In
- MISO
- Master In Slave Out
- SCK
- Clock
- D/C
- Data/Control
- CS / SS
- Chip Select
Das SPI Konzept
SPI arbeitet nach dem Master / Slave Konzept. Der Master kontrolliert die Kommuniktion.
Die Hardware besteht im Prinzip aus einen 8-Bit Schieberegister.
Quelle: https://www-user.tu-chemnitz.de/~heha/hsn/ATmegaX8.chm/19.htm
Die SPI Geräte können auf 2 Arten miteinander verbunden werden. Sie können parallel oder hintereinander (Dasy Chain) verbunden werden.
Quelle: https://de.wikipedia.org/wiki/Serial_Peripheral_Interface
SPI Modes
SPI Modes
SPI Mode |
CPOL |
CPHA
|
0 |
0 |
0
|
1 |
0 |
1
|
2 |
1 |
0
|
3 |
1 |
1
|
Für die Taktfrequenz gibt es bei SPI keine Standards, wie bei I2C. Die maximal zulässigen Taktfrequenzen der SPI Ic's können dem Datenblatt entnommen werden. Sie können bis in den 2stelligen MHz Bereich gehen.
SPI Objekt erzeugen
Wie üblich in Micropython muss zuerst eine Instanz der Klasse SPI erzeugt werden.
Hardware SPI
Der Pico hat 2 Hardware SPI Schnittstellen (ID = 0, 1)
Die Klasse SPI unterstützt nur diese drei Leitungen: SCK, MOSI, MISO.
Die D/C und CS Signale muss der Programmierer selbst steuern.
Die Hardware SPI's können auf verschiedene Pins gelegt werden (s. Pinout)
Die default Einstellungen für Hardware SPI findet man so:
from machine import SPI
print(SPI(0))
print(SPI(1))
SPI(0, baudrate=992063, polarity=0, phase=0, bits=8, sck=18, mosi=19, miso=16)
SPI(1, baudrate=992063, polarity=0, phase=0, bits=8, sck=10, mosi=11, miso=8)
SPI Instanz mit default Pins erstellen:
from machine import Pin, SPI
spi = SPI(0)
Für weitere Parameter gibt es noch folgende Möglichkeiten:
spi = SPI(1, 10_000_000, sck=Pin(14), mosi=Pin(15), miso=Pin(12))
spi = SPI(0, baudrate=80_000_000, polarity=0, phase=0, bits=8, sck=Pin(6), mosi=Pin(7), miso=Pin(4))
Wenn MISO nicht benötgt wird kann miso=None gesetzt werden.
Software SPI
Für eine SoftSPI Instanz sind weitere Angaben erforderlich:
from machine import Pin, SoftSPI
spi = SoftSPI(baudrate=500000, polarity=0, phase=0, bits=8, firstbit=SoftSPI.MSB, sck=Pin(2), mosi=Pin(3), miso=Pin(4))
SoftSPI ist langsamer als die Hardwarevariante.
CS und D/C Handling
Aus ssd1306.py:
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
SPI Methoden
- SPI.deinit()
- Schaltet den SPI Bus aus.
- SPI.read(nbytes, write=0x00)
- Liest nbytes Bytes ein und gibt dabei mit write angegebene Byte aus.
- SPI.readinto(buf, write=0x00)
- Liest Bytes in den Buffer und gibt dabei mit write angegebene Byte aus.
- SPI.write(buf)
- schreibt die in buf enthaltenen Bytes aus.
- SPI.write_readinto(write_buf, read_buf)
- schreibt die in write_buf enthaltenen Bytes aus und liest gleichzeitig Bytes in read_buf ein.
Wie beim I2C Bus sind diese Methoden vor allem für das Schreiben von Treibern interessant.
Wir gehen deshalb nicht weiter darauf ein.
Ein Beispiel mit dem BMP280 Sensor
Auf dem Demoboard befindet sich der Temperatur- und Luftdruck-Sensor BMP280. Es handelt sich dabei um ein sehr komplexes IC. Wir können aber auf einige fertige Module zurückgreifen, so das die Handhabung für uns sehr einfach wird. Wichtig ist aber, dass die Dateien
- bmp280.py
- bmp280_configuration.py
- bmp280_spi.py
- bmp280_i2c.py
im Ordner /lib des Pico vorhanden sind.
Wer sich intensiver mit diesem IC beschäftigen möchte findet hier https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf das Datenblatt.
Weiter Informationen zum hier verwendeten BMP280-Modul gibt es hier: https://github.com/flrrth/pico-bmp280
Eine Instanz von bmp280 erzeugen
Die Anschlussbelegung ist folgendermaßen auf dem Demoboard realisiert:
- GPIO 16 - MISO
- GPIO 17 - CS
- GPIO 18 - SLK
- GPIO 19 - MOSI
DC wird hier nicht verwendet.
from machine import Pin, SPI
from utime import sleep
from bmp280_spi import BMP280SPI
spi = SPI(0, sck=Pin(18), mosi=Pin(19), miso=Pin(16), polarity=1, phase=1)
# spi = SPI(0, polarity=1, phase=1) # funktioniert auch, da die default Belegung verwendet wird.
spi_cs = Pin(17, Pin.OUT, value=1)
bmp280_spi = BMP280SPI(spi, spi_cs)
Werte holen
Das holen der Werte für Temperatur und Luftdruck gestaltet sich nun sehr einfach:
readout = bmp280_spi.measurements
print(f"Temperature: {readout['t']} °C, pressure: {readout['p']} hPa.")
Die Werte werden in einem Dictionary mit den Keys 't' und 'p' zurück gegeben.
Das Script 12_SPI_BMP280_Demo.py zeigt diese einfache Methode.
Ein weiteres, aufwändigeres Script ist 13_BMP280_OLED_Demo.py. Hierin erfolgt die Ausgabe auf dem Oled-Display.
Navigation
Zurück zur "Micropython Kurs 2023 Teil 2" Startseite
Zurück zur "Micropython Kurs 2023" Startseite
Zurück zur Programmieren Startseite
Zurück zur Wiki Startseite