Bus SPI

Ya hemos visto la comunicación serie asíncrona el la comunicación serie con la UART, donde para sincronizar se debe usar la misma frecuencia de reloj en ambos extremos y se añade un par de bits extra a la comunicación en forma de un bit de Start y otro de Stop. (Para enviar 8 bits de datos tenemos que enviar 10 bits).

El SPI es un protocolo de comunicación  síncrona de 4 hilos, entre dispositivos electrónicos presentado por Motorola, ahora Freescale, http://www.freescale.com/ en 1982, que ha ganado bastante aceptación en la industria como sistema de comunicación de muy corta distancia, normalmente dentro la placa de circuito impreso. Es un protocolo de transmisión que permite alcanzar velocidades muy altas y que se diseñó pensando en comunicar un microcontrolador con distintos periféricos y que funciona a full dúplex.

SPI utiliza una solución síncrona, porque utiliza unas líneas diferentes para los datos y el Clock. El Clock es una señal que indica al que escucha exactamente cuándo leer las líneas de datos, con lo que el problema de pérdida de sincronía se elimina de raíz.

Uno de los motivos por los que SPI es tan popular es que el hardware de recepción puede ser un sencillo Shift register, lo que es una solución mucho más simple y barata que una UART (Universal Asíncronous Receiver Transmitter o  sistema universal asíncrono de recepción y transmisión serie) de comunicación serie.

El Bus SPI (del inglés Serial Peripheral Interface) es un estándar de comunicaciones, usado principalmente para la transferencia de información entre circuitos integrados en equipos electrónicos. El bus de interfaz de periféricos serie o bus SPI es un estándar para controlar casi cualquier dispositivo electrónico digital que acepte un flujo de bits serie regulado por un reloj (comunicación sincrónica).

El bus SPI incluye una línea de reloj, dato entrante, dato saliente y un pin de chip select, que conecta o desconecta la operación del dispositivo con el que uno desea comunicarse. De esta forma, este estándar permite multiplexar las líneas de reloj.

Muchos sistemas digitales tienen periféricos que necesitan existir pero no ser rápidos. La ventajas de un bus serie es que minimiza el número de conductores, pines y el tamaño del circuito integrado. Esto reduce el coste de fabricar montar y probar la electrónica. Un bus de periféricos serie es la opción más flexible cuando se tiene tipos diferentes de periféricos serie. El hardware consiste en señales de reloj, data in, data out y chip select para cada circuito integrado que tiene que ser controlado. Casi cualquier dispositivo digital puede ser controlado con esta combinación de señales. Los dispositivos se diferencian en un número predecible de formas. Unos leen el dato cuando el reloj sube otros cuando el reloj baja. Algunos lo leen en el flanco de subida del reloj y otros en el flanco de bajada. Escribir es casi siempre en la dirección opuesta de la dirección de movimiento del reloj.

Más información en:

El bus SPI se define mediante 4 pines:

  • SCLK o SCK : Señal de reloj del bus. Esta señal rige la velocidad a la que se transmite cada bit.
  • MISO(Master Input Slave Output): Es la señal de entrada a nuestro dispositivo, por aquí se reciben los datos desde el otro integrado.
  • MOSI(Master Output Slave Input): Transmisión de datos hacia el otro integrado.
  • SS o CS: Chip Select o Slave Select, habilita el integrado hacia el que se envían los datos. Esta señal es opcional y en algunos casos no se usa.

El funcionamiento para un envío de un Master es el siguiente:

  • Se habilita el chip al que hay que enviar la información mediante el CS (Opcional).
  • Se carga en el buffer de salida el byte a enviar.
  • La línea de Clock empieza a generar la señal cuadrada donde normalmente por cada flanco de bajada se pone un bit en MOSI.
  • El receptor normalmente en cada flanco de subida captura el bit de la linea MISO y lo incorpora en el buffer.

Se repite el proceso 8 veces y se ha transmitido un byte. Si se ha terminado de transmitir se vuelve a poner la linea CS en reposo. Hay que tener en cuenta que a la vez que el Master está enviando un dato también lo recibe así que si el Slave ha depositado algún byte en el buffer de salida, este también será enviado y recibido por el Master, comunicación full-duplex.

La señal de reloj es generada por el master y la línea SS normalmente se mantiene HIGH y se activa con LOW, lo que despierta al esclavo seleccionado. Cuando se termina la transferencia la línea se levanta a HIGH y el esclavo se desactiva.

