Timer1 problem - Atmega8

OP #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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.