Comunicación SPI con Arduino, ESP8266 y ESP32: Guía de Pines y Bus

En este tutorial aprenderás todo lo que necesitas sobre la comunicación SPI, desde la arquitectura y la transmisión de datos hasta ejemplos prácticos

En esta guía técnica analizamos a fondo el funcionamiento del bus de comunicación SPI (Serial Peripheral Interface), su arquitectura síncrona full-duplex y cómo diagnosticar problemas de señal física con instrumental de laboratorio:

  • Asignación de pines hardware: líneas SCK, MOSI, MISO y CS/SS en Arduino Uno, Nano, Mega 2560, ESP8266 (NodeMCU) y ESP32 (buses VSPI y HSPI).
  • Modos de transmisión SPI (0 a 3): configuración de polaridad (CPOL) y fase de reloj (CPHA) para sincronizar maestros y esclavos sin corrupción de datos.
  • Reglas de diseño eléctrico y seguridad: adaptación de niveles entre 5 V y 3,3 V, y solución al bloqueo de bus por módulos sin buffer tri-state en MISO.
  • Diagnóstico con osciloscopio: captura con 4 canales analógicos, disparo por flanco de bajada en CS y decodificación serie de tramas en hexadecimal.

Comparación de protocolos de comunicación de microcontroladores desde el punto de vista de SPI

SPI fue inventado por Motorola en 1970. La siguiente tabla compara los protocolos de comunicación I2C, SPI y UART según diferentes categorías.

 DescripciónI2CSPIUART
Inventado por1982 por Philips Semiconductor1970 por Motorola1960 por Gordon Bell en Digital Equipment Corporation
Transferencia de datos síncronaSe necesita una línea de reloj para sincronizar la comunicaciónVerdaderoVerdaderoFalso
Transferencia de datos asíncronaEn lugar de una señal de reloj, el propio flujo continuo de datos (data stream) contiene señales de inicio y de paradaFalseFalseTrue
Rendimiento10 kbps a 1 Mbps (hasta 3,4 Mbps en High-Speed)Hasta 10 Mbps o más (según el reloj del microcontrolador)Típico 9.600 a 115.200 baudios (máx. ~1-2 Mbps)
El esclavo necesita una dirección únicaVerdaderoFalsoFalso
Número de pines necesarios242
Protocolo de comprobación de erroresVerdaderoFalsoVerdadero
Multi-maestroPuede tener varios maestros que controlen uno o varios esclavosVerdaderoFalsoFalso
Multi-esclavoPuede conectar varias salves a un solo maestroVerdaderoVerdaderoFalso
Conmutación de paquetesLos datos transferidos se agrupan en paquetes/mensajes, compuestos por una cabecera y una carga útilVerdaderoFalsoFalso
Single-endedLos datos se transfieren por un solo cableTrue
Datos en serie (SDA)
Falso
Master in Slave Out (MISO)
Master Out Slave In (MOSI)
False
Conexión serieLos datos se transfieren bit a bit a lo largo de un solo cableVerdaderoVerdaderoVerdadero

Al igual que I2C, SPI es un protocolo de datos en serie síncrono y, por lo tanto, necesita un reloj para sincronizar la comunicación entre los dispositivos maestro y esclavo.

Se recomienda SPI cuando la velocidad de comunicación necesita apostar muy rápido. El rendimiento máximo es de hasta 10,000,000 bps y mucho más rápido que I2C y UART. La velocidad que puede utilizar el microcontrolador se basa en la frecuencia del chip (frecuencia de reloj). La mayoría de los microcontroladores Arduino tienen una velocidad de chip de 16 MHz, pero se recomienda que establezca la velocidad de comunicación a la mitad de la velocidad de chip de 8 MHz (8.000.000 bps). ESP8266 tiene una velocidad de chip más alta que el microcontrolador Arduino 80MHz y también se recomienda reducir la velocidad de comunicación para el microcontrolador ESP8266.
Para configurar el reloj SPI en relación con el reloj del sistema, utilice la función setClockDivider (). Por ejemplo, si desea una velocidad SPI de 8 Mbps y su velocidad de chip es de 16 MHz, utilice la siguiente función con el parámetro setClockDivider (SPI_CLOCK_DIV2). Están disponibles los siguientes divisores: 2, 4, 8, 16, 32, 64 o 128.
Pero en la práctica, depende de usted decidir si desea seleccionar manualmente la velocidad de comunicación a través de la función, porque el Arduino selecciona automáticamente la velocidad de comunicación igual o menor que el parámetro según el dispositivo con la velocidad de comunicación más débil.

