¿Cómo sería el firmware para controlar el sistema Shift1 (para la operación de registro de desplazamiento de 1 pin)?

Esta es una pregunta de continuación de esta respuesta de Spehro Pefhany , en la que nos explica cómo usar los registros de desplazamiento en serie 74HC595 con solo un pin de salida digital. A continuación se muestra la imagen que publicó.

Sistema Shift1 de Roman Black

Por curiosidad, y también para evaluar si yo mismo sería capaz de controlar un registro de turnos, mis preguntas son:

1. ¿Qué tan complicado es controlar los registros de desplazamiento de esta manera con una MCU, en C, por ejemplo?

2. ¿Cómo sería el firmware que controla este registro de desplazamiento?

3. ¿Hay bibliotecas de Arduino que nos ayuden a manejar eso (o también para otras plataformas)?

No tengo idea de cómo empezar.

El diagrama es bastante explícito: configura el pin bajo durante un período de tiempo específico, lo vuelve a poner alto, espera un tiempo mínimo, repite para todos los bits, repite para el pulso de bloqueo. Por cierto, ¿notaste que perdiste un pin de salida?
@WoutervanOoijen: sí, es explícito, pero estoy luchando por diseñar el código que solo haría eso. Entiendo que tendría que usar un temporizador y (como ingeniero de software) probablemente me gustaría abstraer la acción alta/baja detrás de una función como la de Arduino shiftOut.
@WoutervanOoijen: y sí, entiendo que tendría que usar un pin para controlar esto, pero luego guardaría los otros dos que generalmente desperdiciaré controlando el reloj y el pestillo. ¿O hay otro pin que se usa en otro lugar?
@WoutervanOoijen: definitivamente probaría esto en los próximos días, así que publicaré mi intento de un código que impulse esto como respuesta. Es mi tarea: la investigación inicial que aún no he hecho.
¿Recuerdo que usas un Arduino? ¡Seguramente hay alguna biblioteca que tiene una llamada delay_us() o algo similar!
@WoutervanOoijen Hay una delayMicrosecondsfunción, pero solo tiene un tiempo de retraso mínimo de 2 μs, que es demasiado para el primer pulso.
@WoutervanOoijen - Sí, lo es delayMicroseconds(). Pero quería usar una interrupción de desbordamiento del temporizador para que el bucle principal pueda hacer otras cosas.
@Ricardo Leí aquí (sección: ¿Cuánto tiempo lleva ejecutar un ISR ) que la latencia de interrupción en Arduino está en la región de 2.625 μs, lo que sería demasiado tiempo.
@Shaktal: ¿entonces significa que este arreglo no puede ser impulsado por un Arduino de 16 MHz? ¡Eso es muy malo!
@Ricardo Creo que puede ser; solo tendría que hacerlo nopdurante 16 ciclos en la línea principal loopantes de llamar digitalWrite, no podría usar una interrupción
Si no te gustan los tiempos, creo que podrías usar capacitores de 22nF y multiplicar todos los tiempos por 10. Pero Ricardo, pareces pensar que este circuito es el mejor invento desde el pan rebanado. Es un juguete ingenioso. No creo que ningún profesional lo incluya en un diseño serio. Use 595 simple o un chip I2C como el MCP23017 (debe haber bibliotecas arduino para ambos).

Respuestas (1)

Esta es solo una respuesta aproximada porque hay áreas de las que no estoy seguro, por lo que agradecería que alguien pudiera señalar los errores. Supongo que uno de sus problemas es que la delayfunción solo permite una resolución de milisegundos y la delayMicrosecondsfunción solo tiene un tiempo de retraso mínimo de 2 μs. Sin embargo, el ATmega32U4 en Arduino Micro (y otros también) tiene una velocidad de reloj de 16 MHz, por lo que podemos calcular el tiempo entre ciclos:

Δ t = 1 dieciséis  megahercio = 0.0625 m s

Por lo tanto, podemos calcular cuántos ciclos de reloj deben transcurrir antes de cambiar la salida de HIGHa LOWy viceversa. Queremos un retraso de 1μs y por lo tanto calculamos:

norte = 1 0.0625 = dieciséis

Donde n es el número de ciclos de reloj. Por lo tanto, queremos que la CPU espere 16 ciclos, podemos lograr esto con algún ensamblaje en línea:

__asm__("nop\n\t"/*14 more of these*/"nop\n\t");

Sin embargo, no he tenido en cuenta la cantidad de ciclos de reloj digitalWritenecesarios antes de cambiar el voltaje del pin de salida, por lo que también deberá analizarlo.

Como dije, esta es solo una respuesta esbozada, por lo que agradecería verificaciones de validez y sugerencias/críticas; Soy bastante nuevo en esto!