¿Qué compensaciones debo considerar al decidir usar una interfaz SPI o I2C?
Esta placa de acelerómetro/giroscopio está disponible en dos modelos, uno para cada interfaz. ¿Alguno de los dos sería más fácil de integrar en un proyecto Arduino?
http://www.sparkfun.com/products/11028
Resumen
I2C es un sistema de bus con datos bidireccionales en la línea SDA. SPI es una conexión punto a punto con entrada y salida de datos en líneas separadas (MOSI y MISO).
Esencialmente , SPI consiste en un par de registros de desplazamiento, en los que ingresa datos en un registro de desplazamiento mientras registra datos en el otro. Por lo general, los datos se escriben en bytes al tener cada vez 8 pulsos de reloj en sucesión, pero eso no es un requisito de SPI. También puede tener longitudes de palabra de 16 bits o incluso 13 bits, si lo desea. Mientras que en I2C la sincronización se realiza mediante la secuencia de inicio en SPI, se realiza mediante SS yendo alto (SS está activo bajo). Tú mismo decides después de cuántos pulsos de reloj son. Si usa palabras de 13 bits, el SS bloqueará los últimos bits cronometrados después de 13 pulsos de reloj.
Dado que los datos bidireccionales están en dos líneas separadas, es fácil interactuar.
SPI en modo estándar necesita al menos cuatro líneas: SCLK (reloj en serie), MOSI (Master Out Slave In), MISO (Master In Slave Out) y SS (Slave Select). En modo bidireccional necesita al menos tres líneas: SCLK (reloj serial), MIMO (Master In Master Out) que es una de las líneas MOSI o MISO y SS (Slave Select). En sistemas con más de un esclavo, necesita una línea SS para cada esclavo, de modo que para esclavos que tienes líneas en modo estándar y líneas en modo bidireccional. Si no desea eso, en el modo estándar puede conectar en cadena los esclavos conectando la señal MOSI de un esclavo al MISO del siguiente. Esto ralentizará la comunicación ya que tiene que pasar por todos los datos de los esclavos.
Como dice tcrosley, SPI puede operar a una frecuencia mucho más alta que I2C.
I2C es un poco más complejo. Dado que es un bus, necesita una forma de direccionar los dispositivos. Su comunicación comienza con una secuencia de inicio única: la línea de datos (SDA) se baja mientras el reloj (SCL) está alto, ya que el resto de los datos de comunicación solo pueden cambiar cuando el reloj está bajo. Esta secuencia de inicio sincroniza cada comunicación.
Dado que la comunicación incluye el direccionamiento, solo se requieren dos líneas para cualquier número de dispositivos (hasta 127).
editar
Es obvio que la línea de datos es bidireccional, pero vale la pena señalar que esto también es cierto para la línea del reloj. Los esclavos pueden estirar el reloj para controlar la velocidad del autobús. Esto hace que I2C sea menos conveniente para el cambio de nivel o el almacenamiento en búfer. (Las líneas SPI en modo estándar son todas unidireccionales).
Después de enviar cada byte (dirección o datos), el receptor debe confirmar el recibo colocando un pulso de reconocimiento en SDA. Si su microcontrolador tiene una interfaz I2C, esto se solucionará automáticamente. Todavía puede hacer un bit-bang si su microcontrolador no lo admite, pero tendrá que cambiar el pin de E/S de salida a entrada para cada reconocimiento o lectura de datos, a menos que use un pin de E/S para leer y uno para escribir.
A 400 kHz, I2C estándar es mucho más lento que SPI. Hay dispositivos I2C de alta velocidad que funcionan a 1 MHz, aún mucho más lentos que los 20 MHz SPI.
(editar: para ser claros, muchas de las siguientes preocupaciones tienen que ver con la integridad de la señal causada por el uso de dispositivos I2C/SPI de placa a placa, como señala correctamente Olin).
A menos que tenga restricciones que lo empujen fuertemente hacia menos cables (teníamos un proyecto con un conector sellado herméticamente en el que cada contacto adicional era bastante costoso), evite I2C cuando sea posible y quédese con SPI.
SPI es bastante fácil de manejar sobre una base de hardware y software. En el hardware, hay dos líneas de datos compartidas, Master In Slave Out (MISO o SOMI) y Master Out Slave In (MOSI o SIMO), un reloj compartido generado por el maestro y una selección de chip por dispositivo. La línea CS baja, el reloj cicla y esencialmente cambia los bits de entrada y los bits de salida, hasta que finaliza la transacción, momento en el que la línea CS pasa a nivel alto. Cuando su línea CS es alta, los dispositivos esclavos no se comunican: ignoran las líneas CLK y MOSI y ponen su pin MISO en un estado de alta impedancia para permitir que otra persona lo use.
Si tiene un microcontrolador que utiliza varios dispositivos SPI y tiene un periférico SPI integrado, envíe la salida CS del microcontrolador a un demultiplexor (p. ej., 74HC138) y controle las líneas de dirección para seleccionar el dispositivo entre las transacciones SPI; escribe palabras en un registro para ponerlas en cola para la salida, y las vuelve a leer después de que el pin CS se eleva alto.
Debido a que todas las señales SPI son unidireccionales, pueden almacenarse en búfer, usarse a través de una barrera de aislamiento con aisladores digitales y pueden enviarse de placa a placa utilizando controladores de línea como LVDS. Lo único de lo que debe preocuparse es el retraso de propagación de ida y vuelta, que limitará su frecuencia máxima.
I2C es una historia completamente diferente. Si bien es mucho más simple desde el punto de vista del cableado, con solo dos cables SCL y SDA, ambas líneas son líneas bidireccionales compartidas que usan dispositivos de drenaje abierto con un pullup externo. Hay un protocolo para I2C que comienza transmitiendo una dirección de dispositivo, de modo que se pueden usar varios dispositivos si cada uno tiene su propia dirección.
Desde el punto de vista del hardware, es muy difícil usar I2C en sistemas que tienen un ruido significativo. Para amortiguar o aislar líneas I2C, debe recurrir a circuitos integrados exóticos; sí, existen, pero no hay muchos: usamos un proyecto uno a uno y nos dimos cuenta de que podía usar un aislador, pero no podía use dos en serie: usó pequeñas caídas de voltaje para determinar qué lado era el extremo impulsor de las cosas, y dos caídas en serie eran dos.
Los umbrales de nivel lógico de I2C dependen de Vcc, por lo que debe tener mucho cuidado si usa dispositivos de 3V/3.3V y 5V en el mismo sistema.
Cualquier señal que use un cable de más de un pie o dos debe preocuparse por la capacitancia del cable. La capacitancia de 100 pf/metro no está fuera de lo común para un cable multiconductor. Esto hace que tenga que reducir la velocidad del bus o usar resistencias pull-up más bajas para poder manejar la capacitancia adicional correctamente y cumplir con los requisitos de tiempo de subida.
Entonces, digamos que tiene un sistema que cree que ha diseñado bien, y puede manejar la mayoría de los problemas de integridad de la señal, y el ruido es raro (pero aún está presente). ¿De qué tienes que preocuparte?
Hay un montón de condiciones de error que debe estar preparado para manejar:
El dispositivo esclavo no reconoce un byte en particular. Tienes que detectar esto y detener y reiniciar la secuencia de comunicaciones. (Con SPI, generalmente puede volver a leer los datos que envía si desea asegurarse de que se recibieron sin errores).
Estás leyendo un byte de datos de un dispositivo esclavo y el dispositivo está "hipnotizado" debido al ruido en la línea del reloj: has enviado los 8 relojes necesarios para leer ese byte, pero debido al ruido, el dispositivo esclavo lo piensa. ha recibido 7 relojes y todavía está transmitiendo un 0 en la línea de datos. Si el dispositivo hubiera recibido el octavo reloj, habría liberado la línea de datos alta para que el maestro pudiera subir o bajar la línea de datos para transmitir un bit ACK o NACK, o el maestro podría transmitir una condición de parada (P). Pero el esclavo aún mantiene baja la línea de datos, esperando en vano otro reloj. Si un maestro no está preparado para probar relojes adicionales, el bus I2C quedará bloqueado. Si bien he usado varios microcontroladores que manejan las condiciones normales de ACK/NACK,
El caso realmente terrible es cuando un maestro está escribiendo datos en un dispositivo esclavo y otro esclavo interpreta la dirección del dispositivo incorrectamente y piensa que los datos transmitidos son para él. Hemos tenido dispositivos I2C (expansores de E/S) que ocasionalmente tienen registros configurados incorrectamente debido a esto. Es casi imposible detectar este caso, y para ser resistente al ruido, debe configurar periódicamente todos los registros, de modo que si se encuentra con este error, al menos se solucionará después de un breve período de tiempo. (SPI nunca tiene este problema: si tiene una falla en la línea CS, nunca persistirá por mucho tiempo y no obtendrá datos leídos accidentalmente por el dispositivo esclavo incorrecto).
Muchas de estas condiciones podrían manejarse correctamente en el protocolo si hubiera detección de errores (códigos CRC), pero pocos dispositivos tienen esto.
Encuentro que tengo que construir un software complejo en mi dispositivo maestro I2C para manejar estas condiciones. En mi opinión, simplemente no vale la pena a menos que las limitaciones del cableado nos obliguen a usar I2C y no SPI.
La placa de conexión para dispositivos en SparkFun es en realidad solo para la versión I2C (MPU-6500). La versión MPU-6000 tiene interfaces SPI e I2C en el mismo chip, y no veo que SparkFun tenga una placa con ese chip. Así que creo que está limitado a usar I2C si quiere usar esa placa en particular. Pero iba a recomendar usar I2C de todos modos en su situación por las siguientes razones.
En general, encontrará que el bus I2C es más fácil de usar desde el punto de vista del hardware que el bus SPI. I2C es un bus de 2 hilos (SCL/SDA):
SCL – Serial clock.
SDA – Serial data (bidirectional).
SPI es un bus de 4 hilos (SCLK/MOSI/MISO/CS):
SCLK– Serial clock.
MOSI – Master-out, Slave-in. Data from the CPU to the peripheral.
MISO – Master-in, Slave out. Data from the peripheral back to the CPU.
CS – Chip select.
Puede tener varios dispositivos conectados a un bus I2C. Cada dispositivo tiene su propio conjunto de direcciones integradas en el chip. La dirección en realidad se transmite por el bus como el primer byte de cada comando (junto con un bit de lectura/escritura). Esto, junto con algunos otros gastos generales, requiere que se envíen más bits a través de un bus I2C frente a SPI para la misma funcionalidad.
Las diferentes clases de dispositivos (memoria, E/S, LCD, etc.) tienen diferentes rangos de direcciones. Algunos dispositivos, que comúnmente se usan más de una vez en un sistema (como el expansor de E/S PCF8574), usan una o más líneas de dirección (AD0-2 para el PCF8574) que se pueden vincular alto o bajo para especificar los bits bajos. de la dirección El MPU-6500 tiene una de esas líneas de dirección (AD0), por lo que se pueden usar dos en el mismo sistema.
También puede tener varios dispositivos en un bus SPI, pero cada dispositivo debe tener su propia línea de selección de chip (CS). Por lo tanto, la descripción de 4 cables es un poco inapropiada: en realidad es una interfaz de tres cables + un cable adicional por dispositivo. No tengo experiencia con la serie de placas Arduino, pero creo que esto dificultaría el uso de SPI en Arduino, ya que si necesita muchas líneas de selección de chips, esto comenzaría a ser engorroso con las asignaciones de pines comunes utilizados por los diversos escudos. .
Creo que la mayoría de las placas Arduino funcionan a 5 voltios, y algunas más nuevas funcionan a 3.3v. El MPU-6500 funciona a 3,3v. Si el voltaje "alto" de entrada mínimo para un bus I2C en una CPU de 5v es de 3v o menos, puede evitar problemas de conversión de nivel simplemente proporcionando resistencias pullup de 10K a 3.3v en las líneas SCL y SDA, ya que el bus está abierto. coleccionista. Asegúrese de que cualquier extracción interna de 5v en una CPU esté deshabilitada.
Sin embargo, verifiqué la hoja de datos del ATmega2560 (usando el ADK 5v Arduino como ejemplo), y su voltaje mínimo de entrada "alto" es 0.7 * Vcc, o 3.5v, que es mayor que 3.3v. Entonces, necesita algún tipo de nivel activo conversión El TI PCA9306 , que requiere resistencias pull-ups en ambos lados del chip de 5v y 3.3v, cuesta solo 78 centavos en cantidades individuales.
Entonces, ¿por qué elegir SPI sobre I2C? Principalmente porque SPI se puede ejecutar mucho más rápido, hasta muchas decenas de MHz en algunos casos. I2C generalmente está limitado a 400 KHz. Pero esto no es realmente un problema para el acelerómetro MPU-6050/6000, ya que funciona a 400 KHz para I2C y solo 1 MHz para SPI, no hay mucha diferencia.
En general, SPI es un bus más rápido: la frecuencia del reloj puede estar en un rango de MHz. Sin embargo, SPI requiere al menos 3 líneas para comunicación bidireccional y una selección de esclavo adicional para cada dispositivo en el bus.
I2C solo requiere 2 líneas, independientemente de cuántos dispositivos tenga (dentro de los límites, por supuesto). La velocidad, sin embargo, está en el rango de kHz (100-400kHz es típico).
La mayoría de los microcontroladores, hoy en día, tienen soporte de hardware para ambos buses, por lo que ambos son igualmente fáciles de usar.
I2C is designed for on-board applications.
- Aparentemente, los fabricantes de dispositivos I2C no están de acuerdo con usted. Tome el TMP100 . La página del producto establece explícitamente: The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
Lo mismo es cierto para el TMP75SPI se puede ejecutar mucho más rápido que I2C (algunos dispositivos SPI superan los 60MHz; no sé si la especificación I2C "oficial" permite dispositivos de más de 1MHz). La implementación de un dispositivo esclavo usando cualquiera de los protocolos requiere soporte de hardware, mientras que ambos permiten una fácil implementación de maestros de "software bit-bang". Con un hardware relativamente mínimo, se puede construir un esclavo compatible con I2C que funcionará correctamente incluso si el host puede decidir arbitrariamente ignorar el bus hasta 500us a la vez, sin necesidad de cables de enlace adicionales. Sin embargo, la operación confiable de SPI, incluso con soporte de hardware , generalmente requiere que se agregue un cable de protocolo de enlace o que el host agregue "manualmente" un retraso después de cada byte igual al tiempo de respuesta del esclavo en el peor de los casos.
Si tuviera mis preferencias, la compatibilidad con SPI de los controladores contendría algunas características adicionales simples para proporcionar transferencias de datos bidireccionales transparentes de 8 bits entre controladores con capacidades de establecimiento de comunicación y activación, utilizando un total de tres cables unidireccionales (Reloj y MOSI [maestro -out-slave-in] del maestro; MISO [master-in-slave-out] del esclavo). En comparación, la comunicación eficiente y confiable entre microcontroladores con puertos SPI "de stock", cuando ambos procesadores pueden retrasarse de forma independiente por períodos de tiempo arbitrarios, requiere el uso de muchos más cables (Chip-Select, Clock, MISO y MOSI para iniciar con, además de algún tipo de cable de reconocimiento del esclavo.Si el esclavo pudiera comenzar a tener datos para enviar de forma asíncrona (por ejemplo, porque alguien presionó un botón), entonces uno debe usar otro cable más como "despertador"
I2C no proporciona todas las capacidades que tendría mi SPI "mejorado", pero sí ofrece capacidades de protocolo de enlace integradas de las que carece SPI, y en muchas implementaciones también se puede modificar para proporcionar activación, incluso si el maestro es un software bit-bang. Para la comunicación entre procesadores, recomendaría enfáticamente I2C sobre SPI, excepto cuando se necesiten velocidades más altas que las que puede suministrar SPI, y el uso de pines adicionales sea aceptable. Para las comunicaciones entre procesadores donde se necesita un número bajo de pines, los UART tienen mucho que recomendar.
Esta pregunta se ha explorado a fondo en las excelentes respuestas aquí, pero tal vez haya un punto de vista más para I 2 C que podría ofrecer desde el punto de vista de un fabricante de chips.
La interfaz eléctrica del I 2 C es un colector abierto . Ahora respira y piensa en las implicaciones. Usando I 2 C, puedo diseñar un chip que sea totalmente independiente del voltaje operativo del bus. Todo lo que necesito poder hacer es bajar la línea SDA si me complace hacerlo, y comparar los voltajes de SCL y SDA con algún voltaje de umbral con referencia a tierra, que puedo elegir. Y si dejo de lado las estructuras normales de protección lateral alta y las reemplazo con otras estructuras, puedo hacer un chip que puede vivir su propia vida totalmente independientemente del resto del sistema: SCL, SDA nunca alimentan mi chip con corriente y yo ciertamente no alimentará ninguna corriente a esos pines. Es por eso que es un buen bus para relojes en tiempo real y otras cosas de bajo consumo como ese.
Una cosa que no he visto mencionada en las otras respuestas es que I2C admite múltiples maestros en el mismo bus. Si necesita una comunicación bidireccional y no desea utilizar un método basado en sondeos, I2C hará el trabajo.
En distancias más largas, CAN tiene la misma capacidad y es más robusto. Pero CAN es un protocolo asíncrono que requiere soporte de hardware y un transceptor, por lo que puede no ser una opción en un sistema de bajo costo.
Utilice el protocolo SPI y escriba sus bits directamente en el dispositivo siempre que el reloj de sincronización aumente. El circuito lógico xnor se puede usar para hacer coincidir la dirección "casera" de una memoria para seleccionar el dispositivo deseado como si fuera un dispositivo i2c.
El i2c está integrando el circuito autoral dentro del formato del dispositivo, estándar... etc. son complejos y diferentes, con un spi puedes usar una memoria spi para mostrar un video en pantalla, pero i2c no.
I2C es un bus con direcciones de datos. SPI es un bus con direcciones físicas.
I2C, como se mencionó anteriormente, no es fácil ni simple sin un controlador de hardware.
De hecho, SPI tampoco es simple sin un controlador de hardware en el contexto de esta discusión. Principalmente porque el tiempo es tan rápido que puede ser difícil de anticipar y cada dispositivo tiene su propio protocolo y anomalías.
Mi sugerencia es tomar esta decisión en función del ancho de banda.
Si su aplicación se beneficia de precisión de tiempo y tasa de datos. Especialmente si I2C no proporciona SPI de uso de ancho de banda completo.
Es probable que exista una biblioteca de interfaz para ambos o lo hará en breve. Si no, personalmente disfruto resolviendo problemas de SPI más que problemas de I2C.
Si ninguno de estos temas te preocupa. Use I2C simplemente porque es más probable que tenga un código existente y hay menos conexiones para hacer.
Hans
Armanda
jason s
Hans
jon l
crosley
Super gato