En un sistema SPI, siempre tiene un solo dispositivo maestro. Por lo tanto, SPI no puede construir un sistema multimaestro. Si desea comunicarse entre, por ejemplo, un Arduino Uno y un NodeMCU, un dispositivo debe ser el maestro y el otro el esclavo. Pero SPI puede administrar varios dispositivos esclavos, cada uno de los cuales está conectado al dispositivo maestro a través de la línea llamada Slave Select (SS). Como la línea de selección de esclavos conecta cada esclavo al maestro, no hay una dirección única para cada esclavo como para la comunicación I2C.

SPI tres esclavos

Hay 3 líneas que conectan el dispositivo maestro a todos los dispositivos esclavos

  • MISO (Master in Slave Out): la línea esclava para enviar datos al maestro
  • MOSI (Master Out Slave In): la línea maestra para enviar datos a periféricos
  • SCK / SCLK (reloj serial): pulso desde el dispositivo maestro para sincronizar la transmisión de datos

Y 1 línea maestra para cada dispositivo

  • SS (Selección de esclavo) Una línea específica para cada dispositivo que el maestro puede activar o desactivar el esclavo específico. Esto hace posible compartir la línea MISO, MOSI y SCK entre varios dispositivos. El pin SS puede ser cualquier pin digital de su microcontrolador
    • El pin SS es BAJO → La comunicación del esclavo con el maestro está habilitada
    • El pin SS es ALTO → La comunicación del esclavo con el maestro está deshabilitada

Si quieres saber cuáles son los pines MISO, MOSI y SCK para diferentes microcontroladores, puedes encontrar esta información en los artículos relacionados con pinout: Arduino Mega, Arduino Uno, Arduino Nano, ESP8266 NodeMCU o mejor si descargas la hoja de datos eBook del microcontrolador.

Configuración de SPI para habilitar la comunicación SPI

Si queremos iniciar una comunicación, primero debemos activar SPI con el siguiente código Arduino SPI.beginTransaction (SPISettings (8000000, MSBFIRST, SPI_MODE0));
Verá que al iniciar una comunicación SPI, hay en total 3 parámetros que se pueden configurar si queremos controlar los parámetros manualmente. Estos parámetros SPI no se eliminan cuando la comunicación SPI está deshabilitada con SPI.endTransaction (). En su lugar, puede cambiar la configuración de SPI anulando la configuración a través de la función SPISettings (). Siempre existe la opción de permitir que el microcontrolador establezca automáticamente los parámetros SPI, que vemos en los ejemplos de este tutorial.

Configuración de la frecuencia del reloj para SPI

El primer parámetro es la velocidad de reloj SPI que se establece en 8 Mbps en este ejemplo.

Configuración de transferencia de datos para SPI

El segundo parámetro es el desplazamiento de datos que define qué bit se transfiere primero. Hay 2 opciones:

  • Bit más significativo (MSB) → MSBFIRST: el bit 8 es el primer bit que se transfiere a través de SPI
  • Último bit significativo (LSB) → LSBFIRST: el bit 1 es el primer bit que se transfiere a través de SPI

Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1

 2⁷2⁶2⁵2⁴2³2²2¹2⁰ 
MSB>11001011 

La mayoría de los chips SPI utilizan el primer orden de datos MSB.

Modos de transmisión para SPI

Hay un total de 4 modos de transmisión diferentes dependiendo de la combinación de 2 parámetros de transmisión:

  • Fase de reloj (ACSP)
    • CPHA = 1: muestras del flanco ascendente del pulso de reloj
    • CPHA = 0: muestras del flanco descendente del pulso de reloj
  • Polaridad de reloj (CPOL)
    • Reloj no activo en estado alto (CPOL = 1): Cada ciclo consta de un pulso de 0. El flanco ascendente es un flanco descendente y el flanco de salida es un flanco ascendente.
    • Reloj inactivo en estado bajo (CPOL = 0): cada ciclo consta de un pulso de 1. El flanco ascendente es un flanco ascendente y el flanco posterior es un flanco descendente.

La siguiente tabla muestra los 4 modos de transmisión diferentes.

Modo de polaridad de reloj (CPOL) Fase de reloj (CPHA) Captura de datos de borde de salida

Modo SPI CPOL (Polaridad Reloj) CPHA (Fase Reloj) Flanco de Muestreo (Lectura) Flanco de Conmutación (Salida)
SPI_MODE0 0 (Reposo en nivel BAJO) 0 (Primer flanco) Flanco de subida (Rising Edge) Flanco de bajada (Falling Edge)
SPI_MODE1 0 (Reposo en nivel BAJO) 1 (Segundo flanco) Flanco de bajada (Falling Edge) Flanco de subida (Rising Edge)
SPI_MODE2 1 (Reposo en nivel ALTO) 0 (Primer flanco) Flanco de bajada (Falling Edge) Flanco de subida (Rising Edge)
SPI_MODE3 1 (Reposo en nivel ALTO) 1 (Segundo flanco) Flanco de subida (Rising Edge) Flanco de bajada (Falling Edge)

Para la mayoría de los dispositivos, SPI_MODE0 es el modo de transmisión predeterminado. Las siguientes imágenes muestran los cuatro modos diferentes. Ves la línea SCK y cuando el reloj está muestreando.

Modos de transmisión

Transmisión de datos SPI

Reglas de seguridad y diseño eléctrico en el bus SPI
  • Incompatibilidad de tensiones 5 V vs. 3,3 V: A diferencia de I2C, el bus SPI emplea controladores push-pull activos de alta corriente. Las líneas SCK, MOSI y CS de un Arduino Uno o Mega emiten 5 V constantes con transiciones inferiores a 10 ns. Conectarlas directamente a entradas de 3,3 V (como ESP8266, ESP32 o módulos SD) sobrecargará y destruirá los diodos de protección del integrado. Utiliza siempre un conversor de nivel lógico unidireccional de alta velocidad (ej. 74LVC245 o 74AHCT125); los divisores resistivos pasivos degradan la señal por encima de 4 MHz.
  • Trampa del bloqueo de bus en la línea MISO (salidas tri-state defectuosas): Cuando conectas varios esclavos al mismo bus SPI, todos deben liberar la línea MISO (dejándola en alta impedancia o High-Z) excepto el dispositivo seleccionado con CS en BAJO. Muchos módulos comerciales baratos de tarjetas SD carecen de buffer tri-state en MISO y fuerzan la línea a nivel alto constantemente, impidiendo la lectura de cualquier otro sensor conectado en paralelo.
  • Ruido electromagnético y timbrado a altas frecuencias: Dado que SPI puede alcanzar velocidades de 8 a 20 MHz, los cables largos de protoboard (>20 cm) actúan como líneas de transmisión con reflexiones parásitas (ringing) que provocan dobles flancos de reloj. Mantén los cables por debajo de 15 cm y evita cruzar las líneas de reloj con señales analógicas de baja tensión.
Transmisión de datos SPI

Los datos que se transfieren a través de la comunicación SPI se almacenan en registros de desplazamiento de 8 o 16 bits que tienen la misma longitud para el dispositivo maestro y esclavo. Los datos generalmente se desplazan con el bit más significativo primero, definido por los parámetros SPI, y se almacenan como el nuevo último bit significativo del registro de desplazamiento. El módulo SPI no tiene búfer en la dirección de transmisión y es único en la dirección de recepción. Los siguientes 6 pasos describen la transmisión de datos SPI:

  1. Primero, el dispositivo maestro configura los parámetros SPI (frecuencia de reloj, compensación de datos, modo de transmisión).
  2. El maestro selecciona el dispositivo esclavo tirando de la línea SS LOW (del 1 lógico al 0 lógico).
  3. Los siguientes pasos se realizan todos al mismo tiempo durante un ciclo de reloj en una transmisión de datos full duplex:
    1. En el borde del reloj, el maestro envía el primer bit al esclavo a través de la línea MOSI. El esclavo lee el mensaje entrante.
    2. En el borde del reloj, el esclavo envía el primer bit al maestro a través de la línea MISO. El maestro lee el mensaje entrante.
  4. El intercambio de datos se realiza cuando se transmite el registro de desplazamiento completo.
  5. A continuación, se copia el registro de desplazamiento completo en el búfer de recepción y se vuelven a cargar los registros de desplazamiento. El proceso de transmisión de datos comienza de nuevo.
  6. Si la transmisión está completa, el maestro detiene la señal del reloj y deja de tirar de la línea SS LOW.

