I'm wanting to build a 5 digit up/down counter. When I can get the simulation to work I'll be much happier buying the bits and pieces to build it. What I have so far uses the ATmega8, but quite frankly any solution would work for me as long as the components are reasonably cheap.

I found a simple up counter on the web and have changed it to include a down function also. I removed some hideous `_delay_ms(1000)` statements from the code which were probably there to prevent multiple counts while the input is being held? It made the counter very slow and unresponsive. Here's what I have so far:
[![Circuit diagram](https://i.stack.imgur.com/DY0ll.jpg)](https://i.stack.imgur.com/DY0ll.jpg)

The problem I have is that it doesn't count up and when it counts down it doesn't display zero.

The code:
 #include 
 #include 
 #include 
 #include 

```
#define F_CPU 4000000

volatile uint16_t digits[5]={0,0,0,0,0}; //INITIALISE VARIABLE TO STORE INDIVIDUAL DIGITS OF THE NUMBER

void breakup(uint16_t num) {  //FUNCTION TO FIND THE INDIVIDUAL DIGITS OF THE NUMBER
                              // AND STORE THEM IN A GLOBAL VARIABLE
    DDRD=0xFF; // INITIALISE PORTD AS ALL OUTPUT
    PORTD=0x00;
    unsigned int i=0;
    while (num!=0) {
        digits[i]=num%10;
        num=num/10;
        i++;
    }
    for(i=0;i<5;i++) {
        PORTD=(1<<i); // 'i'th PORTD GIVEN HIGH
        display(digits[i]);
        _delay_us(600);
        PORTD=(0<<i); //'i'th PORTD GIVEN LOW
    }
}

void display (uint16_t num) { // Bit patterns changed from the original to correct for my hardware layout.
    DDRB=0b11111111;
    PORTB=0xFF;
    switch(num) {
        case 0:
        PORTB=0b00111111;
        break;
        case 1:
        PORTB=0b00000110;
        break;
        case 2:
        PORTB=0b01011011;
        break;
        case 3:
        PORTB=0b01001111;
        break;
        case 4:
        PORTB=0b01100110;
        break;
        case 5:
        PORTB=0b01101101;
        break;
        case 6:
        PORTB=0b01111101;
        break;
        case 7:
        PORTB=0b00000111;
        break;
        case 8:
        PORTB=0b01111111;
        break;
        case 9:
        PORTB=0b01101111;
        break;
        default:
        PORTB=0xFF;
    }
}

int main(void) {
    DDRB=0xFF; //Initialise PORTB as all outputs.
    DDRC=0x00;   //Initialise PORTC as all inputs.
    PORTC=0b01000000;  //Enable internal pullup for the reset pin.
    char x;
    char down_button_press = 0;
    char up_button_press = 0;
    uint16_t i, c=5;
    while(1) {
        x=PINC&0b00000001; //Check condition of PC0 DOWN button.
        if (x==0 && down_button_press==0) {
            c--;
            breakup(c); //Pass c to the breakup routine and display.
            down_button_press++;
        }
        if (x==1) {
        down_button_press = 0;
        }
        x=PINC&0b00000010; //Check condition of PC1 UP button.
        if (x==0 && up_button_press==0) {
            c++;
            breakup(c); //Pass c to the breakup routine and display.
            up_button_press++;
        }
        if (x==1) {
        up_button_press = 0;
        }
        else
        breakup(c);
    }
}

```

The counting up and counting down bits of the code at the end are essentially identical, so I don't know why it counts down, but not up. In an attempt to stop the counter making multiple counts while the button is pressed I have included a sort of latch `&& up_button_press==0`. It's not supposed to be debouncing code, it's just so I get single increments and single decrements with each button press.
What I have managed to work out is that is doesn't count up because the up-latch isn't clearing when the button goes back high - so the `&& up_button_press==0` condition is never true:

```
if (x==1) {
    up_button_press = 0;
    }

```

If someone can help me to get the thing to work I'd appreciate it. I can add the Proteus simulation file if that helps?