Tengo un dispositivo que estoy tratando de controlar con el Arduino.
Funciona así.
El problema que tengo es hacer que el Arduino se sincronice con los pulsos del reloj. Actualmente tengo una declaración if que establece la línea de datos si ve que la línea del reloj es alta, pero esto no parece funcionar. Creo que debería estar buscando el borde ascendente en su lugar.
¿Cómo puedo sincronizar estos dos dispositivos correctamente?
Agregue estos pasos a su algoritmo: 0. Prepare el primer bit de datos... 3. Use la interrupción externa en el flanco ascendente para generar el bit preparado y coloque el siguiente bit en su variable de soporte de bits. Cuenta los bits emitidos. * El paso 3 se repetirá automáticamente 16 veces (el dispositivo externo lo activará). 4. Cuando el contador de bits llegue a 16, deshabilite la interrupción externa y restablezca la línea lista.
sugerencia: en atmega168/328, cualquier pin puede usarse como fuente de interrupción externa en la transición de borde entrante con una técnica bastante simple.
Espero que su dispositivo externo no esté impulsando pulsos de reloj demasiado rápido. Arduino no es muy bueno en velocidades de reacción superiores a 1MHz. Diría que debe esperar que este enfoque funcione de manera confiable hasta un reloj de 100 kHz. En velocidades más altas, se debe usar SPI de hardware para registrar sus datos o una codificación de ensamblaje estricta. En cualquier caso, varios MHz es el máximo que puede hacer con AVR desnudo aquí.
El SPI tiene dos modos: Arduino Stock Library de forma nativa solo admite maestro. Su escenario suena exactamente como ESCLAVO, en el sentido de que el otro extremo está manejando el Reloj.
Puede vincular su Ready al SS (como entrada) y configurar el SPI con el modo correcto de fase/polaridad. Luego configure el SPCR como Esclavo. Habilite su Listo y luego espere a que se complete la transferencia de 8 bits, ya sea por interrupción o por sondeo. luego suelte el Listo.
ATmega328 Hoja de datos nota sección 18.2 y 18.3.2
El problema aquí tiene que ver con la sincronización, ¡así que saquemos todos nuestros osciloscopios! Básicamente (y un poco demasiado simplificado), la mayoría de las declaraciones de control de flujo C estándar no pueden garantizar la sincronización en un microcontrolador. Las interrupciones basadas en hardware garantizan que el código comenzará a ejecutarse dentro de un número fijo de ciclos de reloj.
El Arduino (más específicamente, el Arduino Uno con un ATmega328) tiene muchas formas de activar interrupciones de hardware, a veces llamadas "vectores de interrupción" (pág. 57 de la hoja de datos de ATmega). ¿Cuál queremos? Queremos ejecutar el código inmediatamente después de la transición del pin del martillo, por lo que estamos buscando una interrupción de cambio de pin o una interrupción externa. La sección 12 en la hoja de datos entra en demasiados detalles sobre esto, pero la clave es que cada puerto de 8 pines comparte un vector de interrupción. ( arduino.cc/en/Hacking/PinMapping168 ) Esto lo hace complicado, especialmente si eres nuevo en microcontroladores. La comunidad de Arduino creó una gran biblioteca para tal situación, llamada PinChangeInt . (Descargo de responsabilidad: contribuí a PinChangeInt)
el incorporadoLa función de creador de interrupciones de Arduino (attachInterrupt(interrupt, ISR, mode)) y el creador de interrupciones de PinChangeInt (PCintPort::attachInterrupt(PIN1, &ISRfunc, EDGE)) toman argumentos muy similares. Los argumentos pin y edge/mode se explican por sí mismos: el pin en el que desea la interrupción y el borde que le interesa (lo más probable es que aumente, pero verifique el diagrama de tiempo de su reloj). El nombre de la función que especifique se adjunta como la rutina de servicio de interrupción (ISR). Cada vez que el hardware ve esa interrupción, el ISR comienza a ejecutarse. Esta función (ISRfunct() arriba) no toma argumentos y no devuelve valores (escriba VOID). Puede acceder a variables globales y otras variables de alcance como cualquier función. Para implementar la lógica que está describiendo, necesitará una variable global para sus datos y otra para el "índice de transmisión" o el último bit enviado.
Para obtener más información sobre las interrupciones en el Arduino, consulte los enlaces a continuación:
Diagramas del subsistema ATmega168
uchobby.com/index.php/2007/11/24/arduino-interrupts/
gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/
Ignacio Vázquez-Abrams
yippie
estruendo
estruendo