Ventajas y desventajas de SPI

Ventajas

  • Comunicación full duplex (I2C no es comunicación síncrona)
  • Flujo más alto que I2C
  • No limitado a palabras de 8 bits
  • Menor consumo de energía que I2C porque no se requiere resistencia pull-up
  • Los esclavos no necesitan una dirección única con respecto a I2C

Desventajas

  • Requiere más pines que I2C
  • Sin protocolo de comprobación de errores
  • Muchas variaciones diferentes ya que no se define ningún estándar formal

Pines del Bus SPI en Arduino Uno, Nano, Mega, ESP8266 y ESP32

Para interconectar memorias EEPROM/Flash, lectores micro-SD, módulos de radio NRF24L01 o pantallas TFT mediante SPI, es indispensable conectar las señales a los pines de hardware dedicados del microcontrolador para aprovechar la máxima velocidad del periférico interno (hasta 10-20 MHz):

Placa / Microcontrolador SCK (Reloj) MOSI (Master Out) MISO (Master In) SS / CS (Chip Select) Nivel Lógico
Arduino Uno / Nano D13 D11 D12 D10 (u otro digital) 5 V
Arduino Mega 2560 Pin 52 Pin 51 Pin 50 Pin 53 (u otro digital) 5 V
ESP8266 (NodeMCU / D1) D5 (GPIO 14) D7 (GPIO 13) D6 (GPIO 12) D8 (GPIO 15) 3,3 V (No tolerante a 5 V)
ESP32 (Bus VSPI por defecto) GPIO 18 GPIO 23 GPIO 19 GPIO 5 3,3 V (No tolerante a 5 V)
ESP32 (Bus HSPI secundario) GPIO 14 GPIO 13 GPIO 12 GPIO 15 3,3 V (No tolerante a 5 V)

También les doy dos ejemplos de comunicación SPI porque es bueno conocer la teoría y cómo funciona algo. Pero al final quieres llevar a cabo proyectos y necesitas ejemplos para ver cómo se hace la comunicación SPI. La primera es la comunicación entre el Arduino Uno como maestro y un Arduino Mega como esclavo. En el segundo ejemplo, estamos estableciendo una comunicación SPI entre un ESP8266 NodeMCU como maestro y un Arduino Uno como esclavo.

Ejemplos prácticos de comunicación SPI

Comunicación SPI: Arduino Uno a Arduino Mega

Queremos comunicarnos a través de SPI entre un Arduino Uno como maestro y un Arduino Mega como esclavo. La siguiente imagen muestra el cableado. También encontrará los pines utilizados en la tabla de descripción general de pines en los artículos especiales para Arduino Uno y Arduino Mega.

Arduino Uno 2 Mega

En la siguiente parte, avanzamos paso a paso por el guión del programa.

Script para dispositivo maestro: Arduino Uno

#include "SPI.h"

void setup() {
   digitalWrite(SS, HIGH); // disable Slave Select
   SPI.begin();
   SPI.setClockDivider(SPI_CLOCK_DIV4);//divide the clock by 4
}
 
void loop() {
   char c;
   digitalWrite(SS, LOW); // enable Slave Select
   for (const char * p = "Hello Megar" ; c = *p; p++) 
   {
      SPI.transfer(c);
   }
   digitalWrite(SS, HIGH); // disable Slave Select
   delay(2000);
}