A diferencia de otros buses el SPI no implementa el nivel del enlace entre dispositivos, es decir no hay un campo para la dirección ni un campo para ACK, etc. El SPI se comporta como un shift register donde a cada golpe de clock se captura un bit. En parte no es necesaria hacer un direccionamiento de los chips ya que mediante la señal Chip select, habilitamos al integrado al que queremos enviar los datos.

Ventajas de SPI sobre I2C.

  • I2C No es Full-Duplex por lo que no permite envíos y recepciones al mismo tiempo.
  • I2C un poco más complejo que SPI.
  • I2C no tiene control de errores, por ejemplo mediante paridad etc. Aunque se puede realizar por Software.
  • Velocidades de comunicación relativamente elevadas. En el caso de Arduino de hasta 8 Mhz.
  • Completo control sobre la trama de bits al no exigir direccionamiento ni ACK.
  • Se requiere un hardware sencillo (Barato)
  • Requiere un menor consumo y menor electrónica de conexión que el I2C
  • Como el Clock lo proporciona el master, los esclavos no necesitan osciladores (más barato)

Desventajas de SPI:

  • No hay control del flujo por hardware.
  • Las comunicaciones tiene que estar perfectamente establecidas de antemano. No puedes enviar mensajes de diferentes longitudes cuando convenga.
  • No hay confirmación de la recepción como ocurre en I2C con el ACK. Es decir no sabemos si el mensaje a llegado al destino.
  • Usa más pines que otros buses, ya que necesita uno por cada esclavo. Eso implica que no hay direccionamiento en la propia trama. A menos que se diseñe por software.
  • Funcionamiento a distancias cortas
  • Master único y casi sin posibilidad de master múltiple

Tanto el bus SPI como el I2C son llamados buses de tarjeta, es decir están pensados para trabajar a distancias pequeñas del entorno de una tarjeta, en caso de necesitar un bus serie a larga distancia hay que ir a buses de campo como RS485, CAN, etc…

El canal SPI fue diseñado para aplicaciones de transmisión de datos a velocidades altas (10 Mbps) y distancias cortas, del orden de 10 a 20 cms, ó bien dentro de un mismo PCB (circuito impreso), entre 2 circuitos integrados como podrían ser un  microcontrolador y otro dispositivo, por ejemplo, un circuito integrado con la función RFID. Las señales de transmisión de datos y control del canal SPI, usan niveles de voltaje TTL ó bien 3.3 volts, dependiendo de la tecnología de fabricación del dispositivo.

Más información en:

La mayoría de los microcontroladores modernos tienen soporte HW para SPI, así como las placas BeagleBoard y Raspberry Pi.

El estándar SPI es un estándar de facto, es decir, no ha sido consensuado ni legitimado por un organismo de estandarización al efecto. Por el contrario, se trata de una norma generalmente aceptada y ampliamente utilizada por iniciativa propia de un gran número de interesados. Por lo tanto cada fabricante puede implementar de forma diferente el SPI y debemos prestar atención al datasheet del dispositivo.

Estandar SPI: http://www.st.com/st-web-ui/static/active/en/resource/technical/document/technical_note/DM00054618.pdf

SPI block Guide: http://www.nxp.com/files/microcontrollers/doc/ref_manual/S12SPIV4.pdf

Cuando el número de esclavos crece suele ser más frecuente conectarlos en cascada, con el MISO de uno (Salida), conectado al MOSI (Entrada) del siguiente. En este caso solo usamos una única línea SS, que se comparte entre todos los esclavos.

Esta configuración es típica de una situación en la que le master envía datos pero no recibe nada de vuelta, como en el caso de una cadena de múltiples display LEDs (Matrices de 8×8), en los que se envía información para ser mostrada pero, no hay datos de vuelta. En este caso incluso podemos desconectar la línea MISO.

Una vez que todos los datos son enviados la línea SS es activada y todos los chips son activados simultáneamente.

SPI en daisy-chaining: http://www.maximintegrated.com/en/app-notes/index.mvp/id/3947

SPI en Arduino

Arduino soporta de serie el bus SPI, con una librería estándar se llama SPI que está incluida en el IDE de Arduino y que gestiona todas las complicaciones y el arbitraje del protocolo.

