#include <avr/io.h>
#define F_CPU 1e6
#include <util/delay.h>
#include <avr/interrupt.h>
#define Modul1 PORTD, PORTD2
#define Modul2 PORTD, PORTD1
//Anschlussbelegung der 7Seg. Anzeige am Port B
#define Summer PORTB, PORTB0
#define SEGa PORTB, PORTB1
#define SEGb PORTB, PORTB2
#define SEGc PORTB, PORTB3
#define SEGd PORTB, PORTB4
#define SEGe PORTB, PORTB5
#define SEGf PORTB, PORTB6
#define SEGg PORTB, PORTB7
#define setbit(IO) __setbit(IO)
#define __setbit(PORT, BIT) PORT |= (1<<BIT)
#define clearbit(IO) __clearbit(IO)
#define __clearbit(PORT, BIT) PORT &=~ (1<<BIT)
//Entprell-Routine übernommen von "http://www.mikrocontroller.net/attachment/67964/debounce.c"
#define debounce( port, pin ) \
({ \
static uint8_t flag = 0; /* new variable on every macro usage */ \
uint8_t i = 0; \
\
if( flag ){ /* check for key release: */ \
for(;;){ /* loop ... */ \
if( !(port & 1<<pin) ){ /* ... until key pressed or ... */ \
i = 0; /* 0 = bounce */ \
break; \
} \
_delay_us( 20 ); /* * 256 = 25ms */ \
if( --i == 0 ){ /* ... until key >25ms released */ \
flag = 0; /* clear press flag */ \
i = 0; /* 0 = key release debounced */ \
break; \
} \
} \
}else{ /* else check for key press: */ \
for(;;){ /* loop ... */ \
if( (port & 1<<pin) ){ /* ... until key released or ... */ \
i = 0; /* 0 = bounce */ \
break; \
} \
_delay_us( 20 ); /* * 256 = 25ms */ \
if( --i == 0 ){ /* ... until key >25ms pressed */ \
flag = 1; /* set press flag */ \
i = 1; /* 1 = key press debounced */ \
break; \
} \
} \
} \
i; /* return value of Macro */ \
})
volatile int8_t zaehler[2];
volatile uint16_t i;
//Initialisierung
void init( void )
{
DDRB = 0xFF; //Port B Ausgang
PORTB = 0xFE; //Alle Pins, bis auf PB0 HIGH
DDRD = 0b0000110; //Port D Pin6,5,4,3,0 Eingänge; Pin 2,1 Ausgänge
PORTD = 0b1111111; //Alle PullUp-Widerstände 6...3 ein; Ausgänge auf HIGH (PNP Transistoren aus)
}
//Ausgabemuster für 7Segment-Anzeige
//gemeinsame Anode, clearbit schaltet Segment
void SiebenSegAnz(uint8_t a)
{
switch(a)
{
case 9: // gfedcba
{ //PORTB = 0b0010000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 8:
{ //PORTB = 0b0000000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 7:
{ //PORTB = 0b1111000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit(SEGd);
setbit(SEGe);
setbit(SEGf);
setbit(SEGg);
}break;
case 6:
{ //PORTB = 0b0000010x;
clearbit(SEGa);
setbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 5:
{ //PORTB = 0b0010010x;
clearbit(SEGa);
setbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 4:
{ //PORTB = 0b0011001x;
setbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit(SEGd);
setbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 3:
{ //PORTB = 0b0110000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit(SEGe);
setbit(SEGf);
clearbit(SEGg);
}break;
case 2:
{ //PORTB = 0b0100100x;
clearbit(SEGa);
clearbit(SEGb);
setbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
setbit(SEGf);
clearbit(SEGg);
}break;
case 1:
{ //PORTB = 0b1111001x;
setbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit(SEGd);
setbit(SEGe);
setbit(SEGf);
setbit(SEGg);
}break;
case 0:
{ //PORTB = 0b1000000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
setbit(SEGg);
}break;
default:
{ //PORTB = 0b0111111x;
setbit(SEGa);
setbit(SEGb);
setbit(SEGc);
setbit(SEGd);
setbit(SEGe);
setbit(SEGf);
clearbit(SEGg);
}
}
}
int main(void)
{
init();
TCCR0A = (1<<WGM01);
OCR0A = 124; // 1MHz Systemtakt, Interrupt-Periodendauer = 1ms
TIMSK |= (1<<OCIE0A);
TCCR0B = (1<<CS01); //Prescaler 8
sei();
zaehler[0]=9;
zaehler[1]=9;
for(;;)
{
if( debounce( PIND, PD3 ) ) zaehler[0]++;
if( debounce( PIND, PD4 ) ) zaehler[0]--;
if( debounce( PIND, PD6 ) ) zaehler[1]++;
if( debounce( PIND, PD5 ) ) zaehler[1]--;
if((zaehler[0] < 1) || (zaehler[1] < 1)) //Rücksetzen erst möglich wenn ein Zähler auf Null
{
setbit(Summer);
if( debounce( PIND, PD0 ) )
{
zaehler[0]=9;
zaehler[1]=9;
}
}
}
}
ISR(TIMER0_COMPA_vect)
{
if (PORTB & (1<<PB0))
{
i++;
if (i>4000) // ergibt 4s bei 1ms Interruptzeit
{
PORTB &= ~(1<<PB0); // = clearbit(Summer)
i = 0;
}
}
if (PORTD & (1<<PD2))
{
setbit(Modul2); // aus
SiebenSegAnz(zaehler[0]); //Wert von Zähler 1 ausgeben
clearbit(Modul1); // an
}
else
{
setbit(Modul1); // aus
SiebenSegAnz(zaehler[1]); //Wert von Zähler 2 ausgeben
clearbit(Modul2); // an
}
}