Primero necesitamos incluir la biblioteca SPI para nuestro ejemplo. En la función de configuración, primero deshabilitamos el pin de selección de esclavo tirando de la línea SS HIGH. A continuación, inicializamos la comunicación SPI con la función SPI.begin. La última parte de la función de configuración es opcional. Dividimos el reloj por 4 para reducir la tasa SPI de 16 MHz a 16/4 = 4 MHz.

La función de bucle comienza definiendo una variable de carácter cy activa la línea de selección esclava arrastrando la línea LOW. Queremos enviar la cadena «Hello Mega r» y usar r como bandera para indicar al dispositivo esclavo que la transferencia de caracteres se ha completado. Por lo tanto, la cadena se divide en sus letras en el bucle for y se transfiere a través de SPI. Cuando se completa la transmisión, el pin selector de esclavo se desactiva y esperamos 2 segundos hasta que volvamos a enviar el mensaje del maestro al esclavo.

Ahora puede descargar el script Arduino Uno como maestro en el microcontrolador.

Script para dispositivo esclavo: Arduino Mega

#include "SPI.h"
char buff [50];
volatile byte indx;
volatile boolean process;

void setup (void) {
   Serial.begin (9600);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt
}

ISR (SPI_STC_vect) // SPI interrupt routine 
{ 
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == 'r') //check for the end of the word
      process = true;
   }
}

void loop (void) {
   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }
}

El script esclavo también comienza con la inclusión de la biblioteca SPI. También necesitamos definir 3 variables. Las variables de mejora almacenan los valores entrantes a través de SPI. La variable indx almacena el índice de 8 bits y la variable de proceso almacena el estado actual de la transmisión.

En la función de configuración, la velocidad en baudios se establece en 9600 para mostrar la salida SPI en el monitor en serie. El pin MISO se define como una salida para recibir datos del maestro. El SPI se configura en modo esclavo y ambas variables se configuran con sus valores predeterminados. Las interrupciones también están habilitadas para la comunicación SPI.

Después de la función de configuración, se define la rutina de interrupción SPI. Primero, los datos SPI se leen del registro de datos interno y se almacenan en forma binaria. Hasta que el búfer esté completamente lleno con 50 caracteres, bit a bit se almacena en el búfer desde el registro de datos SPI hasta que se encuentre la bandera » r» para el final del carácter. Si el mensaje se transmite por completo, la variable de proceso se establece en VERDADERO.

La función de bucle espera a que la variable de proceso sea VERDADERA, luego primero restablece la variable e imprime el búfer completo en el monitor en serie. La última parte es restablecer el índice del búfer para llenar el búfer desde el principio.

La siguiente imagen muestra la salida serial del Arduino Mega como esclavo. La palabra «Hello Mega» se transfiere a través de SPI.

Monitor Arduino Uno 2 Mega Serial

Comunicación SPI: ESP8266 NodeMCU a Arduino Uno

Este segundo ejemplo usa el ESP8266 como maestro porque para el script esclavo, vimos en el primer ejemplo que la función del IRS (spi_stc_vect) se usa porque SPI.attachInterrupt (); La instrucción activa la interrupción. Desafortunadamente, la biblioteca SPI ESP8266 no tiene un método attachInterrupt () y, por lo tanto, no es fácil acceder al registro de datos SPI para NodeMCU. Por lo tanto, no estoy usando ESP8266 NodeMCU como dispositivo esclavo.

La siguiente imagen muestra la conexión entre el ESP8266 NodeMCU y el Arduino Uno.

SPI NodeMCU 2 Arduino Uno

No hay ningún problema para conectar Arduino y NodeMCU directamente aunque el voltaje de funcionamiento para Arduino es de 5V y para NodeMCU es de 3.3V porque los pines digitales de NodeMCU son tolerantes a 5V y están protegidos contra sobretensiones.

El código del programa no depende del microcontrolador específico, por lo que puede usar el script maestro y esclavo del ejemplo anterior. Pero quiero mostrarles un ejemplo muy breve del script maestro del microcontrolador ESP8266.

#include "SPI.h"
char buff[]="Hello Slave\n";

void setup() {
 SPI.begin();
}

void loop() {
 for(int i=0; i<sizeof buff; i++)
 {
  SPI.transfer(buff[i]);
 }
 delay(1000);  
}

