Forum: Mikrocontroller und Digitale Elektronik Stimmt meine Rechnung für Timer0 PIC


von Markus D. (Gast)


Lesenswert?

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

von Sven S. (stepp64) Benutzerseite


Lesenswert?

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

von Master S. (snowman)


Lesenswert?


von Purzel H. (hacky)


Lesenswert?

Der Standardansatz ist im Timerinterrupt einen Pin zu bewegen. Dann mit 
dem Scope zu schauen.

von Peter D. (peda)


Lesenswert?

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

von Markus D. (Gast)


Lesenswert?

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

von Gast XIV (Gast)


Lesenswert?

Vielleicht hilft ja ein

pic timer calculator

bei Google gibt es jede Menge davon.

von Sven S. (stepp64) Benutzerseite


Lesenswert?

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

von Markus D. (Gast)


Lesenswert?

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

von Markus D. (Gast)


Lesenswert?

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;

von Markus D. (Gast)


Lesenswert?

Ach und das

MOVLW  0x124;
MOVWF  PR2;

ist natürlich

MOVLW  0x7C;
MOVWF  PR2;

von Sven S. (stepp64) Benutzerseite


Lesenswert?

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.

von labelohase (Gast)


Lesenswert?


von Markus D. (Gast)


Lesenswert?

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

von Markus D. (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal der auszug aus dem Datenblatt

von Sven S. (stepp64) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.