Saltar al contenido

Interruptores de lectura con ATtiny2313

julio 5, 2021
FLE8QMWFKR119LG

Ha habido varios Instructables relacionados con las salidas del ATtiny2313 y dispositivos AVR similares. Por ejemplo, https://www.instructables.com/id/Ghetto-Programming%3a-Getting-started-with-AVR-micro/, https://www.instructables.com/id/Drive-a-Stepper- Motor-con-un-microprocesador-AVR /. Trabajando en el último de The Real Elliot, que mostraba cómo controlar motores paso a paso, descubrí que sería realmente útil poder ejecutar secciones alternativas de código en el mismo programa para no tener que reprogramar el ATtiny2313 cada uno. vez que quería probar una ligera variación de código (como medio paso o ejecutar el paso a paso en reversa). Si bien es fácil escribir código usando una instrucción switch / case para permitir la selección de variaciones alternativas, se necesita alguna forma de seleccionar el caso. Eso significa que se debe leer algún tipo de dispositivo de entrada para controlar el caso.

Afortunadamente, el ATtiny2313 tiene muchos pines de E / S y está bien diseñado para leer las entradas de los interruptores. Este Instructable mostrará cómo leer las entradas y tomar decisiones en función de su estado. Dado que solo eso haría un Instructable bastante aburrido, explicaré una forma simple de usar la capacidad de temporizador / contador del ATtiny2313 para manejar un pequeño altavoz como un buscapersonas. También habrá una pequeña digresión sobre técnicas sencillas de depuración.

Paso 1: el dispositivo de entrada

El dispositivo de entradaEl dispositivo de entrada

Este Instructable se basa en el excelente trabajo de The Real Elliot y utiliza el sistema de desarrollo ATtiny2313 Ghetto que describe. La hoja de datos ATtiny2313 de Atmel es la última referencia para todas las funciones, pero no es necesariamente fácil de leer. http://www.atmel.com/dyn/products/datasheets.asp?family_id=607 (El enlace tiene todas las hojas de datos del AVR, localice el 2313).

La figura muestra un conjunto simple de interruptores de entrada. Este es simplemente un paquete de cuatro interruptores de encendido / apagado; también conocidos como interruptores unipolares y de un solo tiro (SPST). Por lo general, una conexión, o polo, de cada interruptor está conectado a tierra mientras que la otra conexión se eleva a través de una resistencia limitadora de corriente (aproximadamente 10 K). Una entrada de microcontrolador está conectada al poste con la resistencia. Si el interruptor está abierto, el microcontrolador leerá la entrada como HI. Si el interruptor está cerrado, el microcontrolador leerá la entrada LO. Consulte el esquema para obtener más detalles.

El ATtiny2313 simplifica las cosas al proporcionar resistencias pull-up programables en los pines de E / S cuando se configuran como entradas. Esto significa que los interruptores pueden tener simplemente un polo conectado a tierra (LO) y el otro polo conectado a una entrada de procesador. El primer ejemplo muestra solo dos interruptores. Los conmutadores se leen y configuran con el siguiente código.

Configure los interruptores como entradas:
(No se requiere código; este es el predeterminado).
Encienda las resistencias pull-up:
PORTB = _BV (PB0) | _BV (PB1);
Lea las entradas:
but1 = ~ PINB & 0x03;
Tenga en cuenta el uso de inversión y enmascaramiento para obtener el valor correcto.

Paso 2: luces intermitentes para una señal

Usaremos estos dos interruptores para hacer parpadear un LED un número programable de veces. Los LED que usaremos serán las luces intermitentes que hizo famoso The Real Elliot. Los interruptores 1 y 2 se tratarán como dos dígitos binarios, por lo que la combinación puede representar los números 0, 1, 2 y 3. Nuestro programa leerá los dos interruptores y hará parpadear el LED el número apropiado de veces, pero solo si el interruptor la configuración ha cambiado. Los interruptores se eliminan durante 500 milisegundos (no optimizados). El algoritmo antirrebote es bastante simple. Se leen los interruptores y se anota la lectura. Si es diferente del valor de oldBut (el último valor guardado), entonces el programa se retrasa 500 milisegundos y los interruptores se leen de nuevo. Si el valor es el mismo que el leído anteriormente, el valor de oldBut se actualizará y el LED parpadeará el número de veces que implica el valor binario de los dos interruptores. Note la inversión del valor ya que un interruptor que está “encendido” lee LO. Los interruptores se explorarán continuamente en busca de cambios adicionales.