Al principio incluimos la biblioteca SPI y la matriz de caracteres que contiene los caracteres que queremos transferir al dispositivo esclavo. En la función de configuración, solo inicializamos la comunicación SPI. En la función de bucle, transferimos la matriz de caracteres letra por letra a través de SPI, luego esperamos 1 segundo. Este es el script maestro más corto que puede crear y usa solo la configuración predeterminada para la comunicación. SPI.

Para el script esclavo estamos usando lo mismo que para Arduino Mega.

La siguiente imagen muestra la salida en serie para el ejemplo de comunicación SPI entre NodeMCU y Arduino Uno.

Monitor serial Arduino Uno NodeMCU 2

Visualice y decodifique la comunicación SPI con un osciloscopio

También es posible que falle la comunicación SPI. En este caso, es muy útil saber si la comunicación SPI en la línea MOSI que es la salida del maestro es correcta o no. La mayoría de los osciloscopios tienen la función de decodificar protocolos de comunicación como SPI. Tengo un osciloscopio USB de 2 canales que está vinculado en la parte superior de este artículo en la lista de piezas.

Decodifiqué el primer ejemplo en el que enviamos «Hello Mega» del Arduino Uno al Arduino Mega. Solo conecto la señal MISO y Clock a un canal de mi osciloscopio cada uno. En la siguiente imagen se ve la señal decodificada mostrando que la salida de Arduino Uno es correcta, enviando «Hola Mega».

Haga clic en la imagen para ampliar.

Osciloscopio SPI

Conclusión

En este tutorial, primero comparamos el protocolo de comunicación SPI con I2C y UART. También discutimos la configuración de SPI y cómo se transmiten los datos entre diferentes dispositivos. Al final de este artículo, analizamos dos ejemplos y cómo se puede decodificar y depurar la comunicación SPI con un osciloscopio.
Si tiene alguna pregunta sobre la comunicación SPI, utilice la sección de comentarios a continuación para hacer sus preguntas. Les responderé lo antes posible.

Diagnóstico del Bus SPI con Osciloscopio: Análisis de Modos, Tiempos y Decodificación

Al no disponer de mecanismo de confirmación automática (ACK) como el bus I2C, un fallo de configuración en el bus SPI puede pasar totalmente desapercibido para el software: el microcontrolador seguirá ejecutando su programa leyendo valores corruptos como 0x00 o 0xFF. El osciloscopio digital de 4 canales es la herramienta definitiva para comprobar en laboratorio la integridad eléctrica y lógica de la comunicación.

1. Necesidad de 4 canales para análisis completo de SPI

El bus SPI es un protocolo de 4 hilos (CS, SCK, MOSI y MISO). Un osciloscopio convencional de 2 canales únicamente permite monitorizar el reloj y una línea de datos, perdiendo la referencia de habilitación del chip (CS). Con 4 canales analógicos es posible:

  • Canal 1 (CH1): Chip Select (CS/SS), señal de habilitación del esclavo y fuente de disparo principal.
  • Canal 2 (CH2): Reloj serie (SCK), base temporal para medir frecuencia y ciclo de trabajo.
  • Canal 3 (CH3): Master Out Slave In (MOSI), comandos y datos transmitidos desde el maestro.
  • Canal 4 (CH4): Master In Slave Out (MISO), respuesta inmediata devuelta por el periférico esclavo.

2. Configuración del disparo (Trigger) en la línea Chip Select

  • Tipo de disparo: Configura el trigger en Flanco de bajada (Falling Edge) asignado al Canal 1 (CS). Dado que la inmensa mayoría de dispositivos SPI tienen lógica activa en nivel BAJO, la transición de ALTO a BAJO marca exactamente el inicio de la trama de transmisión.
  • Modo de disparo: Utiliza el modo Normal o Single (disparo único) para capturar ráfagas esporádicas sin que la pantalla se refresque continuamente en reposo.
  • Base de tiempos: Para un reloj SPI de 4 MHz (período de 250 ns), ajusta la escala horizontal entre 1 μs/div y 5 μs/div para visualizar de 4 a 16 bytes consecutivos en una sola pantalla.

3. Verificación de los 4 Modos SPI (CPOL y CPHA) con el reloj

Uno de los errores más frecuentes en programación es configurar un modo SPI incorrecto en SPISettings. El osciloscopio permite diagnosticarlo al instante observando el reloj (SCK) con respecto a CS:

  • Polaridad (CPOL): Si antes del flanco de bajada de CS la línea SCK se encuentra en nivel bajo, el modo tiene CPOL=0. Si SCK descansa en nivel alto (+3,3 V o +5 V) mientras CS está inactivo, se trata de CPOL=1.
  • Fase (CPHA): Comprueba si los bits en MOSI cambian de estado en el primer flanco de reloj (CPHA=0) o en el segundo flanco (CPHA=1). Si el modo no coincide exactamente con el datasheet del sensor, los datos se desplazarán un bit a la izquierda o derecha corrompiendo la lectura.

4. Decodificación digital serie de tramas SPI en pantalla

Los osciloscopios de sobremesa modernos integran decodificadores de protocolo por hardware. Al habilitar la decodificación SPI e introducir los 4 canales, el instrumento muestra los paquetes transmitidos en hexadecimal o ASCII debajo de las ondas analógicas, permitiendo auditar la respuesta del periférico en tiempo real:

Modelo Ancho de Banda Canales Analógicos Tasa de Muestreo Profundidad de Memoria Decodificación Serie
Rigol DS1054Z 50 MHz (ampliable a 100 MHz) 4 canales independientes 1 GSa/s 24 Mpts SPI, I2C, UART (Trigger y Decode integrado)
Siglent SDS1104X-E 100 MHz 4 canales independientes 1 GSa/s 14 Mpts SPI, I2C, UART, CAN, LIN por hardware
Hantek DSO2D10 100 MHz 2 canales + AWG 1 GSa/s 8 Mpts Decodificación SPI, I2C y UART en pantalla
FNIRSI 1014D 100 MHz (efectivo ~30 MHz) 2 canales + AWG 1 GSa/s (compartido) 240 Kpts Sin decodificación serie (solo análisis analógico)

Para depurar buses SPI de 4 hilos en proyectos con microcontroladores, el Rigol DS1054Z es la referencia indispensable por ofrecer 4 canales analógicos reales a un coste accesible:

Preguntas frecuentes sobre el protocolo SPI

¿Cómo conectar dos módulos SPI distintos (por ejemplo un lector SD y una pantalla TFT) al mismo Arduino?

Ambos módulos deben compartir en paralelo las tres líneas comunes del bus (SCK, MOSI y MISO), pero cada uno debe tener su pin CS (Chip Select) conectado a un pin digital independiente del Arduino (p. ej. D10 para la tarjeta SD y D8 para la pantalla). En el código, el microcontrolador pondrá en nivel LOW únicamente el CS del dispositivo con el que desea comunicarse en ese instante, manteniendo el otro en HIGH (deshabilitado).

¿Por qué el lector de tarjetas micro-SD bloquea a otros sensores en el mismo bus SPI?

Muchos módulos genéricos baratos de tarjetas SD para Arduino integran reguladores y conversores de nivel resistivos o chips buffer sin control de alta impedancia (tri-state). En estos módulos defectuosos, la salida MISO continúa excitando la línea activamente incluso cuando su pin CS está en nivel HIGH, impidiendo que cualquier otro esclavo envíe datos al maestro. La solución definitiva consiste en utilizar lectores con chip buffer tri-state (como el 74LVC125) o intercalar una puerta lógica tri-state en la línea MISO controlada por la señal CS de la SD.

¿Cuál es la distancia máxima recomendada para cables en un bus SPI?

SPI no fue diseñado para comunicaciones a larga distancia, sino para interconexión dentro de la misma placa de circuito impreso (PCB). Debido a sus flancos de conmutación ultrarrápidos (push-pull activo sin resistencias pull-up lentas), los cables planos o jumpers de protoboard no deben superar los 15 a 20 cm a velocidades estándar (4 a 10 MHz). Si necesitas alcanzar distancias de varios metros, es imprescindible reducir la frecuencia de reloj a menos de 500 kHz o utilizar transceptores diferenciales como RS-485/LVDS.

Deja un comentario