La interfaz periférica serie (SPI) fue desarrollada por Motorola para permitir que sus chips se comuniquen entre sí, al igual que Philips ideó el bus serie I2C para sus propios circuitos integrados. Mientras que estos dos buses hacen en gran medida el mismo trabajo, ambos se han vuelto casi igualmente comunes, y muchos dispositivos periféricos utilizan uno u otro para comunicarse con un microcontrolador host. Esta ubicuidad es la razón por la que los IMP apoyan a ambos.

SPI tiene algunas ventajas sobre I2C, en particular el soporte para una mayor velocidad de transferencia de datos., SPI también tiene una capacidad dúplex que lo hace particularmente adecuado para aquellas aplicaciones que requieren comunicación bidireccional simultánea.

por otro lado, SPI requiere al menos tres cables, compartidos por todos los dispositivos en el bus, y un número de líneas de selección de dispositivos, una para cada periférico conectado al dispositivo controlador. I2C, por el contrario, requiere solo dos cables; utiliza direcciones únicas para identificar todos los dispositivos en el bus., Esto hace que trabajar con varios dispositivos sea más sencillo que el enfoque sin direcciones de SPI, aunque algunos desarrolladores prefieren usar hardware para seleccionar un dispositivo en lugar de datos de direcciones.

Controladores Y Periféricos

SPI separa los dispositivos en los ‘controladores’ y ‘periféricos’. Solo un dispositivo puede enviar pulsos de sincronización para sincronizar las transferencias de datos, y ese es el elegido para ser el controlador. Todos los demás, que sincronizan sus tiempos con el controlador, se consideran periféricos subsidiarios., El controlador-que en su producto debe ser actualmente su imp-y sus periféricos pueden transmitir y recibir datos, pero solo el controlador puede establecer el patrón de tiempo al que todos operan. Este establecimiento de un esquema de tiempo fijo es lo que hace SPI, como I2C, un bus ‘síncrono’.

El Bus físico

la implementación SPI del imp tiene cuatro líneas:

  • sclk, la señal de reloj Serie del controlador.
  • COPI, abreviatura de ‘Controller Out, Peripheral In’ (a veces etiquetado como MOSI en hojas de datos antiguas).,
  • CIPO, abreviatura de ‘Controller In, Peripheral Out’ (a veces etiquetado como MISO).
  • CS, abreviatura de ‘Chip Select’ (a veces etiquetado como SS, nSS o SYNC)

COPI y CIPO son las líneas de transferencia de datos.

el imp001 y el imp002 no proporcionan pines CS dedicados: en su lugar, puede usar cualquiera de los otros pines GPIO de estos imp. El imp003 y superior proporcionan pines CS dedicados como parte de sus buses SPI, marcados en la página imp pin mux.

Nota El imp005 proporciona un pin de selección de chip dedicado en cada uno de sus dos buses SPI. Para spiBCAD esto es pin D; para spi0 esto es pin CS0., El método imp API chipselect() se puede usar para tomar el control de la aserción y des-aserción de estos pines de selección de chip (consulte la documentación del método para obtener más información).


SPI en el imp: hasta cuatro líneas se conectan a un solo dispositivo periférico

este enfoque sigue la definición de SPI de Motorola: que cada transacción de bus-esencialmente un lote de bytes de datos — debe estar vinculada a un periférico específico., Texas Instruments modificó la especificación SPI para permitir que cada byte se envíe a un periférico específico, aunque esto requiere una línea CS dedicada. Este modo no está soportado por ningún imp.

señalización

suponiendo que tenemos un solo periférico conectado al controlador, las comunicaciones se inician por el controlador tirando de la línea CS baja. Le dice al periférico que se prepare para conversar. Ahora el controlador comienza a enviar pulsos de reloj a lo largo de la línea SCLK; típicamente las transmisiones de datos se ajustan al borde ascendente de cada pulso, aunque no siempre es el caso.,


Clocking the data in and out: the imp sends a command, the peripheral returns data

el controlador ahora transmitirá datos en la línea COPI, conduciendo activamente la línea alta para señalar un 1 o bajo para un 0. El periférico leerá la señal-que podría ser un comando para que se envíe una lectura de sensor — por ejemplo-y devolverá esa información en la línea CIPO, conduciendo nuevamente la línea para permanecer alta para señalar un 1 o conduciéndola baja para transmitir un 0., Este requisito de que la línea sea conducida activamente alta o baja, en lugar de dejar que se asiente a un estado u otro conectando una resistencia, es la razón por la que SPI puede soportar velocidades más altas que I2C. I2C pierde tiempo de transmisión mientras que su resistencia pull-up devuelve la línea a alta.

