Hallo zusammen, brauche Hilfe. Ich möchte per CTC Modus einen 10us Takt erzeugen. Hier der Code: /*CTC & Timer_0*/ #define F_CPU 8000000 #include <util/delay.h> #include <avr/io.h> #include <avr/interrupt.h> #include <stdbool.h> #include "C:\WinAVR-20100110\avr\include\Eigene Header\bit_manipulation.h" #include "C:\WinAVR-20100110\avr\include\Eigene Header\rad_funktion.h" volatile bool Takt=false; //Interrupt erzeugt einen 10us Takt ISR(TIMER0_COMPA_vect) {Takt=true;} int main (void) { //Timer Initialisieren TIMSK|=(1<<OCIE0A); // Overflow aktivieren TCCR0A|=(1<<WGM01); // CTC Modus TCCR0B|=(1<<CS00); // Teiler auf 0 OCR0A=80-1; // Register auffüllen TIFR|=(1<<TOV0); // Überlauf freigabe // (((8000000/0/)/1000)/100))=80 sei(); // Freigabe //E/A Definieren set(DDRB,PB4);set(DDRB,PB3);set(DDRB,PB2);set(DDRD,PD0); int u_sek=0; int m_sek=0; int Sekunde_1=0; bool M1=false; while(1) { if(Takt==true) {u_sek++;if(u_sek>=100) {m_sek++;u_sek=0;}if(m_sek>=1000){Sekunde_1++;m_sek=0;}} if((Sekunde_1>=1)&&(M1==false)) {set(PORTB,PB4);M1=true;Sekunde_1=0;} if((Sekunde_1>=1)&&(M1==true)) {clr(PORTB,PB4);M1=false;Sekunde_1=0;} Takt=false; } } Das Problem: es wird ein 30us Takt erzeugt. Warum ist das so? Wo ist der Fehler? Nutze einen Attiny 2313 mit einem 8MH Quarz. Fuses sind soweit richtig. Jemand eine Idee?
Überlege mal wie viele Takte die ISR braucht und der Rest den Programms. Schätze mal das 80 etwas wenig sind.
Hätte gedacht, dass für so wenig Code 80 Takte reichen. Naja, hab den Teiler jetzt auf 8 gestellt und den Code so geändert, dass er einen 100us Takt erzeugen sollte. (OCR0A=100-1; // Register auffüllen) Aaaber... das selbe Problem. Wieder 300us anstelle von 100us.
ich denke 80 hätten reichen sollen. Aber: deine 30us ergeben sich auch dann, wenn man mal annimmt, dass dein CTC Modus nicht funktioniert und das 0-Setzen des Timers nicht bei 80 sondern bei 256 passiert. Dann ergeben sich rechnerisch die 30us. Jag deinen Code mal durch den Simulator und sieh nach, ob der Timer auch das macht, was er soll.
So, hab noch ein bisschen mit den Vergleichswerten im OCR0A Register gespielt. Wenn ich den Wert erhöhe, ändert sich nicht viel. Setze ich ihn herab, verringert sich der Takt Zyklus. Sobald ich jetzt aber den Programmcode um eine Test-Diode erweitere, muss ich auch den OCR0A Register Wert herabsetzen, um die selbe Taktrate zu erhalten. Ich sehe keinen Zusammenhang zwischen einer Code Erweiterung und der Veränderung des Interrups.
Memnon schrieb: > Sobald ich jetzt aber den Programmcode um eine Test-Diode erweitere Was bitte hat man sich unter einer "Test-Diode" im Programmcode vorzustellen? > Ich sehe keinen Zusammenhang zwischen einer Code Erweiterung und der > Veränderung des Interrups. Hast du dir den Ablauf im Simulator mal angesehen? Warum löscht du das Takt-Flag, auch wenn der Bearbeitungsblock gar nicht aufgerufen wurde?
Über den Takt, der vom Interrupt ausgelöst wird, werden die Zähler betrieben. Diese wird immer am Zyklus Ende abgelöscht. (Das klappt ja auch) Zum Testen habe ich zwei Dioden, die ich im 1 bzw. 10 Sekunden Takt toggle um die Genauigkeit des Interrupt zu testen.
Memnon schrieb: > Über den Takt, der vom Interrupt ausgelöst wird, werden die Zähler > betrieben. Aber nur, wenn der Interrupt nicht während der "if((Sekunde_1>=1)"-Abfragen ausgelöst wird. Sonst wird er gleich wieder gelöscht, obwohl die Variable u_sek noch nicht hochgezählt wurde.
Super, das war mein Denkfehler. Wenn ich das Takt-Bit direkt nach dem us hochzählen ablösche haut alles hin. 100us Takte und auch 10us Takte. Jetzt komme ich endlich weiter. Danke für eure Hilfe.
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.