¿Cómo realizar una salida síncrona en el Arduino?

2

Tengo un dispositivo que intento controlar con el Arduino.

Funciona así.

  1. Arduino establece y mantiene 'línea lista' a 5V de alto.
  2. El dispositivo ve la línea alta preparada y envía 16 pulsos de reloj para recibir dos bytes de mensajes.
  3. En cada pulso de reloj, Arduino establece la salida de datos en el bit que sea (0 o 1)
  4. Cuando se han enviado los dos bytes, la 'línea de preparación' se establece en 0v baja.

El problema que tengo es hacer que el Arduino se sincronice con los pulsos del reloj. Actualmente tengo una sentencia if que establece la línea de datos si ve la línea del reloj 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?

    
pregunta blarg

3 respuestas

4

Agregue estos pasos a su algoritmo: 0. Preparar el primer bit de datos. ... 3. Use la interrupción externa en el flanco ascendente para generar el bit preparado y ponga el bit siguiente en su variable de soporte de bit. Contar los bits de salida. * El paso 3 se repetirá automáticamente 16 veces (un dispositivo externo lo activará). 4. Cuando el contador de bits llegue a 16, desactive la interrupción de ext y establezca la línea preparada de nuevo.

sugerencia: en atmega168 / 328, cualquier pin se puede utilizar 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 los pulsos del reloj demasiado rápido. Arduino no es muy bueno a velocidades de reacción más rápidas que 1MHz. Yo diría que debería 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 sincronizar sus datos o la codificación de ensamblado ajustado. En cualquier caso, varios MHz es el máximo que puede hacer con un AVR simple aquí.

    
respondido por el x4mer
2

El problema aquí tiene que ver con la sincronización, ¡así que salgamos nuestros osciloscopios! Básicamente (y un poco más simplificado) la mayoría de las declaraciones de control de flujo de C estándar no pueden hacer garantías de tiempo 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, llamadas a veces "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 de la polla, 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 Arduino creó una gran biblioteca para tal situación, llamada PinChangeInt . (Descargo de responsabilidad: contribuí a PinChangeInt)

La función integrada del creador de interrupciones Arduino (attachInterrupt (interrupt, ISR, mode)) y el creador de interrupciones de PinChangeInt (PCintPort :: attachInterrupt (PIN1, & ISRfunc, EDGE)) tienen argumentos muy similares. Los argumentos pin y edge / mode son autoexplicativos: el pin en el que desea que se active la interrupción y el edge en el que está interesado (lo más probable es que suba, 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 () anterior) no toma argumentos y no devuelve ningún valor (escriba VOID). Puede acceder a variables globales y otras de alcance como cualquier función. Para implementar la lógica que está describiendo, necesitará una variable global para sus datos y una para el "índice de transmisión" o el último bit enviado.

Para obtener más información sobre las interrupciones en Arduino, consulte los enlaces a continuación:

ATmega168 Subsystem Diagrams

uchobby.com/index.php/2007/11/24/arduino-interrupts/

gonium.net/md/2006/12/20/handling-external-interrupts-with-arduino/

    
respondido por el LexTalionis
1

El SPI tiene dos modos: Arduino Stock Library de forma nativa solo es compatible con master. Su escenario suena exactamente igual a ESCLAVO, ya que el otro extremo está manejando el Reloj.

ejemplo completo

Puede vincular su Lista al SS (como entrada) y configurar el SPI con el modo correcto de fase / polaridad. A continuación, establezca el SPCR como esclavo. Habilite su Lista y luego espere a que se complete la transferencia de 8 bits, ya sea por interrupción o sondeo. luego suelte el Listo.

ATmega328 Hoja de datos note la sección 18.2 y 18.3.2

    
respondido por el mpflaga

Lea otras preguntas en las etiquetas