dicho esto, sin embargo, es una buena práctica también tener un pull-up en una línea CS para asegurarse de que va alto cuando el imp está arrancando o durmiendo y, por lo tanto, no es capaz de conducir la línea alta manualmente. Mantener la línea alta asegura que el periférico ignorará cualquier problema técnico en las líneas de datos y reloj.,

Cuando el controlador tiene lo que quiere, conduce la línea CS alta una vez más, y el periférico puede descansar.

imp SPI Options

cada imp tiene una serie de buses SPI independientes, a los que se accede como propiedades del objeto de hardware del dispositivo, que se instancian al iniciar. La tabla pin mux de cada imp muestra que hay muchas opciones, dependiendo del tipo de imp que esté utilizando en su producto. Este documento asume que está utilizando un imp001, por lo que debe consultar la tabla pin mux si está trabajando con un imp diferente., Los dos buses SPI del imp001 son implementaciones de tres hilos del bus y están conectados a los pines 1, 8 y 9, y 2, 5 y 7, respectivamente. Los pines 1 y 5 son SCLK; 8 y 7 COPI; y 9 y 2 CIPO. Cualquiera de los dos buses que utilice, es una buena práctica para alias desde el principio:

spi1 <- hardware.spi257;spi2 <- hardware.spi189;

configurar cualquiera de los dos para su uso es simplemente una cuestión de decirle al imp lo rápido que desea que el bus funcione, y proporcionar un conjunto de constantes que juntos determinan cómo funcionará el bus:

spi1.configure(modeFlags, speed);

primero, la velocidad., This is simply an integer value giving the throughput in kiloHertz (kHz):

The specific SPI data rates available (in kHz) are as follows:

imp001, imp002 imp003 imp004m imp005 imp006
spi189 spi257 spiEBCA
spiLGDK
spiAHSR
spiGJKL
spiBCAD
spi0
spiXTUVW
15,000 30,000 18,000 24,000 The SPI data rates
available range
from 5KHz to 22.,8MHz
The SPI is clocked
by dividing 160MHz
by any integer
from 7 to 32,000
inclusive
Min. 187KHz, max. 750KHz
7500 15,000 9000 12,000
3750 7500 4500 6000
1875 3750 2250 3000 All others
937.50 1875 1125 1500 Min. 187KHz,
theoretical max. 24MHz
468.75 937.50 562.50 750
234.,375 468.75 281.25 375
117.1875 234.375 140.,g) el borde
MSB_FIRST Enviar bit más significativo primero (predeterminado)
LSB_FIRST Enviar el bit menos significativo primero
NO_SCLK pin SCLK no se usa
USE_CS_L Habilitar el uso del chip dedicado seleccione pin (imp005 sólo)

Estas se pueden combinar, si usted los necesita para ser, utilizando el operador lógico or, |, aunque algunos son mutuamente excluyentes, por lo que no debe ser combinado: SIMPLEX_TX y SIMPLEX_RX, por ejemplo., Para usar tanto CLOCK_IDLE_LOW como CLOCK_2ND_EDGE, por ejemplo, en lugar de ingresar una sola constante como parámetro en el método configure() incluiría ambos, separados por el símbolo |:

spi1.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 400);

Las combinaciones pueden ser necesarias si se especifican en la hoja de datos del periférico, aunque esto puede no ser inmediatamente obvio para el recién llegado. Las hojas de datos pueden hablar sobre el ‘modo SPI’ de un dispositivo, o sus valores CPOL (polaridad del reloj) y CPHA (fase del reloj)., CPOL y CPHA determinan qué bordes de la señal de reloj se utilizan para conducir y muestrear señales de datos. Cada uno de estos dos parámetros tiene dos estados posibles, para cuatro combinaciones posibles en total:


modos SPI

Los modos SPI simplemente indexan esas combinaciones en lugar de los valores separados de CPOL y CPHA. El controlador y el periférico tienen que comunicarse utilizando los mismos valores CPOL y CPHA, y por lo tanto el mismo modo., Múltiples periféricos bien pueden significar diferentes configuraciones, por lo que el controlador tendrá que reconfigurarse cada vez que necesite comunicarse con un periférico específico.,la siguiente tabla:

Lectura y escritura de datos

Una vez configurado el bus SPI, utilice el método write() para enviar una cadena de bytes al dispositivo periférico:

spi1.write("This is an LCD display");

El uso de una cadena es opcional: también puede enviar un blob de bytes de datos sin procesar:

local blob = blob(4); // Create a four-byte blob...blob.writen(0xDEADBEEF, 'i'); // ...and write a 32-bit value to itspi1.write(blob);

Si desea leer una cadena o un blob, necesita uno de los dos métodos de lectura SPI de la API IMP:

