¿Cómo leo la entrada digital en ATmega16?

17

¿Qué tengo que hacer para leer una entrada digital (botón) en ATmega16 ? ¿Debo 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 está pulsado'.

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

    
pregunta curious

5 respuestas

22

¡Saludos brasileños!

En primer lugar, gracias a Joby por tu ejemplo. En segundo lugar, su ejemplo solo tiene un pequeño error. El número 0x20 no es correcto. Debería ser 0x04. Además, solo como una 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 "~" cambia todos los dígitos, es decir,               el binario ahora es 11111011. Finalmente, el & =               Aplica la lógica "AND" entre DDRD y 11111011.               y el resultado se coloca de nuevo en la memoria DDRD.               Nota: Lo que hace el operador "AND" es para cada bit               en la memoria DDRD, se compara con el número binario               encima. Si el bit en DDRD es 0 y el bit en el               binario en la misma posición de mordida es 1, entonces el               el bit resultante es 0, si el DDRD es 1 y el               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 resultante               el bit siempre es 0. En resumen, el comando DDRD & = ~ (1 < < PD2)               solo cambia el bit PD2 a cero y deja los otros               (ceros o unos) intactos. Parece un poco               un poco complicado, pero una vez que te acostumbras,               Es la mejor manera de cambiar un poco en un bocado sin               cambiando los otros bits.

comentario # 2 : (1 < < PD2) genera el binario 00000100.               Usando la misma lógica "AND" descrita en               comentario # 1, el comando "PIND & 0000100" comprueba               solo si el PIND2 (nuestro pin de entrada donde el botón               está conectado a) está configurado en alto o no. Todo los demás               los pines serán FALSOS ya que los bits binarios se establecen en 0,               y como el bit binario # 2 se establece en 1, la instrucción IF               será VERDADERO solo si la entrada PD2 está configurada en alto               o FALSE si la entrada PD2 está configurada en bajo.

comentario # 3 : Siguiendo la lógica explicada en el comentario # 1, este               comando establece el pin PINB2 de salida 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 eso               La resistencia está conectada a tierra, el LED debería encenderse.

comentario # 4 : el LED debería 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 el    no se presiona el botón (circuito abierto), lo recomiendo fuertemente    para colocar una resistencia desplegable (1 kOhm o superior), de modo que el    El LED no se enciende accidentalmente debido a este voltaje aleatorio    oscilación.

b) Una nota de descargo de responsabilidad: las ideas que se describen aquí se deben utilizar como    Solo para uso educativo y NO deben usarse en ningún sistema real    Antes de consultar a un experto en electrónica.

* /

    
respondido por el user3270
2

enlace

enlace

#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;
}
    
respondido por el Toby Jaffey
2

Hackaday tenía un gran escrito para la programación de AVR, tiene mucha información excelente que podría ayudarte

enlace

enlace

enlace

enlace

    
respondido por el jsolarski
0

Bueno, esto es para el AT90Usb1287, un ATMega, pero el botón básico debe ser más o menos lo mismo. Solo cambia los nombres IO.

respondido por el Johan
0

Otra cosa que se debe tener en cuenta cuando se trata de una entrada digital de un interruptor mecánico es que los contactos rebotan, cambiando lo que debería ser un solo botón pulsando lo que parece ser múltiples pulsaciones.

Para algo como encender un LED cuando se presiona el botón, es probable que no tenga que preocuparse por los anuncios. Para algo un poco más complicado (como encender el LED al presionar el botón), el debouncing es una necesidad.

Jack Ganssle tiene una buena Guía para hacer denuncias

    
respondido por el mike

Lea otras preguntas en las etiquetas