Hi Leute, bin so frei gewesen und habe mir das gute Stück Software vom Peter Dannegger (Precise 1 Second Timebase) kopiert und versucht zu modifizieren! Danke an Peter, für diese ausgezeichnete Software und sorry das ich einfach so genommen hab ;) !! Dann habe ich das halt nen bisschen geändert und versucht an meine Bedürfnisse anzupassen, ging aber schief.Versteh aber leider nicht ganz genau was da alles passiert ! Kann einer von mir da eventuell auf die Sprünge helfen ? Hier das originale Programm: ============================================================= #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #ifndef OCR1A #define OCR1A OCR1 // 2313 support #endif #ifndef WGM12 #define WGM12 CTC1 // 2313 support #endif #ifndef PINC #define KEY_INPUT PIND // 2313 #else #define KEY_INPUT PINC // Mega8 #endif #define LED_DIR DDRB //#define XTAL 11059201L // nominal value #define XTAL 8000000L // after measuring deviation: 1.5s/d #define DEBOUNCE 256L // debounce clock (256Hz = 4msec) #define uchar unsigned char #define uint unsigned int uchar prescaler; uchar volatile second; // count seconds SIGNAL (SIG_OUTPUT_COMPARE1A) { /*********************************************************************** */ /* Insert Key Debouncing Here */ /*********************************************************************** */ #if XTAL % DEBOUNCE OCR1A = XTAL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times #endif if( --prescaler == 0 ){ prescaler = (uchar)DEBOUNCE; second++; // exact one second over #if XTAL % DEBOUNCE // handle remainder OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1; // compare once per second #endif } } int main( void ) { LED_DIR = 0xFF; while( KEY_INPUT & 1 ); // start with key 0 pressed TCCR1B = 1<<WGM12^1<<CS10; // divide by 1 // clear on compare OCR1A = XTAL / DEBOUNCE - 1; TCNT1 = 0; second = 0; prescaler = (uchar)DEBOUNCE; TIMSK = 1<<OCIE1A; sei(); for(;;){ if( second == 60 ) second = 0; LED_DIR = second; // display second (binary) } }
Ich versteh z.B. nicht wofür SIGNAL (SIG_OUTPUT_COMPARE1A) { ..... } gut sein soll, sieht aus wie ne Funktion, steht aber ausserhalb des main programmes, wird aber niemals aufgerufen und somit meiner meinung nach nicht gebraucht. Lösche ich das allerdings raus, tut das Prog nicht mehr ?? habe ich was übersehen ?? handelt es sich dabei um die ISR ??
> SIGNAL (SIG_OUTPUT_COMPARE1A)
Das ist der Interrupt Handler. Du startest einen Timer und wenn dieser
abläuft wird diese Funktion ausgeführt.
> und versucht zu modifizieren!
Besser wäre es mit Hilfe des Datenblattes des Controllers und der Doku.
des Compilers versuchen den Code zu verstehen.
Einfach Schritt für Schritt durchgehen.
Ja besser wäre es mit dem Datenblatt ich glaub das versuch ich auch, aber dann müsst ihr mir BITTE BITTE helfen, ok ?? Also sollte mein Programm schonmal grob so aussehen: ?? include bla bla SIGNAL (SIG_OUTPUT_COMPARE1A) { ... } void main(void) { TCCR0 = 0x7c; // DDRA = 0xff; //Port A als Ausgang definieren TIMSK = 0x02; TIFR = 0x02; while(1) { } }
TCCR0 = 0x7c; startet doch meinen Timer, der dann die ganze zeit wie dulle rennt, und TCNT1 um 1 inkrementiert oder dekrementiert, richtig ? und dann geh ich hin und knall nen Wert ins OCR und sobald der wert im OCR mit dem im TCNT übereinstimmt gibt es einen overflow??
Nein, wenn der Wert in TCNT0 mit dem in OCR0 übereinstimmt, gibts ein Compare-Ereignis. Mit Overflow wird hier gar nicht gearbeitet. Der Timer läuft im CTC-(Clear Timer on Compare Match) Modus, d.h. TCNT0 wird auf Null zurückgesetzt, sobald ein Compare-Ereignis auftritt. Dann zählt er wieder hoch, bis TCNT0 den Wert in OCR0 erreicht und das Spielchen geht von vorne los. Der Interrupt wird beim Compare-Ereignis ausgelöst.
Das heißt also: ich schreib jetzt z.B. 200 in OCR0 rein und TCNT0 wird von 0 bis 255 hochgezählt. kommt der Timer dann beim hochzählen an die 200, gibts ein Compare-Ereignis und setzt auf null und fängt von vorne an, und es wurde ein interrupt ausgelöst, der dann die ISR SIGNAL (SIG_OUTPUT_COMPARE1A) {...} aufruft, in der ich dann z.B. die led ein bzw. ausschalte ??
hallo glaube ich habe nochwas rausgefunden: TCNT0 wird von 0 bis 255 hochgezählt, das ergibt mit nem CPU Takt und dem Prescaler von 256 folgendes: 1/fCPU Prescaler TCNT0max = 1/8.000.000 256 256 = 0,008192sec und dann muss ich den scheiss 1/0,008192 mal hochzählen bis eine Sekunde um ist, richtig ? also 122,07...... also rechne ich mit 122, dann ist mir das schon genau genug ! Also setze ich OCR0 = 255 und dann wird wenn TCNT0 MAX erreicht ein interrupt ausgeführt. dieser ruft die ISR auf und in der habe ich folgendes stehen: ISR { i++; if(i == 122) { led an wenn aus led aus wenn an i = 0; } } soweit richtig ?? oder ist das zuviel gemüse innerhalb der ISR, das das zu lange dauert ?
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 ob das richtig ist Vielen Dank schonmal an die Profis unter euch (also an alle) ;) DANKE DANKE Bitte um Hilfe, weiß nicht ob das richtig ist
Ja da ist nen Fehler drin, ich weiß aber nicht wo, habe das soeben in meinen uc geladen.... 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 ??
Vielleicht solltest Du Timer 0 und 1 nicht durcheinanderbringen! Comare1A hat nix mit TCCR0 oder OCR0 zu tun!
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.