El protocolo SPI es un protocolo de comunicación serial para equipos periféricos. Su nombre básicamente indica esto: Serial Peripheral Interface o interface serial periférica. Probablemente ya te hayas topado con algún otro protocolo serial, el más común es el que todos llamamos serial y que lo relacionamos con la UART.
Pero entonces ¿qué es diferente en este protocolo? Resulta que es un protocolo de Maestro-Esclavo, diseñado para controlar varios periféricos utilizando un mismo bus de datos. Consta de cuatro líneas de comunicación que son lo que cualquier ingeniero hubiera pensado si le hubieran pedido que diseñara un protocolo en 5 minutos:
- CLK. Clock para el control de las operaciones.
- MISO. Master in, slave out. Bus de entrada de datos
- MOSI. Maste out, slave in. Bus de salida de datos.
- SS. Slave select. Señal de habilitación del esclavo.
Por supuesto, con forme va incrementando el número de esclavos, va incrementando el número de señales de habilitación, pero los otros tres buses se reutilizan, lo que ahorra considerablemente líneas de comunicación. Aquí abajo aparece un diagrama para su mejor comprehensión:

La secuencia de comunicación con el dispositivo es bastante sencilla, en realidad lo único que tienes que hacer como master es habilitar (0 lógico, por trabajar con lógica negativa) el esclavo con el que quieres comunicarte y después empiezas a transmitir o recibir datos, un bit por ciclo de reloj y comenzando por el más significativo (MSB) hasta el menos significativo (LSB). Algo así como lo que muestra el siguiente diagrama:

El protocolo no define por sí mismo el baud rate o velocidad de transmisión, por lo que en teoría podría alcanzar velocidades muy altas. Lo que limita la comunicación es el dispositivo con el cual estás trabajando.
En fin, probablemente no te estemos diciendo más que Wikipedia o cualquier otro sitio, así que para que quede más claro y puedas hasta practicar, te dejamos una rutina hecha en C para un microcontrolador que ejemplifica el protocolo.
Como queremos ejemplificarlo de la forma más sencilla haremos la comunicación con un componente muy sencillo, porque es un ejemplo real. Se trata de un potenciómetro controlado digitalmente por SPI (¡obviamente!). En fin, se trata del MAX5402 el cual solo recibe información por lo que no tendremos que lidiar con la comunicación de regreso. A este componente solo se le envía un byte y con eso tiene para mediar el valor del potenciómetro de 0 a 255.
Pero dejémonos de palabras y vamos a lo que realmente nos interesa, el código:
/*****************************************************************************
SPI routines for MAX5402 Digital Potentiometer.
MCU: Freescale 9S12EXP100
Clk: 2Mhz
Developed by:
Arturo Javier Hernández
javier@quierobits.com
07/02/2011
*****************************************************************************/
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define MOSI PORTA_PA0 /// Master Out Slave In, Port A Pin 0
#define SCLK PORTA_PA1 /// Source Clock, Port A Pin 1
#define SS PORTA_PA2 /// Chip Select, Port A Pin 2
/** MISO uninplemented **/
void main(void) {
EnableInterrupts;
SPI_init();
for(;;) {
asm nop;
send_byte(169);
_FEED_COP();
} /* loop forever */
} /* END OF MAIN */
/** Port initialization **/
void SPI_init(void){
/** Set pins as Output **/
DDRA_DDRA0=0x01;
DDRA_DDRA1=0x01;
DDRA_DDRA2=0x01;
SS=1;
MOSI=0;
SCLK=0;
}
void send_byte(unsigned char rByte){
unsigned char dataToSend;
unsigned char tempCountr;
dataToSend=rByte;
tempCountr=7;
SS=0; /// Alert for slave
do{
MOSI=(dataToSend/128); /// Send from MSB to LSB
SCLK=1; /// Send every clock cycle
dataToSend<<=1;
SCLK=0;
}while(tempCountr--);
SS=1; /// End of transmission
}
Como verán, la rutina que nos interesa es la de send_byte en la que se llevan a cabo los pasos para lograr la comunicación.
Esperamos que con este ejemplo quede más claro cómo implementar un protocolo de comunicación SPI y que les sirva de base para crear rutinas más complejas. Les comparto también el archivo .c descargable por si lo quiere utilizar.
Comunicación SPI.c >>
Las imágenes las tomé de:
Leens, F. (2009) An introduction to I^2C and SPI protocols.
Síguenos en