5/1/2013

Interfaces de comunicación SPI, I2C, UART...

Para alguien que comienza a utilizar Arduino puede resultar algo complejo entender las diferencias entre los diferentes tipos de interfaces de comunicación (y protocolos asociados). Existe mucha información relativa a cada protocolo, pero entender la relación que existe entre ellos quizá no sea trivial. Es por esto que me parece adecuado resaltar unos comentarios que he leído en un foro. El enlace podéis encontrarlo aquí. Esta vez me voy a tomar la molestia de traducirlo (algo resumido), ya que se encuentra en inglés.
capcom pregunta: Como aficionado novel a la electrónica, he oído los términos USART, UART, RS232, USB, SPI, I2C, TTL, etc. Entiendo que están basados en comunicación entre dispositivos, ordenadores, periféricos, etc. Tengo conocimientos básicos sobre cómo trabajan, pero tengo dificultad entendiendo cómo están relacionados. Por ejemplo, ¿es UART un subconjunto de USART? ¿Cuál es la diferencia entre RS232 y Serial?
Pregunta a la cuál, un tal stevenh, que en mi opinión parece bastante entendido en la materia, responde:
Serial es la palabra clave de todo lo que es "multiplexación de la división temporal". Indica que el dato es enviado en función del tiempo, un bit detrás de otro. Todos los protocolos que has nombrado son protocolos serie. 
UART (recepción-transmisión asíncrona universal) es uno de los protocolos serie más utilizados. La mayoría de los controladores disponen de hardware UART. Usa una línea de datos simple para transmitir y otra para recibir datos. Comúnmente, 8 bits de datos son transmitidos de la siguiente forma: un bit de inicio, a nivel bajo, 8 bits de datos y un bit de parada a nivel alto. El bit de inicio a nivel bajo y el de parada a nivel alto indican que siempre hay una transmisión de alto a bajo para iniciar la transmisión. Eso es lo que describe a UART. Puedes utilizarlo a 3.3V ó 5V, dependiendo de lo que tu microcontrolador use. Note que los microcontroladores que quieren comunicarse via UART tienen que fijar la velocidad de transmisión, la tasa de bits, ya que sólo disponen del bit de flanco de bajada para sincronizar. Esto es llamado comunicación asíncrona.
Para largas distancias de comunicación, utilizar 5V en UART no es fiable, por lo que es convertido a un voltaje más alto de +12V para un 0 lógico y -12V para un 1. El formato de datos se conserva. Es entonces cuando tienes RS-232.
La dependencia de la coordinación es uno de los puntos negros de UART, y la solución es USART (recepción-transmisión síncrona/asíncrona universal). Puede actuar igual que UART, pero también como un protocolo síncrono. Sincronización de datos, pero también del reloj. En cada pulso de reloj se indica al receptor que capte el bit. Los protocolos sincronizados, por contra, necesitan un mayor ancho de banda, como en el caso de Manchester encoding, o de una conexión extra para el reloj, como es el caso de SPI o I2C.
SPI es otro protocolo serie muy simple. Un maestro envia la señal de reloj, y tras cada pulso de reloj envía un bit al esclavo y recibe un bit de éste. Los nombres de las señales son por tanto SCK para el reloj, MOSI para el Maestro Out Esclavo In, y MISO para Maestro In Esclavo Out. Para controlar más de un esclavo es preciso utilizar SS (selección de esclavo).
I2C es un protocolo síncrono, y es el primero que vemos con algo "inteligente". I2C usa solo 2 cables, uno para el reloj (SCL) y otro para el dato (SDA). Esto significa que el maestro y el esclavo envían datos por el mismo cable, el cuál es controlado por el maestro, que crea la señal de reloj. I2C no utiliza selección de esclavo, sino direccionamiento. El primer byte enviado por el maestro se forma de 7 bits para la dirección (así que permite comunicarse con hasta 127 dispositivos) y un bit de lectura/escritura, indicando si el proximo byte vendrá desde el maestro o el esclavo. Tras cada byte recibido se envía una confirmación con el noveno pulso de reloj. Si el maestro quiere recibir datos solo genera pulsos de reloj. El esclavo tiene que cuidar que el próximo bit esté listo cuando la señal de reloj es dada.
Dos o más señales a través del mismo cable pueden causar conflicto, y ocurrirían problemas si un dispositivo envía un 1 lógico al mismo tiempo que otro envía un 0. Por tanto el bus es "cableado" con dos resistencia para poner el bus a nivel alto, y los dispositivos envían niveles bajos. Si quieren enviar un nivel alto simplemente lo comunican al bus.
TTL no es un protocolo. Es una vieja terminología para lógica digital, pero el nombre es a menudo utilizado para referirse a 5V de alimentación.
Reseñar que el protocolo TWI es I2C. El nombre TWI  es utilizado a veces (en la web de Arduino, por ejemplo), pero significan lo mismo.
Ejemplos de dispositivos que utilizan este protocolo son unos módulos que, conectándolos a un display lcd, permiten controlarlos por comunicación serie, ahorrando considerablemente el número de salida de Arduino necesarias.