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
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
> 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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.