2

I recently had a written exam for a class and one of the questions was to write a program for the ATmega8515. I wrote down this:

#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{}
    }
}   

For some reason this does not work.

The expected outcome is that if the first two switches are pressed (SW0 & SW1), it'll scroll the leds from left to right. if the first switch is pressed (SW0), the LEDs will scroll from right to left. And if the second switch is pressed (SW1), the leds will scroll from left to right going back and forth forever

As of now, I know the for loops work, I've tested them in other programs. It just seems like I'm not getting and input from the switches.

Funkyguy
  • 3,588
  • 1
  • 23
  • 45
  • 1
    I modified your question a little bit. You don't need to specifically say "Help would be great," etc. because that's a given here. However, you do need to elaborate a little bit more. What was the expected outcome? When you say "this does not work" you need to specify what it did instead. And if there's anything specific, try to have your audience focus on that instead of the project as a whole. – JYelton Mar 05 '14 at 21:16
  • 1
    Don't forget to mention what it did instead (the not working part). – JYelton Mar 05 '14 at 21:19
  • Always important stuff for helping others to understand your problem and work toward a solution. One last question from me: Are you doing this in simulation or with an actual circuit? – JYelton Mar 05 '14 at 21:23
  • With an actual circuit. It is just the LEDs and Switches on the STK-600 board. – Funkyguy Mar 05 '14 at 21:25

2 Answers2

1

Your code expects three possible states for PORTA inputs, PINA == 0b11111100 or PINA == 0b11111110 or PINA == 0b11111101.

You want to check only PINA.0 and PINA.1 but instead you also check the rest of the bits in the port (b7:b2). This would only work if you have enabled all the internal pull-ups of the port (unless you have connected eight external pull-ups which I doubt)

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

A better solution, just check the state of the two pins which are actually connected to the buttons, discarding the result for the rest of the port bits.

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
        {
        }
alexan_e
  • 11,130
  • 1
  • 29
  • 62
0

I am assuming you have the switches connected to PA0 and PA1, and that you are normally keeping them high with a pull-up resistor (per schematic below.) Pressing the switch then brings the pin low, and that's the input you are looking for. I'll further assume that PA2 through PA7 are all kept high with pull-up resistors.

schematic

simulate this circuit – Schematic created using CircuitLab

I would recommend reading PINA once before the if statement, so that you avoid state changes between conditional statements. For example, if PINA evaluates to one statement, but then changes before the loop completes, a separate conditional statement might execute. (Or maybe that's desired behavior.)

Next, physical switches are noisy and need to be debounced. Consider that your while loop is constantly running and PINA is being continually evaluated. When you press a switch, the pin does not transition cleanly one time from high to low. Instead, it may "bounce" a few times between high and low, in a few milliseconds, before becoming stable. You might want to implement a slight delay from detecting a change on PINA before reading it again and accepting the final value. Switch debouncing is covered by many other sites/answers.

JYelton
  • 34,119
  • 33
  • 145
  • 265