No obteniendo entrada en STK600 con ATmega8515

2

Hace poco tuve un examen escrito para una clase y una de las preguntas fue escribir un programa para el ATmega8515. Escribí esto:

#include <avr/io.h>
#define F_CPU 4000000UL
#include <util/delay.h>
#define Delay 5000

int main(void){
DDRB = 0xFF;    //set to output
DDRA = 0x00;    //set to input
PORTB = 0xFF;   //turn off all LEDs

while(1) {
    if (PINA == 0b11111100){    //if SW0 and SW1 are pressed
        for(uint8_t i = 7; i<=0; i--){
            PORTB &= ~(1<<i);   //Turn on led at location i
            _delay_ms(Delay);   //Delay
            PORTB |= (1<<i);    //Turn off led at location i
            _delay_ms(Delay);   //Delay
        }
    }
    else if(PINA == 0b11111110){
        for(uint8_t i=0; i>=7; i++){
            PORTB &= ~(1<<i);
            _delay_ms(Delay);
            PORTB |= (1<<i);
            _delay_ms(Delay);
        }
    }
    else if(PINA == 0b11111101){
        for(uint8_t i = 7; i<=0; i--){
            PORTB &= ~(1<<i);
            _delay_ms(Delay);
            PORTB |= (1<<i);
            _delay_ms(Delay);
        }   
        for(uint8_t i=0; i>7; i++){
            PORTB &= ~(1<<i);
            _delay_ms(Delay);
            PORTB |= (1<<i);
            _delay_ms(Delay);
        }
    }
    else{}
    }
}   

Por alguna razón, esto no funciona.

El resultado esperado es que si se presionan los dos primeros interruptores (SW0 & SW1), los leds se desplazarán de izquierda a derecha. Si se presiona el primer interruptor (SW0), los LED se desplazarán de derecha a izquierda. Y si se presiona el segundo interruptor (SW1), los leds se desplazarán de izquierda a derecha yendo y viniendo para siempre

A partir de ahora, sé que los bucles for funcionan, los he probado en otros programas. Simplemente parece que no estoy recibiendo ninguna entrada de los interruptores.

    
pregunta Funkyguy

2 respuestas

1

Su código espera tres estados posibles para las entradas PORTA, PINA == 0b11111100 o PINA == 0b11111110 o PINA == 0b11111101 .

Desea verificar solo PINA.0 y PINA.1, pero en su lugar también verifica el resto de los bits en el puerto (b7: b2). Esto solo funcionaría si ha habilitado todos los pull-ups internos del puerto (a menos que haya conectado ocho pull-ups externos que dudo)

PORTA = 0xff;   // enables internal pull-ups for all bits

Una solución mejor, simplemente compruebe el estado de los dos pines que están realmente conectados a los botones, descartando el resultado para el resto de los bits de puerto.

DDRA = 0x00;    //set to input
PORTA = 0x03;   // enable internal pull-ups for PORTA.0 and PORTA.1

if((PINA & 0b00000011) == 0b00000000)   // check if both button are pressed
{
}

else
    if((PINA & 0b00000011) == 0b00000010) // check if button in PORTA.0 is pressed
    {
    }

    else
        if((PINA & 0b00000011) == 0b00000001) // check if  button in PORTA.1 is pressed
        {
        }
    
respondido por el alexan_e
0

Supongo que usted tiene los interruptores conectados a PA0 y PA1, y que normalmente los mantiene altos con una resistencia de pull-up (según el esquema a continuación). Al presionar el interruptor, el pin baja, y esa es la entrada que estan buscando. Además, asumiré que las PA2 a PA7 se mantienen altas con resistencias pull-up.

simular este circuito : esquema creado usando CircuitLab

Recomendaría leer PINA una vez antes de la instrucción if, para evitar cambios de estado entre las declaraciones condicionales. Por ejemplo, si PINA se evalúa como una declaración, pero luego cambia antes de que se complete el ciclo, podría ejecutarse una declaración condicional separada. (O tal vez es el comportamiento deseado).

A continuación, los interruptores físicos son ruidosos y deben ser rebatidos. Considere que su bucle while se está ejecutando constantemente y que PINA se está evaluando continuamente. Cuando se presiona un interruptor, el pin no realiza una transición limpia de una vez de alta a baja. En su lugar, puede "rebotar" unas cuantas veces entre alta y baja, en unos pocos milisegundos, antes de estabilizarse. Es posible que desee implementar un ligero retraso en la detección de un cambio en PINA antes de volver a leerlo y aceptar el valor final. El debouncing del conmutador está cubierto por many otro sites / respuestas .

    
respondido por el JYelton

Lea otras preguntas en las etiquetas