¿Qué es este blog?

La idea de este blog nace para compartir los avances que se vayan realizando a lo largo de un estudio sobre cómo interconectar los distintos sensores que se pueden encontrar en el mercado, o fabricar de forma casera, con la plataforma Mindstorms de LEGO. Para ello se hará uso ARDUINO, un entorno de desarrollo abierto basado en microcontrolador.

domingo, 12 de junio de 2011

Arduino y la comunicación SPI


En este epígrafe se va a analizar el protocolo de comunicaciones SPI, y se va a ver de qué manera se puede manejar desde el entorno de desarrollo Arduino. En primer lugar se hará un resumen de cómo funciona dicho protocolo, y a continuación se explicarán las distintas funciones disponibles para poder utilizarlo.

El protocolo SPI
El protocolo SPI proviene de las siglas en inglés “Serial Peripheral Interface”, y es un estándar de comunicaciones usado principalmente en la transferencia de información entre circuitos integrados en circuitos electrónicos. Se trata de un bus serie de datos para la transferencia síncrona y bidireccional de información. En toda comunicación por SPI deberá haber al menos un dispositivo actuando como maestro, y uno o más actuando como esclavos. Para seleccionar a cada uno de los esclavos existe una línea, denominada “slave select” o “chip select”.
Las señales del protocolo SPI son las siguientes:
  • SCLK: Es la señal de reloj, impuesta por el dispositivo maestro.
  • MOSI: Corresponde a las siglas “Master Output – Slave Input”, es decir, el maestro enviará los datos a través de esta línea y el esclavo los recibirá.
  • MISO: Corresponde a las siglas “Master Input – Slave Output”, y es la línea por la que los esclavos enviarán datos al dispositivo maestro.
  • SS: Es la señal de “Slave Select”, es decir, la línea que el maestro activará para indicar al esclavo que se va a establecer la comunicación con él.



Habitualmente, el pin MISO del maestro se conecta con el pin MOSI del esclavo, y viceversa. Además, la señal de selección de esclavo suele ser activa a nivel bajo.
A continuación se va a describir con un poco más de detalles cómo funciona el protocolo:
  • Para iniciar la comunicación, el maestro configura el reloj usando una frecuencia menos o igual a la frecuencia máxima que soporta el esclavo. Estas frecuencias suelen estar en el rango de 1 a 70 MHz.
  • El maestro a continuación pone a nivel bajo la señal “Slave Select” del esclavo para indicarle que se va a comunicar con él. Si es necesario esperar un tiempo antes de iniciar la comunicación (por ejemplo para permitir una conversión analógico / digital), el maestro esperará al menos ese tiempo antes de proseguir con el intercambio de información.
  • Durante cada ciclo de reloj se produce una comunicación en los dos sentidos, ya que por una parte el maestro va a mandar un bit a través del pin MOSI y el esclavo lo va recibir, mientras que a la vez el esclavo va a mandar un bit a través de la línea MISO para que el maestro lo reciba.
  • Cuando ya no quedan datos que transmitir, el maestro deja de accionar la señal de reloj y normalmente vuelve a colocar a nivel alto la señal de “Slave Select” para así deseleccionar al dispositivo.
  • Cualquier dispositivo que no tenga a nivel bajo su señal de selección, ignorará los movimientos que haya en las líneas MISO y MOSI, con lo que podemos tener distintos dispositivos conectados a esas mismas líneas sin que interfieran en la comunicación. Evidentemente, la señal de “Slave Select” sí debe ser propia de cada dispositivo.
  • Además de la frecuencia de reloj, el maestro también puede configurar la polaridad y la fase de la señal de reloj con respecto a los datos. La polaridad se suele denominar usando las siglas CPOL, mientras que la fase se suele denominar como CPHA. En la figura inferior se puede ver un diagrama temporal que explica las distintas combinaciones (o modos) que se describen a continuación:

o   Si CPOL = 0, el valor base de la señal de reloj es el nivel bajo.
§  Si CPHA = 0, los datos se capturan en el flanco de subida de la señal de reloj, y se propagan en el flanco de bajada. Este modo se denomina modo 0.
§  Si CPHA = 1, los datos de capturan en el flanco de bajada de la señal de reloj, y se propagan en el flanco de subida. Este modo se denomina modo 1.
o   Si CPOL = 1, el valor base de la señal de reloj es el nivel alto.
§  Si CPHA = 0, los datos de capturan en el flanco de bajada de la señal de reloj, y se propagan en el flanco de subida. Este modo se denomina modo 2.
§  Si CPHA = 1, los datos se capturan en el flanco de subida de la señal de reloj, y se propagan en el flanco de bajada. Este modo se denomina modo 3.




Figura Diagrama temporal del protocolo SPI

Funciones disponibles en Arduino
La gestión del protocolo SPI en Arduino se realiza a través de la librería SPI. Esta interfaz se inicializa automáticamente cuando la librería SPI se incluye en un código. En el caso de Arduino Mega 2560 usando en las pruebas, los pines se inicializan de la siguiente forma:
  • Pin 50: señal MISO
  • Pin 51: señal MOSI
  • Pin 52: señal SCK
  • Pin 53: Señal SS, aunque se pueden usar otros pines para este fin. Esto puede ser útil por ejemplo en el caso de tener varios dispositivos conectados en un mismo bus.


La configuración por defecto del protocolo SPI en Arduino establece que el esclavo será él mismo, que se van a transferir en primer lugar los bytes más significativos de cada byte (MSB), que  el modo seleccionado es el 0 y se establece la frecuencia de reloj en una cuarta parte de la frecuencia del sistema. Veamos las distintas funciones disponibles para modificar estos parámetros:
  • mode (byte config). Permite modificar el registro de configuración del SPI. Si hay varios dispositivos usando SPI y cada uno necesita un modo distinto, esta función se deberá llamar antes de acceder a cada dispositivo en particular. Veamos dos ejemplos de uso:
    • Spi.mode( (1<<CPOL) | (1<<CPHA) ). Establece el modo 3
    • Spi.mode( (1<<SPR0) ). Configura el reloj SCK a 1/16 la velocidad del reloj del sistema.
  • Byte transfer(byte b). Envía y recibe un byte a través del bus SPI. Por ejemplo:
    • n = Spi.transfer( 0x2A ). Envía el byte 0x2A y devuelve lo que reciba del otro dispositivo.
  • Byte.transfer(byte b, byte delay). Esta función es idéntica a la anterior, sólo que antes de acometer la operación espera un número de microsegundos especificados en el parámetro delay. Es útil cuando hay que esperar un tiempo antes de iniciar una transferencia de datos.






--------------------------------------------
Referencias:


2 comentarios:

  1. y como hago, o que funcion podria utilizar para que el arduino (como esclavo) reciba y envie datos al maestro?

    ResponderEliminar
  2. Puedo modificar la libreria SPI para utilizar otros pines del mega2560 cono puerto SPI

    ResponderEliminar