Para usar el bus SPI en Arduino, se usa la librería: http://arduino.cc/en/Reference/SPI

En un primer paso importamos la librería del SPI con #include <SPI.h>. En el setup hay que iniciar y configurar el SPI con SPI.begin() y además hay que definir el pin SS como salida.

Finalmente mediante la función SPI.transfer enviamos el byte que queremos.

Métodos SPI:

  • begin() — Inicializa el bus SPI
  • end() — Deshabilita el bus SPI.
  • setBitOrder() — Configura el orden de los bits enviados como el menos significativo primero o el más significativo primero.
  • setClockDivider() — Configura del divisor de reloj en el bus SPI. ES decir configura la velocidad del bus.
  • setDataMode() — Configura el modo de dato del bus SPI, es decir, polaridad y fase del reloj.
  • transfer() — Transfiere un byte sobre el bus SPI, tanto de envío como de recepción.
  • SPI settings: https://www.arduino.cc/en/Reference/SPISettings

Para controlar el bus SPI es necesario usar esos unos pines inexcusablemente, aunque podemos elegir entre dos juegos de ellos, entre ciertos pines digitales, según el modelo y la tabla que especificamos abajo, y usando los equivalentes en el bus ICSP. La siguiente tabla muestra que pines corresponden a los líneas SPI en cada Arduino:

Arduino / Genuino Board MOSI MISO SCK SS (slave) SS (master) Level
Uno or Duemilanove 11 or ICSP-4 12 or ICSP-1 13 or ICSP-3 10 5V
Mega1280 or Mega2560 51 or ICSP-4 50 or ICSP-1 52 or ICSP-3 53 5V
Leonardo ICSP-4 ICSP-1 ICSP-3 5V
Due ICSP-4 ICSP-1 ICSP-3 4, 10, 52 3,3V
Zero ICSP-4 ICSP-1 ICSP-3 3,3V
101 11 or ICSP-4 12 or ICSP-1 13 or ICSP-3 10 10 3,3V
MKR1000 8 10 9 3,3V

Los pines ICSP son los pines del conector ICSP de Arduino que tienen la siguiente disposición:

Todas las placas con microcontroladores AVR tienen un pin SS que se usa cuando actúa como esclavo. Dado que esta librería solo soporta el estado maestro, este pin debe ponerse siempre como output, sino el interfaz SPI podría ponerse como esclavo. Sin embargo, es posible usar el pin SS para dispositivos, por ejemplo el pin 4 y 10 son usados para controlar las conexiones de la Ethernet Shield.

En el Arduino Due, el interfaz SPI funciona diferente al resto de Arduinos. Este tiene 3 pines para dispositivos SS. Uso extendido de la librería SPI en Due: http://arduino.cc/en/Reference/DueExtendedSPI

Para microcontroladores “Microchip PIC” y “ARM-based” podemos tener varios modos de funcionamiento:

SPI Mode Clock Polarity

(CPOL/CKP)

Clock Edge

(CKE/NCPHA)

0 0 1
1 0 0
2 1 0
3 1 1

Uso del bus SPI: https://www.pjrc.com/teensy/td_libs_SPI.html

Un magnífico ejemplo de como usar el bus SPI en los microcontroladores AVR y uso con registros de desplazamiento: http://www.ermicro.com/blog/?p=1050

Más información:

Registros Arduino para SPI

Internamente el microcontrolador ATmega328p tiene un bus SPI que puede trabajar como master o slave. Para manejar internamente este bus, se hace uso de una serie de registros.

En la página 215 de http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_datasheet.pdf puede verse el funcionamiento del bus SPI en el microcontrolador.

Características del bus SPI en Arduino:

  • Full-duplex, Three-wire Synchronous Data Transfer
  • Master or Slave Operation
  • LSB First or MSB First Data Transfer
  • Seven Programmable Bit Rates
  • End of Transmission Interrupt Flag
  • Write Collision Flag Protection
  • Wake-up from Idle Mode
  • Double Speed (CK/2) Master SPI Mode

Diagrama de bloques:

spi-block-diagram

Los microcontroladores AVR tienen los siguientes tres registros para manejar SPI:

  • SPCR – SPI Control Register – This register is basically the master register i.e. it contains the bits to initialize SPI and control it.

  • SPSR – SPI Status Register – This is the status register. This register is used to read the status of the bus lines.

  • SPDR – SPI Data Register – The SPI Data Register is the read/write register where the actual data transfer takes place.

