Hey, Bin neu im Form habe aber schon etwas Erfahrung mit der Programmierung in C. Wollte euch bitten mal meinen Code anzuschauen und mir sagen warum die ISR nicht ausgeführt wird. Vielen Dank für eure Hilfe MfG. #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> #include "ports_init_4bit.h" volatile unsigned int millisekunde =0; volatile unsigned int sekunde =0; volatile unsigned int minute =0; volatile unsigned int stunde =0; int main(void) { INITIALISIERUNG_SYSTEMPORTS(); //Ports initialisieren TCCR2=0b00001100; OCR2=250-1; sei(); //Global Interrupt Flag freischalten TIMSK=(1<<OCIE2); //Timer/Counter 2 Interrupt Register freigeschalten while(1) { if (sekunde==2) { PORTD|=(1<<PD7); if (sekunde==4) { PORTD&=~(1<<PD7); } } } } ISR (TIMER2_COMP_vect) { millisekunde++; if (millisekunde==1000) { millisekunde=0; sekunde++; } if (sekunde==60) { sekunde=0; minute++; } if (minute==60) { minute=0; stunde++; } }
TCCR2=0b00001100; Ist da bei irgendeinem dieser Bits ein CS Bit dabei? Biiiiiiitteeee Schreib das nicht in Binärschreibweise. Da sieht man genau gar nichts, wenn man nicht zufällig die Bitbelegung der Konfigurationsregister komplett auswendig weiss. Schreibs doch so TCCR2 = ( 1 << CS20 ) | ( 1 << CS21 ); oder welches Bit du dann eben brauchst. Dann sieht man zumindest, dass du ein oder mehrere CS Bits setzt und weiß: Jup, da ist zumindest ein Vorteiler beteiligt. Der kann jetzt immer noch falsch sein und ist zu kontrollieren aber zumindest das Bitgefummel und auseinanderpfriemeln fällt beim Kontrollieren weg.
wenn du dier diesen Code
1 | while(1) |
2 | {
|
3 | if (sekunde==2) |
4 | {
|
5 | PORTD|=(1<<PD7); |
6 | if (sekunde==4) |
7 | {
|
8 | PORTD&=~(1<<PD7); |
9 | }
|
10 | }
|
11 | }
|
sauber einrückst, dann sieht er so aus
1 | while(1) |
2 | {
|
3 | if (sekunde==2) |
4 | {
|
5 | PORTD|=(1<<PD7); |
6 | if (sekunde==4) |
7 | {
|
8 | PORTD&=~(1<<PD7); |
9 | }
|
10 | }
|
11 | }
|
und da erhebt sich sofort eine Frage: Das obere if führt seinen then Teil nur dann aus, wenn sekunde gleich 2 ist. Innerhalb dieses if steht das andere if, bei dem sekunde gleich 4 sein müsste. Nur: Wie kann das sein? An dieser Stelle steht schon fest, dass sekunde gleich 2 sein muss, andernfalls wäre das Programm nie an diese Abfrage gekommen! An dieser Stelle KANN sekunde daher niemals 4 sein was wiederrum bedeutet, dass dein Port einmal eingeschaltet aber nie wieder ausgeschaltet wird. Du hast überhaupt eine seltsame Art der Einrückung, wie man innerhalb der ISR sieht. Die Einrückung dient nicht dazu, nach Gutdünken angewendet zu werden, sondern sie hat eine Funktion! Sie zeigt welcher Code abhängig von welchem anderen Code ist. Daher: Nach einem { wird eingerückt. Das zugehörige } wird wieder ausgerückt. Und ein paar strategisch platzirete Leerzeichen dann und wann machen den Code leichter lesbar. Schliesslich bist du von Kindesbeinen an daran gewöhnt worden, dass zwischen Wörtern ein Leerzeichen kommt. Oder findestduetwdiesenTextwirklichlesbarer als wie wenn zwischen den Wörtern ein Zwischenraum steht?
1 | ISR (TIMER2_COMP_vect) |
2 | {
|
3 | millisekunde++; |
4 | if (millisekunde == 1000) |
5 | {
|
6 | millisekunde = 0; |
7 | sekunde++; |
8 | }
|
9 | |
10 | if (sekunde == 60) |
11 | {
|
12 | sekunde = 0; |
13 | minute++; |
14 | }
|
15 | |
16 | if (minute == 60) |
17 | {
|
18 | minute = 0; |
19 | stunde++; |
20 | }
|
21 | }
|
Bei solchen Sachen bin ich zwiespältig
1 | int main(void) |
2 | {
|
3 | |
4 | INITIALISIERUNG_SYSTEMPORTS(); //Ports initialisieren |
Das Problem: Die Initialisierung der Ports sind maximal ein paar Zuweisungen an die DDR Register und eventuell das Setzen von Pullups. Das ist aber eine wichtige Information, die ich nicht wirklich in eine eigene Funktion verpacken würde. Denn um in deinem Programm zu kontrollieren, ob du PD7 auch wirklich auf Ausgang gesetzt hast, muss ich jetzt in eine andere Funktion wechseln um mir das anzusehen. Fängt dein Programm so an
1 | int main(void) |
2 | {
|
3 | DDRD = ( 1 << PD7 ); |
dann ist das auch nicht länger als der Funktionsaufruf, ich sehe aber auf einen Blick, dass du PD7 auf Ausgang gesetzt hast und zwar NUR PD7. All das sehe ich nicht bei deinem Funktionsaufruf (der aus welchen Gründen auch immer in seiner SChreibweise eigentlich ein Makro ist, was in mir sowieso schon wieder die nächsten Alarmglocken zum klingeln bringt)
Hallo Danke für die schnell Antwort, also habe den Code mal um geschrieben: while(1) { if (sekunde==2) { PORTD|=(1<<PD7); } if (sekunde==4) { PORTD&=~(1<<PD7); } } } müsste so jetzt passen oder? und zu karl heinz, TCCR2=0b00001100; //CTC Mode, Prescaler=64 (16MHz/64=250KHz -> 250KHz=4µs) OCR2=250-1; //TCNT 2 wird mit vorgeteilter Frequenz (250KHz bzw.alle 4µs)inkrementiert, bis OCR2-1(-1, da das Interrupt Flag erst einen Timertakt nach der Übereinstimmung gesetzt wird) erreicht wird (4µs*250=1ms) dann startet ISR Timer2
Port D wird folgender Maßen initialisiert: DDRD |= (1<<PD7); PORTD &= ~(1<<PD7); //PortD //Datenrichtungsregister von PortD Pin 7 wird als Ausgang definiert. //Setze Pin 7 auf "low".
Matze schrieb: > müsste so jetzt passen oder? Versuch macht kluch > TCCR2=0b00001100; > //CTC Mode, Prescaler=64 (16MHz/64=250KHz -> 250KHz=4µs) Kann alles sein. Ich weiß ja nicht, welchen µC du benutzt daher kann ich das auch nicht kontrollieren.
Aso ja sorry, also Code funktioniert so wie ich ihn gepostet habe. Ich benutze einen AtMega 32. PS.:Habe den Fehler jetzt gefunden. in den Einstellungen des AVR Studios war der AtMega 16 mit 1Mhz eingestellt. Danke an euch und ich freue mich über Anregungen um meine Code übersichtlicher und schneller lesbar zu machen. MfG.
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.