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
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_tprescaler;
6
uint8_tvolatilesecond;// 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
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
MOVLW0x27;;Timer2Initialisieren
2
#Stopwatch# MOVWF T2CON
3
#start# BSF STATUS,RP0
4
MOVLW0x124;
5
MOVWFPR2;
6
BCFSTATUS,RP0
7
8
y:BTFSSPIR1,TMR2IF;
9
GOTOy;
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
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
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.