Simular registro de desplazamiento en AVR (¿Lógica configurable/Temporizadores?)

Recientemente configuré dos MCU (ATtiny1616) para realizar una comunicación serial básica utilizando registros de desplazamiento que hice yo mismo.

esquemático

simular este circuito : esquema creado con CircuitLab

Aquí está el diagrama lógico de mi registro de desplazamiento. Lo hice con las puertas lógicas que tenía por ahí. Todo lo que hace es cambiar lo que esté en la línea de datos al registro cuando el reloj (activo alto) va de alto a bajo:

esquemático

simular este circuito

Ignore mis flip-flops no estándar, quería visualizar los bits en mi panel indicador LED y cambiar desde el bit menos significativo (derecha). Conecté la línea del reloj al receptor para que solo leyera PORTA.IN cuando finalice la transmisión. A medida que se transmite cada byte, el TEMPORIZADOR A cuenta los flancos descendentes del reloj en modo de 8 bits. Cuando el contador llega a 8, activa una interrupción que reinicia el contador y lee PORTA.IN .

Luego, el receptor/esclavo baja la línea de datos, provocando una interrupción en el remitente/maestro, que ahora espera inactivo una confirmación de transmisión. También agregué un detector de tiempo de espera. Para señalar el final de una transmisión, envío un byte con todos los bits altos. El receptor no esperará una respuesta después de recibir el último byte y bajar la línea de datos, y la transmisión está completa.

Probé esto con dos matrices de 512 bytes: una matriz de bytes vacía en el receptor y una matriz con bytes que representan un mensaje ASCII y algo de basura aleatoria al final en el remitente. Los datos se transfirieron con éxito del remitente al receptor en una fracción de segundo. Estoy bastante impresionado con los resultados.

La desventaja de este método, además de permitir la comunicación unidireccional por el momento, es que utiliza un puerto completo para leer los datos. Me gustaría que mi 'registro de desplazamiento' sea interno dentro de la MCU, y no fuera de desordenar mi prototipo y desperdiciar muchos pines de E/S. Entonces podría alimentar el reloj y los datos al controlador y hacerlo todo allí. Hardware solo hasta la lectura final, por supuesto.

¿Alguna idea sobre cómo podría lograrse esto? El 1616 es compatible con la lógica personalizada configurable, pero no creo que tenga la cantidad de entradas necesarias para un registro de desplazamiento de 8 flip-flop. Supongo que podría recurrir a enviar nibbles a la vez... También pensé en usar temporizadores para lograr esto, pero no sé cómo podría hacerse. ¿Quizás una combinación de los dos?

Respuestas (2)

El ATTINY161 contiene un registro de desplazamiento de hardware que puede hacer exactamente lo que desea dentro del USART....

ingrese la descripción de la imagen aquí

El USART es muy flexible, por lo que puede configurarlo fácilmente para serializar/deserializar bytes de 8 bits en función de un reloj externo, entre muchas otras configuraciones.

La documentación en las hojas de datos (USART está en la sección 24) está completa y es muy buena, así que la leería detenidamente.

Informe si tiene alguna pregunta específica sobre cómo configurar los registros para cumplir específicamente con sus requisitos.

Alternativamente, puede conectar el reloj y las líneas de datos a cualquier pin GPIO antiguo, configurar una interrupción de cambio de pin en el pin del reloj y luego muestrear el pin de datos en la rutina de servicio de interrupción y cambiar el bit recién muestreado a una variable o regístrese hasta que obtenga 8 bits completos. Un pequeño truco es inicializar la variable de registro de desplazamiento con 0x01 y luego puede verificar el bit de acarreo después de cada desplazamiento a la izquierda; si está configurado, entonces tiene 8 bits de datos (vea por qué). Esto ahorra la necesidad de una segunda variable para mantener el conteo de bits.

El ATtiny1616 presenta una interfaz I²C ("TWI") y SPI, tanto en modo Maestro como Esclavo.

El SPI puede ser exactamente lo que desea, pero también eche un vistazo al TWI. Podría ser la mejor opción, dependiendo de su aplicación real.

Este. Es fácil de implementar (aunque se podría argumentar que sería "menos divertido"), más barato de hacer, solo usaría dos pines en su micro... ¡Pruébelo, OP! Pusieron todos esos periféricos en el chip por una razón :-)
¡Ajá! ¡No me di cuenta de que el hardware TWI NO es solo para I2C! ¡Es un bloque lógico y tiene un registro de desplazamiento de 8 bits como parte del periférico! ¡Gracias de nuevo!
I²C aún puede ser la mejor opción, ya que solo necesita dos E/S. Implementar un esclavo I²C es solo unas pocas líneas de código con la ayuda de TWI.