Tabla de contenido:
- Paso 1: ¿Cómo podemos lograr que dos microcontroladores se comuniquen entre sí?
- Paso 2: Subrutinas de comunicaciones
- Paso 3: Conclusión
Video: Tutorial de ensamblador AVR 6: 3 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:40
¡Bienvenido al Tutorial 6!
El tutorial de hoy será breve en el que desarrollaremos un método simple para comunicar datos entre un atmega328p y otro usando dos puertos que los conectan. Luego, tomaremos el rodillo de dados del Tutorial 4 y el Analizador de registros del Tutorial 5, los conectaremos y usaremos nuestro método para comunicar el resultado de los lanzamientos de dados del rodillo al analizador. Luego imprimiremos el rollo en binario usando los LED que construimos para el analizador en el Tutorial 5. Una vez que tengamos esto funcionando, podremos construir la siguiente pieza de nuestro proyecto general en el siguiente tutorial.
En este tutorial necesitará:
- Tu tablero de prototipos
- Tu rodillo de dados del Tutorial 4
- Su analizador de registros del tutorial 5
- Dos cables de conexión
-
Una copia de la hoja de datos completa (revisión de 2014):
www.atmel.com/images/Atmel-8271-8-bit-AVR-M…
-
Una copia del manual del conjunto de instrucciones (revisión de 2014):
www.atmel.com/images/atmel-0856-avr-instruc…
Aquí hay un enlace a la colección completa de mis tutoriales de ensamblador AVR:
Paso 1: ¿Cómo podemos lograr que dos microcontroladores se comuniquen entre sí?
Dado que estamos comenzando a expandir nuestro proyecto para que nuestro producto final único se componga de una colección de piezas más pequeñas, necesitaremos más pines de los que puede proporcionar un solo Atmega328P. Por lo tanto, haremos cada parte del proyecto general en un microcontrolador separado y luego haremos que compartan los datos entre ellos. Entonces, el problema que debemos resolver es ¿cómo podemos idear un método simple para que los controladores se comuniquen entre sí y transfieran datos entre ellos? Bueno, una cosa acerca de estos controladores es que cada uno ejecuta 16 millones de instrucciones por segundo. Esto está cronometrado con mucha precisión y, por lo tanto, podemos usar este tiempo para transferir datos. Si usamos retrasos de milisegundos para constituir los datos, entonces realmente no tenemos que ser tan precisos ya que la CPU está ejecutando 16, 000 instrucciones en un solo milisegundo. En otras palabras, un milisegundo es una eternidad para la CPU. Intentémoslo con las tiradas de dados. Quiero transmitir el resultado de una tirada de dados desde el chip del rodillo de dados al chip analizador. Suponga que está al otro lado de la calle y quiero señalarle el resultado de mi tirada de un par de dados. Una cosa que podría hacer, si ambos tuviéramos un reloj, es encender una linterna, luego, cuando estés listo para recibir mis datos, enciendes tu linterna y ambos ponemos en marcha nuestros relojes. Luego mantengo mi linterna encendida durante el número exacto de milisegundos mientras se lanzan los dados y luego la apago. Entonces, si sacara un 12, mantendría mi luz encendida durante 12 milisegundos. Ahora, el problema con lo anterior es que, para usted y para mí, no hay forma de que podamos cronometrar las cosas con la suficiente precisión para distinguir entre 5 milisegundos y 12 milisegundos. Pero ¿qué pasa con esto? Supongamos que decidimos que mantendría la luz encendida durante un año por cada número en los dados. Entonces, si saco un 12, te iluminaría durante 12 años y creo que estarás de acuerdo en que no hay posibilidad de que te equivoques al calcular el número, ¿verdad? Podrías tomarte un descanso e ir a jugar béisbol, incluso podrías ir a jugar a los dados en Las Vegas durante 6 meses, siempre y cuando en algún momento del año mires al otro lado de la calle para ver si la luz está encendida y no te pierdas ni una cuenta. ¡Eso es exactamente lo que estamos haciendo por los microcontroladores! Un solo milisegundo para la CPU es como un año. Entonces, si enciendo la señal durante 12 milisegundos, casi no hay posibilidad de que el otro microcontrolador lo confunda durante 10 u 11 sin importar las interrupciones y las cosas que sucedan mientras tanto. Para los microcontroladores, un milisegundo es una eternidad, así que esto es lo que haremos. Primero elegiremos dos puertos en el controlador para que sean nuestros puertos de comunicación. Usaré PD6 para recibir datos (podríamos llamarlo Rx si queremos) y elegiré PD7 para transmitir datos (podríamos llamarlo Tx si queremos). El chip analizador comprobará periódicamente su pin Rx y, si ve una señal, pasará a una "subrutina de comunicación" y luego transmitirá una señal de retorno al rodillo de dados diciendo que está listo para recibir. Ambos comenzarán a cronometrar y el rodillo de dados transmitirá una señal (es decir, 5 V) durante un milisegundo por número en los dados. Entonces, si la tirada fue doble seis, o un 12, entonces el rodillo de dados establecería su PD7 en 5V durante 12 milisegundos y luego lo volvería a establecer en 0V. El analizador verificará su pin PD6 cada milisegundo, contando cada vez, y cuando regrese a 0V, entonces envía el número resultante a la pantalla del analizador, mostrando un doce en binario en los LED. Así que ese es el plan. Veamos si podemos implementarlo.
Paso 2: Subrutinas de comunicaciones
Lo primero que debemos hacer es conectar los dos controladores. Así que tome un cable de PD6 en uno y conéctelo a PD7 en el otro, y viceversa. Luego, inicialícelos configurando PD7 en OUTPUT en ambos y PD6 en INPUT en ambos. Finalmente, configúrelos todos a 0V. Específicamente, agregue lo siguiente a la sección Init o Reset del código en cada microcontrolador:
sbi DDRD, 7; PD7 configurado para salida
cbi PortD, 7; PD7 inicialmente 0V cbi DDRD, 6; PD6 configurado para ingresar cbi PortD, 6; PD6 inicialmente 0V clr total; total en dados inicialmente 0
Ahora configuremos la subrutina de comunicaciones en el chip del rodillo de dados. Primero defina una nueva variable en la parte superior llamada "total" que almacenará el número total tirado en el par de dados y lo inicializará a cero.
Luego escriba una subrutina para comunicarse con el analizador:
comunicar:
cbi PortD, 7 sbi PortD, 7; Enviar señal de espera en espera: sbic PinD, 6; leer PinD y saltar si 0V rjmp espera retardo 8; retardo para sincronizar (encontrado esto experimentalmente) enviar: dec retardo total 2; retraso para cada recuento de dados cpi total, 0; 0 aquí significa que se han enviado retardos numéricos "totales" breq PC + 2 rjmp send cbi PortD, 7; PD7 a 0V clr total; restablecer el total de dados a 0 ret
En el analizador agregamos una llamada de la rutina principal a la subrutina de comunicación:
analizador de clr; prepárate para un nuevo número
sbic PinD, 6; comprobar PD6 para una señal de 5V rcall comunicarse; si 5V van a comunicar analizador mov, total; salida a la pantalla del analizador rcall analizador
y luego escriba la subrutina de comunicación de la siguiente manera:
comunicar:
clr total; restablecer el total a 0 retardo 10; retraso para deshacerse de rebotes sbi PortD, 7; establezca PB7 en 5V para señal de recepción preparada: retardo 2; espere el próximo número inc total; Incrementar PinD sbic total, 6; si PD6 vuelve a 0V, terminamos la recepción rjmp; de lo contrario, vuelva a realizar un bucle para obtener más datos cbi PortD, 7; restablecer PD7 cuando haya terminado ret
¡Ahí tienes! Ahora cada microcontrolador está configurado para comunicar el resultado de la tirada de dados y luego mostrarlo en el analizador.
Implementaremos una forma mucho más eficiente de comunicarnos más adelante cuando necesitemos transferir el contenido de un registro entre controladores en lugar de solo una tirada de dados. En ese caso, todavía usaremos sólo dos cables que los conecten, pero usaremos 1, 1 para significar "comenzar la transmisión"; 0, 1 para significar "1"; 1, 0 para significar "0"; y finalmente 0, 0 para significar "fin de transmisión".
Ejercicio 1: vea si puede implementar el mejor método y úselo para transferir la tirada de dados como un número binario de 8 bits.
Adjuntaré un video que muestra el mío en funcionamiento.
Paso 3: Conclusión
Adjunto el código completo para su referencia. No está tan limpio y ordenado como me gustaría, pero lo limpiaré a medida que lo ampliemos en futuros tutoriales.
De ahora en adelante, solo adjuntaré los archivos que contienen el código en lugar de escribirlo todo aquí. Simplemente escribiremos las secciones que estamos interesados en discutir.
Este fue un breve tutorial en el que se nos ocurrió un método simple para decirle a nuestro microcontrolador analizador cuál es el resultado de nuestra tirada de dados de nuestro microcontrolador de rodillo de dados mientras solo usamos dos puertos.
Ejercicio 2: En lugar de usar una señal de listo para mostrar cuando el rodillo de dados está listo para transmitir y otro cuando el analizador está listo para recibir, use una "interrupción externa" llamada "Interrupción de cambio de pin". Los pines del atmega328p se pueden usar de esta manera, por lo que tienen PCINT0 a PCINT23 junto a ellos en el diagrama de pines. Puede implementar esto como una interrupción de una manera similar a como lo hicimos con la interrupción de desbordamiento del temporizador. En este caso, el "manejador" de interrupciones será la subrutina que se comunica con el rodillo de dados. De esta manera, no es necesario llamar a la subrutina de comunicaciones desde main: irá allí cada vez que haya una interrupción proveniente de un cambio de estado en ese pin.
Ejercicio 3: Una forma mucho mejor de comunicar y transferir datos entre un microcontrolador a una colección de otros es usar la interfaz serial de 2 cables incorporada en el microcontrolador mismo. Intente leer la sección 22 de la hoja de datos y vea si puede descubrir cómo implementarla.
Usaremos estas técnicas más sofisticadas en el futuro cuando agreguemos más controladores.
El hecho de que todo lo que hicimos con nuestro analizador fue tomar el total de la tirada de dados y luego imprimirlo en binario usando LED no es lo importante. El hecho es que ahora nuestro analizador "sabe" qué es la tirada de dados y puede utilizarla en consecuencia.
En el próximo tutorial cambiaremos el propósito de nuestro "analizador", presentaremos algunos elementos más del circuito y utilizaremos la tirada de dados de una manera más interesante.
Hasta la proxima vez…
Recomendado:
Tutorial 1 del ensamblador AVR: 5 pasos
Tutorial 1 de AVR Assembler: He decidido escribir una serie de tutoriales sobre cómo escribir programas en lenguaje ensamblador para el Atmega328p, que es el microcontrolador utilizado en Arduino. Si la gente sigue interesada, seguiré publicando una por semana más o menos hasta que me quede sin
Tutorial 8 del ensamblador AVR: 4 pasos
Tutorial 8 de AVR Assembler: ¡Bienvenido al Tutorial 8! En este breve tutorial vamos a desviarnos un poco de la introducción de nuevos aspectos de la programación en lenguaje ensamblador para mostrar cómo mover nuestros componentes de creación de prototipos a otro " impreso " placa de circuito. Los
Tutorial de ensamblador AVR 7:12 pasos
Tutorial 7 de AVR Assembler: ¡Bienvenido al Tutorial 7! Hoy vamos a mostrar primero cómo buscar un teclado y luego mostrar cómo usar los puertos de entrada analógica para comunicarse con el teclado.Haremos esto usando interrupciones y un solo cable como aporte. Conectaremos el teclado para que
Tutorial de ensamblador AVR 9: 7 pasos
Tutorial 9 de AVR Assembler: Bienvenido al Tutorial 9. Hoy mostraremos cómo controlar una pantalla de 7 segmentos y una pantalla de 4 dígitos utilizando nuestro código de lenguaje ensamblador ATmega328P y AVR. En el transcurso de hacer esto, tendremos que desviarnos sobre cómo usar la pila
Tutorial de ensamblador AVR 11: 5 pasos
AVR Assembler Tutorial 11: ¡Bienvenido al Tutorial 11! En este breve tutorial, finalmente vamos a construir la primera parte de nuestro proyecto final. Lo primero que debe hacer es ir al último paso de este tutorial y ver el video. Entonces vuelve aquí. [haciendo una pausa mientras