Protocolul SPI: Magistrala Sincronă Full-Duplex de Mare Viteză
Transfer simultan bidirecțional la viteze de peste 50 MHz: arhitectura registrelor de deplasare, cele 4 moduri CPOL/CPHA și conectarea ecranelor TFT și a cardurilor SD.
1. Cum funcționează SPI: Iluzia transferului simultan
Spre deosebire de I2C sau UART (care sunt semiduplex sau asincrone), SPI este un protocol sincron cu linii dedicate pentru fiecare direcție. La fiecare impuls generat pe linia de ceas (SCK), un bit iese din Master spre Slave pe linia MOSI, iar simultan un alt bit este împins dinspre Slave spre Master pe linia MISO. Practic, cele două dispozitive formează un uriaș inel circular de 16 biți (ring buffer).
Linii active push-pull rapide, capabile să atingă zeci de megahertzi fără limitarea rezistențelor de pull-up.
Fiecare periferic conectat are propriul său pin CS dedicat tras la LOW (0V) pentru a activa comunicația.
Explorator Interactiv: Cele 4 Moduri de Ceas (CPOL & CPHA)
Polaritatea (CPOL) determină starea liniei de ceas în repaus, iar Faza (CPHA) specifică pe care front se eșantionează datele.
În cod Arduino IDE: SPI.beginTransaction(SPISettings(viteza, MSBFIRST, SPI_MODE0));
2. Tabel Decizional: Când alegi SPI în loc de I2C?
- Debit masiv de date: Ecrane grafice color TFT (ILI9341, ST7789) la 30-60 FPS.
- Stocare pe Card MicroSD: Scriere continuă de loguri la 20-40 MHz.
- Module Radio RF rapide: Module NRF24L01+ și LoRa SX1276/SX1262.
- Număr limitat de pini GPIO: Vrei să legi 10 senzori folosind fix aceiași 2 pini.
- Senzori de mediu lenți: Senzori de temperatură, presiune atmosferică, giroscoape.
- Distanțe mai lungi: I2C suportă cabluri mai lungi datorită rezistențelor de pull-up și vitezei mai reduse.
3. Cod Model: Citire Registru JEDEC ID prin SPI
#include <SPI.h>
// Definim pinul dedicat Chip Select (CS / SS)
const int csPin = 5; // Pin GPIO configurat ca iesire CS
void setup() {
Serial.begin(115200);
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH); // Inactiv in starea HIGH (linie deselectata)
SPI.begin(); // Activeaza perifericul hardware SPI (SCK, MOSI, MISO)
Serial.println("[SPI] Magistrala initializata la viteza maxima!");
}
void loop() {
// Configuram tranzactia la 20 MHz, MSB first, Modul 0
SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
digitalWrite(csPin, LOW); // Selecteaza perifericul (Active LOW)
// Transfer Full-Duplex: trimitem comanda 0x9F (Read JEDEC ID) si citim simultan raspunsul
byte response1 = SPI.transfer(0x9F);
byte manufacturerId = SPI.transfer(0x00);
byte deviceId = SPI.transfer(0x00);
digitalWrite(csPin, HIGH); // Deselecteaza perifericul
SPI.endTransaction();
Serial.print("JEDEC Manufacturer ID: 0x");
Serial.println(manufacturerId, HEX);
Serial.print("Device ID: 0x");
Serial.println(deviceId, HEX);
delay(2000);
}