Moin zusammen, Ich wollt nur mal kurz nachfragen ob meine Rechnung stimmt. Und zwar will ich später auf eine sekunde kommen aber dafür wollte ich erstmal wissen ob ich generell schonma richtig gerechnet habe =). Also kurz die Fakten: Ich benutze einen Pic: 4MHz Interner Oszillator Timer 0 wird benutzt Prescaler auf 1/1024 Der µC benötigt für einen Befehl 4 Taktzyklen also mit 1 MHz (1µs) arbeitet er. Mit dem Prescaler von 1024 braucht er für einen Zählimpuls 1024 * 1µs =1,024ms Bis der Timer dann überläuft benötigt er dann 256 * 1,024ms = 262,144ms. Stimmt das bis dahin ? das würde mir schon sehr weiterhelfen =) das wird später in assembler umgesetzt aber erst wollte ich wissen ob die rechnung so stimmt. Gruß Key
Der Vorteiler des Timer0 kann maximal 1:256. Damit stimmt deine Rechnung schon mal nicht. Mit dem Timer2 geht es aber sehr gut. Stelle diesen so ein, dass der Vorteiler 16:1 und der Nachteiler 5:1 ist. Das PR2 Register stellst du auf 124. Dann erhältst du exaakt alle 10ms einen Interupt und hast alle 100 Interrupts eine Sekunde. Wenn deine Sekunde genau sein soll, kannst du aber nicht den internen Ossi verwenden. Der ist zu ungenau. Da musst du dann schon einen Quarz anschliesen. Gruß Sven
Der Standardansatz ist im Timerinterrupt einen Pin zu bewegen. Dann mit dem Scope zu schauen.
Schoener Tag heute schrieb: > Der Standardansatz ist im Timerinterrupt einen Pin zu bewegen. Dann mit > dem Scope zu schauen. Oh Gott !!! Seit wann ist Trial&Error Standard ??? Standard ist, einfach ins Datenblatt zu schauen und dann die Formeln hinzuschreiben, damit der Compiler die nötigen Konstanten zur Compilezeit ausrechnet. Ein Beispiel, wie das beim AVR aussehen würde:
1 | #define XTAL 11059201L // crystal frequency
|
2 | |
3 | #define TIMEBASE 200 // 200Hz (5ms)
|
4 | |
5 | uint8_t prescaler; |
6 | uint8_t volatile second; // count seconds |
7 | |
8 | |
9 | ISR( SIG_OUTPUT_COMPARE1A ) |
10 | {
|
11 | OCR1A = XTAL / TIMEBASE - 1; |
12 | if( --prescaler == 0 ){ |
13 | prescaler = TIMEBASE; // for 1 second |
14 | second++; // one second over |
15 | OCR1A = XTAL / TIMEBASE + XTAL % TIMEBASE - 1; // remainder once per second |
16 | }
|
17 | }
|
Und das ist dann auch genau eine Sekunde, da brauchst Du kein Oszi dafür. Bzw. Dein Oszi könnte es garnicht erst so genau anzeigen. Peter
Hm das vom Sven hört sich ganz gut an. Aber ich kann das noch nicht ganz nachvollziehen. Bei Timer 2 gibts den Prescaler und Postscaler. ich verstehe das so: Es kommt von vornerein nur ein Viertel meiner OSC Frequenz in den Prescaler -> das macht 4Mhz / 4 = 1MHz Bei einem Prescaler von 16 ergibt das 62,5kHz was 16 µ pro Takt entspricht. Also gibts in TMR2 alle 16µs*256 = 4.096ms einen Overflow. so du sagst jetzt das PR2 Register auf 124 setzten. Das PR2 Register wird immer mit dem TMR2 Register verglichen. Das bedeutet das es alle 16µs*124 =1,984ms einen Compare gibt. Und das geht dann in den Postscaler - aber was macht der damit. Gibt der nur jeden 5ten Copare weiter, wenne er auf 1:5 steht ? oder wie funktioniert der? Gruß Markus
Vielleicht hilft ja ein pic timer calculator bei Google gibt es jede Menge davon.
Du hast es schon richtig verstanden. Der Vorteiler teilt die 1MHz (4MHz Quarzfrequenz / 4) durch 16 macht 62500Hz. Dann vergleicht der Timer2 seinen Inhalt immer mit dem PR2 Register. Bei Gleichheit wird ein Impuls an den Nachteiler gegeben. Das ergibt dann 62500 / 125 = 500 (du musst die Null mitrechnen. PR2=124 macht 125 Takte). Nun noch der Nachteiler 500 / 5 = 100 Hz. Erst jetzt wird der Interrupt ausgelöst. Schau es dir im Datenblatt oder bei sprut.de an. Erst der Nachteiler löst den Interupt aus. Funktioniert bei mir in einer Uhrenschaltung problemlos und ist sehr genau. Ich hab zwar 8MHz als Quarztakt aber dafür den Nachteiler auf 10:1. Im Simulator (Stop Watch) kann man erkennen, dass er exakt alle 10ms den Interupt auslöst. Meine Uhr geht am Tag ca. 1 Sekunde falsch. Das liegt aber meiner Meinung nach am Quarz und der Temperatur und nicht an der Software. Die 10ms bilden auch gleichzeitig meinen Systemtakt, für z.Bsp. die Tastaturabfrage oder andere regelmäßig zu pollende Ereignisse. Gruß Sven
mhm joar ich hab mir mal alles reingezogen, aber wenn ich bei Prozessor Frequenz im Simulator 4 MHz angebe Bekomme ich bei dem Programme
1 | MOVLW 0x27; ;Timer 2 Initialisieren |
2 | #Stopwatch# MOVWF T2CON
|
3 | #start# BSF STATUS,RP0
|
4 | MOVLW 0x124; |
5 | MOVWF PR2; |
6 | BCF STATUS,RP0 |
7 | |
8 | y: BTFSS PIR1,TMR2IF; |
9 | GOTO y; |
10 | #Breakpoint# GOTO start;
|
eine Zeit von 40ms bis TMR und zwar gemessen von SW start bis zum Breakpoint - habe das mal im programm markiert. mhm mal gucken wo der fehler ist, wenn ihn wer gefunden hat bescheid sagen bitte :D Gruß Markus
Mhm das Prog war komisch anzugucken ^^ hier nomma
1 | MOVLW 0x27; ;Timer 2 Initialisieren |
2 | #Stopwatch# MOVWF T2CON
|
3 | #start# BSF STATUS,RP0
|
4 | MOVLW 0x124; |
5 | MOVWF PR2; |
6 | BCF STATUS,RP0 |
7 | |
8 | y: BTFSS PIR1,TMR2IF; |
9 | GOTO y; |
10 | #Breakpoint# GOTO start;
|
Ach und das MOVLW 0x124; MOVWF PR2; ist natürlich MOVLW 0x7C; MOVWF PR2;
Versuch es mal so:
1 | MOVLW 0x27; ;Timer 2 Initialisieren |
2 | #Stopwatch# MOVWF T2CON |
3 | #start# BSF STATUS,RP0 |
4 | MOVLW 0x124; |
5 | MOVWF PR2; |
6 | BCF STATUS,RP0 |
7 | |
8 | y: BTFSS PIR1,TMR2IF; |
9 | GOTO y; |
10 | |
11 | bcf PIR1,TMR2IF |
12 | #Breakpoint# GOTO y |
Wenn das Prog das erste mal am Breakpoint anhält, löschst du im Stopwatch den Zähler und lässt das Programm weiter laufen. Beim zweiten und allen folgenden durchläufen sollte es eigentlich stimmen. Hinweis: PR2 muss nur am Anfang initilisiert werden. Den Rest macht der µC alleine.
So ich habe ENDLICH den Fehler gefunden ! Ziemlich Dumm eigentlich bzw habe ich dafür keine Erklärung: Und Zwar habe ich ins T2CON Register immer eine 0x27 Reingeschoben also b'00100111' Also Postscaler auf 1:5 TMR2 angemacht und Bit 1 und 0 sind für den Prescaler T2CKPS1 und T2CKPS0. So im Datenblatt steht wenn T2CKPS1 gesetzt ist dann ist T2CKPS0 unbekannt und der ist 1:16. BZW so würde ich es verstehn. Aber wenn T2CKPS0 gesetzt ist dann wird ein Teiler von 1:4 genommen. Naja und da lag dann der Fehler
Ich hatte nach deinem Beitrag auch ein wenig damit herumexperimentiert. Das interessante ist, dass im Simulator bei einem 16F887 das TMR2 Register nur alle 64 Takte weitergezählt wird, wenn T2CKPS1 und T2CKPS0 = 11 sind. Aber gut zu wissen, dass man an dieser Stelle mal wieder Obacht geben muss. Mir ist auch aufgefallen, dass die meisten Timercalculatoren im iNet bei meiner Formel das PR2 Register mit 125 laden würden. Allerdings scheinen diese Calculatoren nicht zu berücksichtigen, dass das TMR2 Register erst mit der nächsten Flanke nach Übereinstimmung (TMR2=PR2) zurückgesetzt wird und damit 125 Takte gezählt werden, wenn man eine 124 einträgt. Bsp. mit einer 1 im PR2: 0. Takt: TMR2=0 1. Takt: TMR2=1 --> PR2 = TMR2 2. Takt: TMR2=0 3. Takt: TMR2=1.... Das heist alle 2 Takte ist TMR2=0 obwohl im PR2 eine 1 steht. Man muss also noch eine 1 abziehen von dem Wert den man für PR2 errechnet. Gruß Sven
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.