local bytes = spi1.readblob(8);local inputString = spi1.readstring(16);

el valor entero pasado como parámetro es, respectivamente, el número de bytes que se leerán en el BLOB y el número de caracteres que se pondrán en la cadena., Por supuesto, dado que un carácter ocupa un byte, estos dos métodos son equivalentes. Este último simplemente convierte blob en cadena para usted.

debido a la naturaleza’ full duplex ‘ del bus SPI, las Escrituras y las lecturas siempre ocurren simultáneamente. Con los comandos de lectura y escritura que hemos visto hasta ahora, los datos que se mueven en la dirección opuesta a la que nos interesa son ignorados o puestos a cero. Por lo tanto, cuando se escribe una cadena, por ejemplo, cualquier dato que llega al imp desde el periférico se ignora., Durante cualquiera de las dos operaciones de lectura, se escribe un tamaño coincidente de cero bytes ‘dummy’ en el periférico: si lee ocho bytes, digamos, ocho 0s se escriben automáticamente.

para administrar esta comunicación bidireccional simultánea, la API imp tiene un cuarto método que combina lecturas y escrituras:

local inputString = spi1.writeread(outputString);

así, como la cadena outputString se envía a lo largo de la línea COPI, la variable inputString se llena con los bytes de datos que vienen en CIPO. Puede enviar y recibir cadenas o blobs, pero tanto la entrada como la salida deben ser del mismo tipo., Por grande que sea tu blob de salida, tu blob de entrada será del mismo tamaño. Del mismo modo, las cadenas de entrada y salida serán de la misma longitud.

La operación full duplex también se puede usar con dispositivos que no esperan funcionar de esa manera, aquellos que requieren que los bytes ‘dummy’ de lectura y escritura sean un valor específico distinto de cero. Este requisito descarta el uso de los métodos regulares write(), readblob() y readstring (), pero writeread() se puede usar en su lugar para asegurarse de que se utilicen los valores ficticios preferidos del dispositivo.,

código de ejemplo

el siguiente código funciona con el acelerómetro Digital Analog Devices ADXL345, una parte que utiliza SPI para comunicarse con su microcontrolador host. También es compatible con I2C, y los pines de esta placa de desbloqueo Adafruit, que se basa en el chip, Están etiquetados en consecuencia. La hoja de datos del chip se puede descargar desde el Sitio Web de Analog Devices.

cómo funciona el Código

utilizamos un bus spi257 de imp001, alias cerca del principio del listado como spi. También alias pin 8 como la línea CS. La función spiWriteReg () muestra cómo se usan., Una transacción de escritura se indica cambiando la línea CS baja. A continuación, la dirección del registro en el que queremos escribir se convierte de un entero con signo de ardilla de 32 bits a un valor de 8 bits escribiéndolo en un blob. Este blob se escribe en el bus SPI. Hacemos lo mismo con el valor que queremos que el ADXL345 ponga en ese registro, y luego configuramos La línea CS alta nuevamente para señalar el final de la transacción.,


El Adafruit/Analog Devices ADXL345

la función spiReadReg() funciona de la misma manera, solo que esta vez leemos los datos de valor del bus después de escribir la dirección del registro fuente. El ADXL345 requiere que se hagan algunos ajustes a la dirección de registro en este caso: el bit 7 debe configurarse para marcar la transacción como una operación de lectura, y el bit 6 debe configurarse para decirle al chip que esperamos que se envíe más de un solo byte.,

donde se inicia el programa, configuramos el bus SPI del imp para que coincida con los requisitos del chip ADXL345. Utiliza el modo SPI 3-ie. tanto CPOL como CPHA deberían estar configurados — así que usamos el parámetro imp equivalente: CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE en la llamada configure (). También ajustamos la velocidad a 100kHz. A continuación, el pin 8 del imp, que funciona aquí como el pin CS, se configura como una salida digital y se establece en alto.


cableando el ADXL345

otras funciones en el programa inicializan el ADXL345 en sí en lugar del bus SPI., El ADXL345 se inicializa, y el código se lee en el valor de la dirección de registro 0x00 para garantizar que el dispositivo esté presente en el bus. El chip tiene un modo de auto-prueba que permite tomar una serie de lecturas de calibración; esto lo hacemos y almacenamos los resultados. Más tarde, en la función loop (), estos valores se utilizan para ajustar las lecturas finales del acelerómetro.,

el ADXL345 guarda sus muestras de los ejes x, Y Y z como valores de 16 bits, cada uno en dos registros de 8 bits; loop() usa la función spiReadReg() para adquirir los dos componentes de cada valor y luego los convierte en valores simples multiplicando el byte más significativo por 256 y agregando al resultado el valor del byte menos significativo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *