Estoy tratando de establecer una comunicación entre Atmel Atmega32U4 (utilizado en Arduino Leonardo) en MCU PCB y TI DAC8552 en PSU PCB a través de enlace SPI aislado. Para el aislamiento, estoy usando Silicon Labs Si86xx aislador digital que puede funcionar Hasta 150MHz. Si bien todo funciona como se esperaba SIN el aislador, obtuve resultados bastante extraños cuando el aislador se colocó entre el dispositivo MCU y el dispositivo DAC. Para las pruebas se utiliza un boceto de Arduino muy simple que envía en bucle infinito dos valores al DAC cada uno de los últimos 20 ms:
#include "SPI.h"
int DAC2_SELECT=5; // uncomment this line if Arduino board is used instead of PSU MCU board
int IO_EXPANDER2=6; // uncomment this line if Arduino board is used instead of PSU MCU board
int ADC2_SELECT=13; // uncomment this line if Arduino board is used instead of PSU MCU board
int var=0;
void setup()
{
// Deselect devices that share same SPI bus on the PSU post-regulator board
pinMode(ADC2_SELECT, OUTPUT);
digitalWrite(ADC2_SELECT, HIGH); // Deselect ADS1120
pinMode(IO_EXPANDER2, OUTPUT);
digitalWrite(IO_EXPANDER2, HIGH); // Deselect MCP23S08
// Initialize DAC8552
pinMode(DAC2_SELECT, OUTPUT);
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(0); //CPOL=0, CPHA=0
// SPI.setClockDivider(SPI_CLOCK_DIV16); // Slow down SPI clock speed to 1MHz for testing purpose
digitalWrite(DAC2_SELECT, LOW);
SPI.transfer(B00100100); // Write to Data Buffer B
SPI.transfer(0x99); // send first byte
SPI.transfer(0x99); // send second byte
digitalWrite(DAC2_SELECT, HIGH); // Deselect DAC
}
void loop()
{
digitalWrite(DAC2_SELECT, LOW);
SPI.transfer(B00010000); // Write to Data Buffer A
SPI.transfer(0x20); // send first byte
SPI.transfer(0x00); // send second byte
digitalWrite(DAC2_SELECT, HIGH); // Deselect DAC
delay(20);
digitalWrite(DAC2_SELECT, LOW);
SPI.transfer(B00010000); // Write to Data Buffer A and activate channel A
SPI.transfer(0x80); // send first byte
SPI.transfer(0x00); // send second byte
digitalWrite(DAC2_SELECT, HIGH); // Deselect DAC
delay(20);
}
El esquema derivado de uno muy complejo se muestra a continuación:
ResultadosSINaislador:
Conexión entre MCU y PSB PCB:
EstoesloqueobtuvecuandoseagregóaisladorentreMCUyDAC:
Lo probé utilizando el aislador en MCU PCB ...
perotambiénparaasegurarsedeusarelaisladorconectadoeneltableroparaasegurarsedequealgoestáconectadoincorrectamentealaPCBMCU:
Tenga en cuenta que la PCB de MCU tiene dos conectores IDC de 10 pines: el negro es un SPI no aislado y el gris está aislado SPI donde la parte "remota" del dispositivo aislador se suministra desde una fuente externa (PSU PCB). Intencionalmente, utilicé el mismo cable plano, y la longitud del cable no parece ser un problema, ya que todo funciona correctamente sin aislador. Para estar completamente seguro, traté de reducir la velocidad del reloj SPI tanto como sea posible, incluso a 125 kHz (se divide por 128 de 4 MHz por defecto o se divide por 4). Nada ayuda en caso de aislador: recibo continuamente valores aleatorios en la salida en lugar de dos fijos. También probé la siguiente conexión "híbrida" en la que MOSI y el chip select (ADC2_SELECT) pasan por el aislador y SCLK está conectado directamente, mientras que la conexión a tierra MCU NO ESTÁ conectada a la conexión a tierra remota "PSU". Para mi sorpresa, esa combinación funciona, pero no puedo explicar por qué. La verificación de la señal desde ambos lados del aislador no muestra nada sospechoso: la duración de la señal en el lado "remoto" es ligeramente más corta ya que el aislador tiene la lógica de activación Schmitt incorporada.
Se me acabaron las ideas sobre qué probar a continuación, así que si alguien tiene alguna sugerencia, hágamelo saber.
EDITAR 2015-06-08: Estoy agregando a continuación dos capturas de pantalla una al lado de la otra, donde a la izquierda se encuentra el DAC cuando SPI está conectado directamente. Parece que la configuración del nuevo valor está sincronizada pero, por alguna razón, el valor se "desplaza" hacia arriba o hacia abajo en caso de un valor más bajo (0x20).
Cuandoelcambioesde0x70a0x80,obtuvelosiguiente:
EDICIÓN 2015-06-09: A continuación, encontrará más medidas sugeridas por Tom L. Todo se realiza en el tablero, se usan los mismos cables y el cable plano que en los resultados presentados inicialmente. Las conexiones a ambos lados del aislador están unidas, el "remoto" (o lado B) se suministra desde la PCB de la PSU, el host (o el lado A) desde Arduino Leonardo. Primero me cansé de usar el cableado mencionado de la conexión directa SPI y funciona como se esperaba. En el primer paso, SCLK y MOSI permanecen directamente conectados. CS (ADC2_SELECT) pasa el aislador. Todos los pines del aislador no utilizados están conectados a tierra. DAC funciona como se puede ver en las siguientes dos capturas de pantalla (S1 es el lado del host, S2 es el lado remoto en el dispositivo aislador, la señal DAC es una salida analógica en el pin 4 de DAC8552 (VOUTA):
Lo mismo cuando MOSI pasa por el aislador y SCLK y CS se mantuvieron directamente conectados:
Y ahora tenemos un problema que persiste y no puedo entender qué está pasando: cuando SCLK pasa por el aislador, la comunicación se detiene, independientemente del hecho de que la señal se ve bien en ambos lados del aislador. Tenga en cuenta que en el rastreo DAC no hay más cambios. Ese es uno de los dos escenarios posibles. Ya se describió otro (los valores aleatorios se presentan en la salida DAC).
Estoy agregando un escenario adicional cuando SCLK está conectado al lado del host a través de un condensador. En ese caso, el DAC comienza a comportarse con regularidad incluso cuando los terrenos no están unidos. Por favor encuentre abajo el esquema y el resultado: