Hallo, ich denke ich habe das erste Programm stehen, ist es so richtig, oder ist da noch nen dicker Denkfehler drin ?? ===================================================================== #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> unsigned char CountVariable = 0; SIGNAL (SIG_OUTPUT_COMPARE1A) { CountVariable++; } void main(void) { //DDRA = 0x07; //Port A0-A2 als Ausgang definieren DDRA |= 0x01;//Port A0 als Ausgang definieren TCCR0 = 0x7c; //Startet Timer/Counter 0, von 0-255 TIMSK = 0x02; //enable Compare-Match Interrupt TIFR = 0x02; //enable Compare-Match Interrupt OCR0 = 255; //Vergleichswert für Wert in TCNT0 while(1) //Einleitung der Endlos-Systemschleife { if(CountVariable == 121) { PORTA |= 0x01; //LED (PORTA0) an CountVariable = 0;//Variable wieder auf 0 } else { PORTA &= 0xFE; //LED (PORTA0) aus } } } ==================================================================== Bitte um Hilfe, weiß nicht weiter, da sind zwei doofe Fehler drin: die LED leuchtet die ganze Zeit durch und ich muss die falsch herum anklemmen das die leuchtet... weil der uc den scheiss port auf masse zieht und nicht auf +5V was muss ich da dann ändern, also das der port auf +5v gezogen wird und die LED im sekundentakt blinkt ?? Hilfe !!!!
Ein Fehler ist sicher in der Zeile unsigned char CountVariable, da muss ein volatile davor.
oh ja stimmt :) vielen dank, aber wofür ist das volatile eigentlich genau ?? wo liegt der unterschied zwischen unsigned char und unsigned char volatile ??
Volatile heißt 'flüchtig' oder 'verlierbar' und wird für Variablen benötigt die außerhalb der Funktion main, also Interrupt-Funktionen behandelt werden.
Ahso cool, danke also immer für "Globale" Variablen die ich für Interrupt-Routinen benötige mit volatile kennzeichnen !!?? Und wo gibt es noch fehler? Warum wird der port auf masse gezogen und nicht gegen +5v und warum nur einmal ??
Was ist denn das ? PORTA |= 0x01; //LED (PORTA0) an CountVariable = 0;//Variable wieder auf 0 } else { PORTA &= 0xFE; //LED (PORTA0) aus am Anfang schaltest du POTRA bit 0 ein und im else-Teil alle anderen Bits aus? Klar dass PORTA bit 0 immer an ist. PORTA |= (1<<PA0); // PORTA 0 ein PORTA &= ~(1<<PA0); // PORTA 0 aus so wird eher 'n Schuh draus!
Mal abgesehen davon dass die LED nur für max. 1 Zähler von 'CountVariable' high ist, was whrscheinlich schlecht zu sehen ist (kenne den eingestellten Teilerfaktor nicht auswendig).
Habe das Programm jetzt so abgeändert: ======================================================================= #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> unsigned char volatile CountVariable = 0, Status = 0; SIGNAL (SIG_OUTPUT_COMPARE1A) { CountVariable++; } void main(void) { //DDRA = 0x07; //Port A0-A2 als Ausgang definieren DDRA |= 0x01;//Port A0 als Ausgang definieren TCCR0 = 0x7c;//Startet Timer/Counter 0, von 0-255 TIMSK = 0x02; //enable Compare-Match Interrupt TIFR = 0x02; //enable Compare-Match Interrupt OCR0 = 255; //Vergleichswert für Wert in TCNT0 while(1) //Einleitung der Endlos-Systemschleife { if(CountVariable == 121) { if(Status == 0) { //PORTA &= 0xFE;//LED (PORTA0) aus PORTA &= ~(1<<PA0);// PORTA 0 aus Status = 1; } else { //PORTA |= 0x01;//LED (PORTA0) an PORTA |= (1<<PA0);// PORTA 0 ein Status = 0; } CountVariable = 0;//Variable wieder auf 0 } } } ===================================================================== Aber die Led bleibt immer noch ständig an....
Du beutzt den COMPARE1A - Interrupt, Initialisierst aber TIMER0, das geht nicht! Außerdem musst du den globalen Interrupt SREG |= (1<<SREG_I); // Globalen Interrupt freigeben freigeben.
also muss ich noch folgendes einbauen ?? SREG = 0x80; Wo benutze ich denn COMPARE1A ? ich dachte OCR0 gehört zu timer0 oder was muss ich da benutzen ?
Du benutz die Output-Compare-1A Interrupt-Routine. dafür wären z.B. diese Einstellungen nötig: TCCR1A = 0; // Output pins disconnected, normal operation TCCR1B |= _BV(WGM12)|_BV(CS11); // Teiler /8 => 1µs, Compare-Mode 4 (CTC) TCCR1C = 0; OCR1A = 1000; // 1000µs = 1ms (Timer) TCNT1 = 0; // Startinitialisierung TIFR |= _BV(OCF1A); // Flag löschen TIMSK |= _BV(OCIE1A); // output-Compare 1A - INT enabled SREG |= _BV(SREG_I); // Globalen Interrupt freigeben Das gilt für einen Takt von 8 MHz. Ich glaube, du solltest dir die Funktion der Timer im Datenblatt nochmal genau durchlesen!
Tut mir leid, aber habe mir schon den ganzen tag lang immer wieder das DB reingezogen. Ich kenn das ja schon bald auswendig, finde aber den Fehler nicht, denn es ist das erste mal für mich, das ich mit Timern/Countern und Interrups arbeite. und gerade beim ersten mal fällt es jeden schwer denk ich, tut mir leid wenn ich hier nerv, aber brauche einfach jemand der mir den scheiss erklärt... :( Ist TCNT1 denn nicht von Timer 1 ??
Wo und an welcher Stelle genau benutze ich Output-Compare-1A Interrupt-Routine ?? was muss ich da anstelle dessen hinschreiben ? gibt es Output-Compare-0 Interrupt-Routine ?? also für meinen TimerCounter0 ?? brauch ich irgendwas von: TCCR1A = 0; // Output pins disconnected, normal operation TCCR1B |= _BV(WGM12)|_BV(CS11);// Teiler /8 => 1µs, Compare-Mode 4(CTC) TCCR1C = 0; OCR1A = 1000; // 1000µs = 1ms (Timer) TCNT1 = 0; // Startinitialisierung TIFR |= _BV(OCF1A); // Flag löschen TIMSK |= _BV(OCIE1A); // output-Compare 1A - INT enabled SREG |= _BV(SREG_I); // Globalen Interrupt freigeben
SIGNAL (SIG_OUTPUT_COMPARE1A) { CountVariable++; } Das ist deine COMPARE1A-Routine. Mit meiner Initialisierung läuft das Teil 1x pro ms (bei 8MHz Taktfrequenz) da rein, das heißt, 'CountVariable' wird jede ms um 1 erhöht.
Ahso da steht die scheisse mit Compare1A ;) Danke Sonic, bitte nicht gestresst sein !! kann ich da nicht irgendwas pasendes für meinen counter reinschreiben ? ich habe es aber auch mal mit deiner initialisierung probiert... TCCR1C = 0; kannte er nicht habs auskommentiert.... und mir gedacht, wenn countervarialbe jede ms hochgezählt wird ist 1s um wenn countervariable bei 1000 ist und habe das in der schleife gändert, LED leuchtet aber immer noch durch ?!? hier programm: ======================================================================= #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> unsigned char volatile CountVariable = 0, Status = 0; SIGNAL (SIG_OUTPUT_COMPARE1A) { CountVariable++; } void main(void) { DDRA |= 0x01;//Port A0 als Ausgang definieren TCCR1A = 0; // Output pins disconnected, normal operation TCCR1B |= _BV(WGM12)|_BV(CS11);//Teiler/8 =>1µs,Compare-Mode 4(CTC) OCR1A = 1000; // 1000µs = 1ms (Timer) TCNT1 = 0; // Startinitialisierung TIFR |= _BV(OCF1A); // Flag löschen TIMSK |= _BV(OCIE1A); // output-Compare 1A - INT enabled SREG |= _BV(SREG_I); // Globalen Interrupt freigeben while(1) { if(CountVariable == 999) { if(Status == 0) { PORTA &= ~(1<<PA0);// PORTA 0 aus Status = 1; } else { PORTA |= (1<<PA0);// PORTA 0 ein Status = 0; } CountVariable = 0;//Variable wieder auf 0 } } } =======================================================================
Hey Sonic :) :) :) :) :) :) :) :) :) :) :) :) Ich habs hinbekommen, ich habs ich habs JUHUUUUUUUUUUUUUUUUUUUU DAAAAAAAAAAANNNNKE ALTER DANKE DANKE DANKE !!!!!!!!!!!! ich habe einfach die scheisse von SIGNAL (SIG_OUTPUT_COMPARE1A) in SIGNAL (SIG_OUTPUT_COMPARE0) geändert, bor voll geil ne LED die im Sekundentakt blinkt, lol ABER EINFACH GEIL, Du bist superspitze DANKE DANKE DANKE !!!
Danke das Du mich nicht hängen lassen hast, echt super, jeder andere wäre schon kotzen gegangen :P
:P ja genau, das musste ja jetzt sein lol !! So ich geh nu aber pennen, muss ja morgen früh fit für die PWM sein :) N8 @all
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.