Interruptbehandlung bei ATMega8
Hi,
ich bau mir gerade einen "Rhythmusrobotter" :)
aus dem Rhythmusteil einer alten Elektroorgel
und 'nem ATMega8 mit 16MHz.
Dazu brauche ich an den Pins PC0 -PC3 je einen Impuls
von ca 10- 40mSek. Mit aktivem Warten hab ich's nun schon
hingekriegt, wuerd's aber lieber mit 'nem Timer Overflow Interrupt
machen.
Ich habe nun den Prescaler von Timer 0 auf 1/1024
bei einer Quarzfrequenz von 16MHz gestellt:
Code:
int Timer_Inits(void)
{
//Timer Interrupt=(Quarzfreq 16000000/8Bit-Ueberlauf 256)/ Prescaler 1024= 16mS
//letzte 3 Bit von Timer Clock Control: Prescaler = Quarz/1024:
TCCR0 = (TCCR0 | (1 << CS00) | (1 << CS02)) & (~(1 << CS01));
//Timer Interrupt Mask Register Bit 1 setzen fuer Timer Overflow Interrupt enable:
TIMSK |=(1<<TOIE0);
return 0;
}
Das sollten dann ca. 16mSek für einen Überlauf sein.
(16M / 256) / 1024.
Meine Frage ist nun, kommt das hin mit der Initialisierungsroutine?
Mit der Interruptbehandlung komme ich noch nicht so klar,
welcher Vektor ist das nun: SIGNAL (SIG_OVERFLOW0) ?
und wie bekomme ich das in meinen Code rein?
Wann muß ich die Interrupts global enabeln?
Code:
int Bass_Drum(void)
{
PORTC |= (1<<PC1); //PC1=Port fuer Bass Drum
//hier muesste dann nach einem Timer 0 Overflow
//der Pin PC1 wieder ausgeschaltet werden.
return 0;
}
Danke schonmal,
tholan
Re: Interruptbehandlung bei ATMega8
Die Initialisierung ist soweit ok. Es ist allerdings u.U. besser, TCCR0 wirklich zu setzen, damit alle Bits den gewünschten Wert haben. Sollte bei dir aber egal sein.
Code:
void Timer_Inits(void)
{
//Timer Interrupt=(Quarzfreq 16000000/8Bit-Ueberlauf 256)/ Prescaler 1024= 16mS
//letzte 3 Bit von Timer Clock Control: Prescaler = Quarz/1024:
TCCR0 = (1 << CS00) | (1 << CS02);
//Timer Interrupt Mask Register Bit 1 setzen fuer Timer Overflow Interrupt enable:
TIMSK |=(1<<TOIE0);
}
Wenn ich's recht sehe, willst du so was wie Timeouts machen: Nen Port an und nach ner bestimmten Zeit wieder aus, wahrscheinlich unterschiedliche Zeiten für die verschiedenen Ports...
Du könntest dir eine Struktur machen mit Countdown-Werten, die du setzt und die in der ISR bis aus 0 zurückgezählt werden, eine Einheit pro Tick (16ms):
Code:
typedef struct
{
uint8_t takt;
uint8_t bass;
...
} countdown_t;
volatile countdown_t countdown;
SIGNAL (SIG_OVERFLOW0)
{
uint8_t i = sizeof (countdown_t);
uint8_t * cd = (uint8_t *) &countdown;
cd += i;
do
{
uint8_t wert = *(--cd);
if (wert)
*cd = wert-1;
} while (--i);
}
Dadurch werden in jedem Tick die Elemente von countdown, die nicht 0 sind, um 1 erniedrigt.
Code:
int main()
{
ioinit();
Timer_Inits();
sei();
// Hauptschleife
while (1)
{
if (countdown.takt == 0)
{
countdown.takt = 200;
countdown.bass = 20;
PORTC |= (1 << 1);
}
if (countdown.bass == 0)
{
PORTC &= ~(1 << 1);
}
}