Hi Leutz bin noch ziemlich frisch auf dem Gebiet. Meine Frage: Wieso zählt der TCNT0 nicht hoch oder sieht Jemand einen Fehler im Code. Ich benutze einen Atmega8 mit 4.000 MHz #include <avr/io.h> int takt; int sekunde; void setup (void) { TCCR0 |= ( 1<<CS02 )|( 1<<CS00 ); //counter0,Prescaler CK/1024 TIMSK |= ( 1<<TOIE0 ); // enable counter0 overflow interrupt TCNT0 = 0x00; // Counter0 auf Null setzen takt = 0; // 4.000.000 1024 256 = 15 sekunde = 0; } void aus (void) { if(TCNT0 == 0xFF) { TCNT0 = 0x00; takt++; if (takt == 15) { sekunde++; takt = 0; } if(sekunde == 1) { sekunde = 0; if(PORTB == 0x01) { PORTB = 0x00; } else { PORTB = 0x01; } } } } int main (void) { setup(); DDRB = 0xFF;; while(1) { aus(); } }
In dem Programm sind mehrere Probleme, die nicht da wären, wenn du dir das Tutorial zum Timer genau angesehen hättest. Du hast kein echtes Timer-Programm. Du schaltest zwar den enable counter0 overflow interrupt ein, hast aber keine Interrupt Service Routine ISR dafür. Und du schaltest die Interrupts nicht global mit sei() frei. Zum Glück, denn wegen der fehlenden ISR würde das Programm abstürzen. In der aus() fragst du TCNT0 auf 0xFF ab. Es kann passieren, dass deine Aufrufe von aus() langsamer sind als der Timer0 zählt. Dann ist es Zufall mal TCNT0 == 0xFF zu erwischen. Oder die Aufrufe von aus() sind wesentlcih schneller als der Timer0 hochzählt. Dann erwischst du TCNT0 mehrfach im Zählzustand 0xFF. Abhilfe ist exakt dann einen Interrupt auszulösen, wenn der Timer0 Zähler von 0xFF auf 0x0 wechselt - die ISR eben.
Deine LED (oder was auch immer du an dem Port Pin angeschlossen hast) blinkt mit rund 1kHz. Ich denke nicht, dass du das sehen wirst. Dein Programm .... es ist zwar unorthodox und du hast da ein paar Dinge, die man so nicht macht, aber richtiger Fehler ist da erst mal keiner drinn. Du hast die (schlummernden) Fehler alle mit eventuell ein wenig Glück erfolgreich umschifft. Du hast zwar den Overflow Interrupt freigegeben, hast aber keine ISR dafür. Da du die Interrupts nicht mittels sei generell freigegeben hast, passiert da also nichts. Einen TCNT0 direkt abfragen bedeutet, dass die Abfrage schneller sein muss, als der Timer zählt, damit du den Zählerstand genau erwischt. Da du einen Vorteiler von 1024 hast, wird das in deinem Fall sogar der Fall sein. Und da du den Timer händisch auf 0 zurücksetzt, kriegst du den Zählerstand von 0xFF tatsächlich auch nur 1 mal mit. All das sind eigentlich No-No's. Allerdings wirken sie sich momentan (noch) nicht aus.
OK danke erstmal für die Tipps ich schau mir jetzt Erstmal das Tutorial an habe da etwas falsch verstanden denke ich.
Karl heinz Buchegger schrieb: > Deine LED (oder was auch immer du an dem Port Pin angeschlossen hast) > blinkt mit rund 1kHz. Ich denke nicht, dass du das sehen wirst. Hmm. Da dürfte ich mich am Taschenrechner vertippt haben. Erneutes nachrechnen bringt 1Hz zu Tage 4000000 / 1024 = 3906 3906 / 255 = 15 und dann noch durch 15 macht 1 Also das passt
so hab das Programm bischen verändert aber das funktioniert irgend wie nicht. Meine Rechnung: MHz Vorteiler 8-Bit-Timer = Overflows pro Sekunde 4.000.000 1024 256 = 15 bei der Simulation habe ich Festgestellt das er die ganze Zeit in der ISR bleibt. Wieso??? #include <avr/io.h> #include <avr/interrupt.h> int sekunde; void setup (void) { TCCR0 |= ( 1<<CS02 )|( 1<<CS00 ); //counter0,Prescaler auf 1024 TIMSK |= ( 1<<TOIE0 ); //counter0 overflow interrupt TCNT0 = 0x00; //Counter0 auf Null setzen sei(); //Interrupts global aktivieren } ISR(TIMER0_OVF_vect) { sekunde ++; } int main (void) { DDRB = 0xFF; setup(); while(1) { if(sekunde >= 15) { sekunde = 0; if(PORTB == 0x01) { PORTB = 0x00; } else { PORTB = 0x01; } } } }
Siehe den Abschnitt http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Datenaustausch_mit_Interrupt-Routinen volatile ist hier nämlich das Problem. MfG Mark
Besser so, aber noch nicht einwandfrei :-) Und jetzt nicht aufgeben, sondern im Artikel Interrupt nachlesen, was es mit atomaren Zugriff auf Variablen zu tun hat und wieso volatile allein nicht reicht. Dann hast du dir einen Riesenbatzen AVR-Wissen angeeignet!
ok danke das ist echt super hier man bekommt sehr schnell Hilfe. bin jetzt dabei das AVR-GCC-Tutorial zu lesen.
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.