hi, ich hab mit meinen kollege ein "taskmanager" erstellt der soll alle 20ms abgearbeitet werden und wenn er länger als 20 ms braucht soll eine LED aufleuchten. das problem ist das selbst wenn wir alles auskommentiert haben oder die tasks leer lassen die 20ms anscheinend überschritten werden. TCCR2A = (1<<WGM21) |(0<<WGM20) | (0<<COM2A1) | (1<<COM2A0) | (1<<CS22) | (1<<CS21) | (1<<CS20) ; OCR2A= 76; int task_state = 0; uint8_t Led_status=0; while (1) { { //*********** Taskmanager alle 20ms*************************** ocr2a >> "75" switch (task_state) { case (0): { } break; case (1): { } break; case (2): { } break; case (3): { } break; case (4): { } break; default: { } break; } if (task_state == 4) { task_state = 0; } else { task_state ++; } if (bit_is_set(TIFR2,OCF2A)) { PORTB |= (1<<PB4); //FEHLER: Task Dauert zu lang! } while (bit_is_clear(TIFR2,OCF2A)) // Warte bis Timer Compare Match Flag gesetzt ist { //irgendwas unkritisches tun (idle-Task) } TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen } } return 0; }
marcel schrieb: > TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der Kommentar nicht stimmt. Das Bit wird hiermit gesetzt. Dieses Bit wird von der Hardware gesteuert. Das ist noch nicht die Lösung deines Problems. An dieser Stelle kannst du weitersuchen. Gruß Guido
1 | // irgendwas unkritisches tun (idle-Task)
|
Und der Timer läuft so lange weiter... Guido Scheidat schrieb: >> TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen > Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der > Kommentar nicht stimmt. Das Bit wird hiermit gesetzt. Alle 3 Behauptungen sind falsch. Das solltest du nochmal genauer nachlesen...
OK, ich werde lesen. Sprechen wir vielleicht von verschiedenen Prozessoren? Sorry!
im handbuch steht "Alternatively, OCF2A is cleared by writing a logic one to the flag."
Guido Scheidat schrieb: >> TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen > > Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der > Kommentar nicht stimmt. Das Bit wird hiermit gesetzt. naja, irgendwer muß ja OCF2A wieder zurücksetzen, wenn da kein Interrupt ist der das üblicherweise tun würde
>> TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen > "Alternatively, OCF2A is cleared by writing a logic > one to the flag." Und wenn es im TIFR2 weitere solche Flags gibt, die man benutzt, darf man keine ODER Operation benutzen! Mit dem ODER löscht man nämlich auch die anderen gesetzten Flags! Richtig ist, wenn überhaupt: TIFR2 = (1<<OCF2A)
TIFR2 |= (1<<OCF2A); //Timer Compare Match Flag rücksetzen eigentlich bräuchte ich diesen aufruf doch gar nicht, wenn alles läuft muss doch gar kein interrupt aufgerufen werden ich brauch doch nur wenn die zeit überlaufen wird, was mit (if bit is set) ja abgefragt wird, eine meldung. hab jetzt mal ein anderen Port benutzt komischerweise treten jetzt keine fehler mehr auf was bei Portb 4 noch der fall war
Irgendwie haben sich hier viele Missverständnisse eingeschlichen. ich habe jetzt gelesen und bin auf folgende Info gestoßen: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ver.C3.A4ndern_von_Registerinhalten somit wird mit "TIFR2 |= (1<<OCF2A);" ein Bit gesetzt. Jetzt zum Vorhaben. Ich hatte ganz übersehen, dass es sich nicht um ein interruptgesteuertes Programm handelt. Ist es wirklich so, dass OCF2A durch die Hardware zurückgesetzt wird, wenn die Zeit abgelaufen ist? Passiert das auch, wenn man keine Interrupts verwendet? Kann das jemand mal mit AVR-Studio testen? Ich habe gerade keines zur Hand.
@ Guido > ich habe jetzt gelesen und bin auf folgende Info gestoßen: > http://www.mikrocontroller.net/articles/AVR-GCC-Tu... > somit wird mit "TIFR2 |= (1<<OCF2A);" ein Bit gesetzt. Das ist richtig für normale Variablen und SFRs. >> "Alternatively, OCF2A is cleared by writing a logic >> one to the flag." Genau da geht es aber nicht mit dem ODER! Bsp: TIFR2 = 0b10000001; Du willst Bit0 löschen TIFR2 |= 0b00000001; Dann ist anschliessend TIFR2 gleich 0b00000000 !!! ^ ^ Wieso? TIFR2 |= 0b00000001; Ist eine Kombination aus (volatile Charakter von TIFR2 mal aussen vor) 1) TIFR2 einlesen 2) eingelesenes TIFR2 mit 0b00000001 verodern 3) Ergebnis in TIFR2 schreiben Der Haken ist Schritt 2: 0b10000001 | 0b00000001 = 0b10000001 Und dann die Zuweisung TIFR2 = 0b10000001 Damit ist Bit0 und Bit7 gelöscht, wenn Bit0 und Bit7 solche Spezialbits sind, die durch Beschreiben mit 'ner log. 1 gelöscht werden!
Krapao schrieb: > Genau da geht es aber nicht mit dem ODER! völlig richtige Analyse. Ergänzend: Genau das ist nämlich auch der Grund, warum diese Register sich anders verhalten: Damit man eben NICHT erst das Register auslesen, den Wert verodern und neu schreiben muss. Denn diese 3-er Kombination ist nicht atomar, was man aber beim Löschen derartiger Bits sein möchte. D.h. man WILL eine Operation haben, die garantiert in einem Ausführungszyklus dieses Bit und nur dieses Bit löscht.
:
Wiederhergestellt durch User
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.