Consulte Instructables anteriores de The Real Elliot para obtener más información sobre las luces intermitentes. Echa un vistazo a esto http://www.ganssle.com/debouncing.pdf para obtener más información sobre los interruptores antirrebote.

Aquí está el código ATtiny2313 para este ejemplo. En funcionamiento, este programa hará parpadear el LED en PB4 (pin físico 8) dos veces para mostrar que está inicializado. Luego leerá los interruptores uno y dos, y parpadeará de una a tres veces dependiendo de la configuración del interruptor cada vez que se cambien. Cuando los interruptores no cambian, el LED parpadeará lentamente.

Para ejecutar este código, cree un nuevo directorio (llámelo “Básico” si lo desea) y descargue el siguiente archivo de código C y makefile en él. Cambie el nombre de Makefile1.txt a solo Makefile. Usando WinAVR, compile el programa y cárguelo en su ATtiny2313.

Paso 3: una pequeña digresión sobre la depuración.

Si eres como yo (y cualquier otro programador del mundo) probablemente hayas experimentado momentos en los que el código “libre de errores” que has escrito y compilado cuidadosamente no hace lo que esperabas. ¡Quizás simplemente no hace nada! ¿Entonces, cuál es el problema? ¿Cómo vas a averiguarlo?

Afortunadamente, existen varios enfoques para hacer que las cosas funcionen. (Obtenga este libro para obtener un excelente tratamiento del tema de la depuración. http://www.debuggingrules.com/) Me gustaría ofrecer algunas sugerencias sencillas relacionadas con el tema de la depuración de aplicaciones de microcontroladores.

El primer paso es basarse en lo que sabe. Si ha conseguido que una luz intermitente funcione una vez, úsela de nuevo para ver dónde se encuentra en su programa. Me gusta que el LED parpadee dos veces para indicar el inicio del programa. Puede poner el código para hacer esto inicialmente al comienzo de su programa. Una vez que sepa que no hay ningún problema con su hardware, cree una función para hacer el parpadeo. Esta es la función que utilizo.

/ * ———————————————— ————————
** blinkEm – función para hacer parpadear el LED usando PD4
** PD4 debe configurarse como salida.
** ———————————————— ——————— * /
void blinkEm (uint8_t count) {
while (cuenta> 0) {
PORTD = _BV (PD4);
_delay_ms (1000);

PORTD = ~ _BV (PD4);
_delay_ms (1000);
contar–;
}
}

Ahora es posible usar esta función en varios puntos de su código como una señal de que el código se ha ejecutado hasta ese momento. Saber que el código se está ejecutando significa que puede examinar cuidadosamente cada sección que se ha ejecutado, pero que no hizo lo que esperaba, para encontrar errores.

Cambiar una cosa a la vez es una técnica clave para la depuración también (descrita en la referencia anterior). Este método clásico funciona junto con “divide y vencerás”: dar pequeños pasos para agregar funcionalidad de manera incremental. Esto puede parecer un enfoque lento, pero no es tan lento como tratar de depurar una gran sección de código que no funciona de una vez.

Paso 4: más depuración

Hay muchas ocasiones en las que queremos verificar una sección de código omitiendo la mayoría de las líneas y luego habilitándolas una a la vez a medida que verificamos que cada una funciona. Normalmente, hacemos esto “comentando” las líneas que queremos omitir. Una extensión de esta técnica es cortar y pegar un bloque de código, comentar el original (para que no lo perdamos) y piratear la copia.

C tiene cuatro formas sencillas de comentar líneas.
Poner “//” delante de una línea comenta esa línea.
Incluir una o más líneas entre “/ *” y “* /” comentará una sección completa. Para que este método funcione eficazmente, no debe haber ningún otro “* /” en el bloque de código (aparte del final). Entonces, una disciplina efectiva es usar // para comentarios dentro de bloques de código y reservar la construcción / * * / para bloques de comentarios y para comentar secciones de código.
Colocando “#if 0” al comienzo de un bloque para comentar y terminando la sección con “#endif”.
Es posible un control más selectivo utilizando “#ifdef (identificador)” al comienzo de un bloque y “#endif” al final. Si desea que el bloque se compile, use “#define (identifier)” anteriormente en el programa. Tenga en cuenta que las comillas son solo para enfatizar y no deben incluirse.

La combinación de estas técnicas debería proporcionar un enfoque útil para depurar sus programas ATtiny2313. Puede encontrar estas herramientas útiles a medida que avanzamos en este Instructable.

Paso 5: Uso del temporizador / contador 0 para pitidos

Uso del temporizador / contador 0 para pitidos

El ATtiny2313 tiene dos potentes recursos de temporizador / contador: uno de 8 bits y otro de 16 bits. Estos pueden configurarse como generadores de frecuencia, controladores de modulación de ancho de pulso variable y registros de comparación de salida. La funcionalidad completa de estos se describe en 49 páginas de la hoja de datos. Sin embargo, usaremos un caso simple. Solo se utilizará el Temporizador / Contador 0 (el de 8 bits) y se utilizará simplemente como generador de frecuencia. La frecuencia se enviará a un pequeño altavoz para producir un pitido. El temporizador / contador 0 se describe completamente en las páginas 66 a 83 de la hoja de datos de ATtiny2313. Una lectura atenta de este material le proporcionará una comprensión completa de Time / Counter 0. Afortunadamente, un modo bastante simple, Clear Timer on Compare (CTC), es todo lo que se requiere para generar el tono de bip que queremos.

Para el modo que usaremos, el funcionamiento del temporizador / contador es sencillo. Cuando se selecciona una señal de reloj, el contador comienza en cero e incrementa cada pulso de reloj. Cuando el valor del contador alcanza el valor en el registro de comparación de salida (TOP), el contador se restablece a cero y el conteo comienza de nuevo. El bit de salida asociado con el temporizador / contador se alterna para producir una salida de onda cuadrada. Esto impulsa directamente un transductor de audio para que emita un pitido.

Un pequeño transductor de audio TDK produce el pitido. Una unidad adecuada es Digikey 445-2530-ND, TDK SD1209T3-A1 (utilicé una versión anterior de esto). Esta es una versión de 3 voltios; la versión de 5 voltios también funcionará, espero. Conduzco esto directamente desde el puerto de salida del Attiny2313 y parece funcionar bien. Sparkfun tiene un dispositivo similar.

Paso 6: Configuración del temporizador / contador 0

El modo CTC se puede utilizar para alternar la salida OC0A en el pin 2, puerto B (pin físico 14). Para habilitar la salida en este pin, DDRB debe configurarse apropiadamente. El código C para esto es como configurar una salida para una luz intermitente.

DDRB = _BV (PB2); // El puerto B2 es una salida.

El siguiente paso es suministrar una señal de reloj y cargar el registro de comparación de salida para producir una forma de onda como frecuencia. La ecuación para la frecuencia resultante se da en la hoja de datos (página 72). Los términos de la ecuación se describirán a continuación. Aquí está la ecuación:

fOC0A = fclk_I / O / 2 * N * (1 + OCR0A)

Donde fOC0A: = frecuencia de salida
fclk_I / O: = frecuencia de la fuente de reloj
N: = factor de preescala del reloj
OCR0A: = valor en el registro de comparación de salida para el temporizador / contador 0A.

Frecuencia de la fuente de reloj, fclk_I / O
Esta es la frecuencia del reloj del sistema. El valor predeterminado es 1 MHz. Los bits CS00, CS01 y CS02 de TCCR0B controlan esta selección. Dado que estos bits también seleccionan el valor de N, se describe a continuación.

Valor de preescalador, N
N es el valor utilizado para dividir, o preescalar, el reloj del sistema. Los bits CS00, CS01 y CS02 de TCCR0B controlan esta selección. La Tabla 41 en la página 81 de la hoja de datos de ATtiny2313 describe las combinaciones. Dado que se desea una frecuencia cercana a 1 kHz, se establecerán los bits CS00 y CS01 de TCCR0B. Tenga en cuenta que establecer los tres bits en 0, por lo que no se selecciona ninguna fuente de reloj, detiene efectivamente la salida. Este es el método que se utilizará para iniciar y detener el pitido.

Valor SUPERIOR, OCR0A
Este valor es el valor SUPERIOR para el contador que se carga en el registro de comparación de salida para el temporizador / contador 0A. Cuando se alcanza este valor, el contador se restablecerá a cero y el conteo comenzará nuevamente hasta que se alcance TOP y el ciclo se repita. TOP se modifica fácilmente, …

close