Timer1 problem - Atmega8

#5709052
Lesenswert?

Hallo zusammen,

es ist zwar nicht der erste Thread, hoffe aber trotzdem auf eure 
Unterstützung.

Ich möchte beim Atmega8 (int. 1Mhz) den Timer1 nutzen, bekomme das aber 
nicht hin

void init_1 (void)
{
  DDRD |= (1<<PD0);
  DDRB &= ~(1<<PB1);

  TCCR1A = 0x00;
  TCCR1B = (1<<CS10);
  TIMSK = (1<<TOIE1);
  TCNT1H = 0;
  TCNT1L = 0;
  sei();
}

ISR(TIMER1_OVF_vect)
{
  zahl = zahl + 1;
  TCNT1 = 0;
}

int main(void)
{
  init_1();
    while (1)
    {
  if (zahl >=15 )
    PORTD = (1<<PD0);
  }
}

Der Timer1 sollte doch bei 1Mhz und 15 Durchläufen nach ca.1sek den 
Ausgang einschalten, tut er aber nicht.
Dieser wird leider nie geschaltet

Selbst wenn auf (zahl >= 1) abfrage, wird der Ausgang nie eingeschaltet.
Wenn ich den Ausgang jedoch direkt in der Interrupt Routine setze, wird 
dieser auch sofort aktiviert.
Das deutet doch darauf hin, das die Routine ausgelöst wird..
Dann sollte doch eigentlich auch die zahl hochgezählt werden und den 
Port schalten?
#5709066
Lesenswert?

Ist deine Variable "zahl" als volatile deklariert?

Wenn nicht, dann kann sie nicht in Interrupts verändert werden.

Bevor der Controller in ein Interrupt springt, wird im Prinzip ein 
Backup von den Variablen gemacht. Dann gehts in den Interrupt und das 
Backup wird zurückgespielt, mit dem Wert, den die Variable vor dem 
Interrupt hatte.
Gast #5709087
Lesenswert?

> Bevor der Controller in ein Interrupt springt, wird im Prinzip ein
> Backup von den Variablen gemacht. Dann gehts in den Interrupt und das
> Backup wird zurückgespielt, mit dem Wert, den die Variable vor dem
> Interrupt hatte.

Ähm.. nein.
#5709108
Lesenswert?

Sebastian R. schrieb:
> Dann erklär es bitte besser, anstatt nur zu kritisieren. Vielleicht
> lerne ich auch noch was.
>
> Ich habe Absichtlich Begriffe wie "Stack" vermieden und es so einfach
> wie möglich gehalten.

Volatile sagt dem compiler nur dass sich eine Variable immer ändern 
kann.

Nehmen wir diesen c-code
1
int i = 5;
2
int j = 0;
3
if(i != 5){
4
    j = i;
5
}

Diesen Code wird jeder intelligente compiler zu
1
int i = 5;
2
int j = 0;
machen, da i ja immer 5 ist.

Das gleiche passiert auch mit globalen variablen:
1
int zahl = 0; //wird in ISR verändert
2

3
void main(){
4
    while(1){
5
        if(zahl != 0){
6
            PORTD |= 1 << PD5;
7
        }
8
    }
9
}

Der compiler sieht hier, dass zahl eigenlich immer 0 ist, und optimiert 
das ganze if mit inhalt weg. Das keyword volatile sagt dem compiler, 
dass sich der Wert immer ändern kann und er keine ausdrücke damit 
wegoptimiert und den Wert immer aus dem Speicher liest, wenn er 
gebraucht wird.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren