Forum: Mikrocontroller und Digitale Elektronik Timer1 problem - Atmega8


von Philipp L. (viech)


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?

: Verschoben durch User
von Uhu U. (uhu)


Lesenswert?

Wie hast du denn die Variable zahl deklariert?

von Sebastian R. (sebastian_r569)


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.

: Bearbeitet durch User
von g457 (Gast)


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.

von Sebastian R. (sebastian_r569)


Lesenswert?

g457 schrieb:
> Ähm.. nein.

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.

: Bearbeitet durch User
von Alex D. (daum)


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.

von Philipp L. (viech)


Lesenswert?

Volatile....

Danke, funzt !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.