Los 4 modos disponibles de funcionamiento de SPI son:

Velocidad del bus SPI:

De una forma más detallada, el funcionamiento es de la siguiente forma: el SPI Master (servidor) inicializa el ciclo de comunicación cuando se coloca en bajo el Selector de Esclavo (SS-Selector Slave)(cliente). Master y Slave(servidor y cliente) preparan los datos a ser enviados en sus respectivos registros de desplazamiento y el Master genera el pulso del reloj en el pin SCK para el intercambio de datos. Los datos son siempre intercambiados desde el Maestro al Esclavo en MasterOut-SlaveIn, MOSI, y desde Esclavo al Maestro en MasterIn-SlaveOut, MISO. Después de cada paquete de datos el Maestro debe sincronizar el esclavo llevando a ‘alto’ el selector de Esclavo, SS.

Cuando se configure como Maestro, la interfaz SPI no tendrá un control automático de la línea SS. Este debe ser manejado por software antes de que la comunicación pueda empezar, cuando esto es realizado, escribiendo un byte en el registro de la SPI comienza el reloj de la SPI, y el hardware cambia los 8 bits dentro del Esclavo. Después de cambiar un Byte, el reloj del SPI para, habilitando el fin de la transmisión (SPIF). Si la interrupción del SPI está habilitado (SPIE) en el registro SPCR, una interrupción es requerida. El Master podría continuar al cambio del siguiente byte escribiendo dentro del SPDR, o señalizar el fin del paquete colocando en alto el Esclavo seleccionado, línea SS. El último byte llegado se mantendrá en el registro Buffer para luego usarse.

Cuando lo configuramos como un Esclavo, la interfaz SPI permanecerá durmiendo con MISO en tres-estados siempre y cuando el pin SS esté deshabilitado. En este estado, por el software se podría actualizar el contenido del registro SPDR, pero los datos no serán desplazados por la llegada del pulso de reloj en el pin SCK hasta que el pin SS no sea habilitado( ‘0’ ). Será visto como un byte completamente desplazado en el fin de la transmisión cuando SPIF se habilite. Si la interrupción SPI, SPIE en SPCR, está habilitada, una interrupción es solicitada. El Esclavo podría continuar para colocar nuevos datos para ser enviados dentro del SPDR antes de seguir leyendo la data que va llegando. El último byte que entra permanecerá en el buffer para luego usarse.

Más información:

Dispositivos SPI

Los dispositivos SPI se comunican entre sí utilizando un bus de 4 señales (MOSI, MISO, SCK, SS) y un esquema maestro/esclavo, en el cual el maestro inicia el protocolo de trasmisión de los datos. En ocasiones, las interfaces SPI son circuitos que están ya disponibles como parte del hardware en los microcontroladores como por ejemplo el 18F2550 (Microchip) ó Atmega8 (Atmel-AVR) ó bien en dispositivos como módulos lectores RFID, tarjetas de memoria, convertidores A/D, etc.

Diferentes tipos de periféricos con SPI: http://www.mct.net/faq/spi.html

Aplicaciones SPI : http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Applications

Varios dispositivos con interfaz SPI: https://www.sparkfun.com/search/results?term=spi

Veamos varios ejemplo de dispositivos SPI:

Adaptadores

También disponemos de adaptadores o bridges de SPI a otros puertos.Por ejemplo de USB a SPI: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Host_adapters

Conversor de USB a SPI: http://www.maximintegrated.com/en/products/interface/controllers-expanders/MAX3421E.html

Otro conversor SPI a USB: https://www.sparkfun.com/products/9235

SPI to serial (UART):

SPI to I2C:

ISP (In Sytem Programming)

Recordar que el conector ICSP se usa  para hacer la programación del microcontrolador y que comparte los pines. In system programming:

Por ejemplo un ISP: http://www.pololu.com/product/1300. Lleva este PIC http://ww1.microchip.com/downloads/en/DeviceDoc/41350E.pdf con un firmware para realizar esta función.

Y podemos programar un microcontrolador por el conector ICSP:

Ejercicios SPI Arduino

Ejemplos de uso de SPI:

Ejercicio34-SPI: Comunicar dos arduinos por SPI.

Cómo hacerlo:

Solución: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio36-ArduinoISP

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s