¿Cómo leo la entrada digital en ATmega16?

18

¿Qué debo hacer para leer una entrada digital (botón) en ATmega16 ? ¿Tengo que habilitar las resistencias pullup o puedo usar una de 10 kohm? ¿Cuál sería un código simple? Solo un simple 'Enciende el LED cuando se presiona'.

¿Hay un tutorial para principiantes? He intentado buscar en Google y AVR Freaks , pero todo se convierte en una pelea allí y no obtengo mi respuesta. Realmente no he encontrado ningún tutorial sobre estas cosas. Toneladas de cosas específicas pero nada simple sobre mi microcontrolador AVR ...

curioso
fuente
44
Esto se respondería en casi cualquier tutorial para principiantes, y me temo que una respuesta completa aquí socavaría su comprensión más que la ayuda. ¿Qué esfuerzo previo has hecho para aprender?
Yann Vernier
No estoy seguro de si vio mi publicación o si puede verla (lo siento, todavía estoy un poco confundido acerca de este sitio ...) Pero conozco el código, digamos que mi pregunta es: ¿acabo de conectar un pin a GND y es bajo?
curioso
2
¿Por qué no editar su publicación para reflejar esto con mayor precisión e incluir la publicación a continuación en la publicación original también?
Amós
Pruebe el Tutorial AVR From-Scratch en esta página AVR Freaks. Encontrarás muchas más cosas allí.
Leon Heller

Respuestas:

24

Saludos brasileños!

En primer lugar, gracias Joby por tu ejemplo. En segundo lugar, su ejemplo tiene solo un pequeño error. El número 0x20 no es correcto. Debería ser 0x04. Además, solo como sugerencia, no usaría números hexadecimales como 0xFB, 0x20 o 0x04 en el código. Sugeriría usar las definiciones de puerto PIN que se encuentran en io.h y otras a las que hace referencia el archivo de encabezado. He reescrito el ejemplo de Joby a continuación, con algunos comentarios para los principiantes.

# include <avr/io.h>

int main (void)
{
    // set all pins on PORTB for output
    DDRB = 0xFF;

    // set port pin PORTD2 as input and leave the others pins 
    // in their originally state (inputs or outputs, it doesn't matter)
    DDRD &= ~(1 << PD2);        // see comment #1

    while (1) 
    {
        if (PIND & (1<<PD2))    // see comment #2
            PORTB |= (1<<PB2);  // see comment #3
        else
            PORTB &= ~(1<<PB2); // see comment #4
    }
    return 0;
}

/ *

comentarios para principiantes

comentario # 1: (1 << PD2) genera el binario 00000100. La operación "~" invierte todos los dígitos, es decir, el binario ahora es 11111011. Finalmente, el & = aplica la lógica "Y" entre DDRD y 11111011 y el resultado se coloca nuevamente en memoria DDRD. Nota: Lo que hace el operador "Y" es para cada bit en la memoria DDRD, se compara con el número binario anterior. Si el bit en DDRD es 0 y el bit en el binario en la misma posición de mordida es 1, entonces el bit resultante es 0, si el DDRD es 1 y el bit en el binario es 1, el bit resultante es 1, y si el bit en el DDRD es 1 o 0 y el bit en el binario es 0, entonces el bit resultante es siempre 0. En resumen, el comando DDRD & = ~ (1 << PD2) cambia solo el bit PD2 a cero y deja los otros (ceros o unos) intactos. Parece un poco complicado, pero una vez que te acostumbras, es la mejor manera de cambiar un poco sin cambiar los otros bits.

comentario # 2 : (1 << PD2) genera el 00000100 binario. Usando la misma lógica "Y" descrita en el comentario # 1, el comando "PIND & 0000100" verifica solo si el PIND2 (nuestro pin de entrada donde está conectado el botón pulsador a) se establece en alto o no. Todos los demás pines serán FALSOS ya que los bits binarios están configurados en 0, y dado que el bit binario n. ° 2 está configurado en 1, la instrucción IF será VERDADERA solo si la entrada PD2 está configurada en alta o FALSA si la entrada PD2 es puesto a bajo.

comentario # 3 : Siguiendo la lógica explicada en el comentario # 1, este comando establece el pin de salida PINB2 en el puerto PORTB a alto voltaje. Si su LED está conectado correctamente a este puerto de pin con una resistencia de ~ 300 ohmios, y esa resistencia está conectada a tierra, el LED debería encenderse.

comentario # 4 : El LED debe apagarse por las mismas razones explicadas en los comentarios anteriores.

Consideraciones finales:

a) Para evitar la oscilación de voltaje en el pin de entrada PD2 cuando no se presiona el botón (circuito abierto), recomiendo encarecidamente colocar una resistencia desplegable (1 kOhm o más), de modo que el LED no se encienda accidentalmente debido a esta oscilación de voltaje aleatorio.

b) Una nota de renuncia: las ideas descritas aquí deben usarse solo con fines educativos y NO deben usarse en ningún sistema real antes de consultar a un experto en electrónica.

* /

Comunidad
fuente
3
No lo aliento a que envíe su correo electrónico porque la correspondencia por correo electrónico hace que la comunicación sea privada. Entonces nadie más puede beneficiarse. Pero si realmente desea proporcionar su correo electrónico para comunicaciones privadas, el mejor lugar para hacerlo es en su perfil.
Daniel Grillo
¿No es al revés: el n. ° 3 apaga el led y el n. ° 4 enciende el led?
sitilge
2

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/#digital-in

#include <avr/io.h>

/*
 * Assumptions:
 *  - LED connected to PORTB.2
 *  - Switch connected to PORTD.2
 */

int main (void)
{
    /* set PORTB for output*/
    DDRB = 0xFF;
    /* set PORTD for input*/
    DDRD &= 0xFB;
    PORTD |= 0x04;

    while (1) {
        if (PIND & 0x04)
            PORTB &= ~0x20;
        else
            PORTB |= 0x20;
    }
    return 0;
}
Toby Jaffey
fuente
Gracias a @joby Taffey por el enlace suministrado. Estaba buscando funciones EEPROM y obtuve mucha ayuda de: mainframe.cx/~ckuethe/avr-c-tutorial/lesson11.c Muchas gracias.
Bishal Paudel
0

Algo más a tener en cuenta cuando se trata de una entrada digital de un interruptor mecánico es el rebote de los contactos: cambiar lo que debería ser un solo botón en lo que parece ser un impulso múltiple.

Para algo como encender un LED cuando se mantiene presionado el botón, probablemente no tenga que preocuparse por el rebote. Para algo un poco más complicado (como alternar el LED al presionar el botón), es necesario eliminar el rebote.

Jack Ganssle tiene una buena guía para el rebote

Miguel
fuente