Forum: Mikrocontroller und Digitale Elektronik Timer0 Interrupt alle 10ms


von Stefan U. (unti)


Lesenswert?

Hallo alle zusammen

Ich brauche bei meinem Projekt ein Timerinterrupt von 10ms. Ich wollte 
fragen ob man das mit dem TIMER0 überhaupt realisieren kann und fals es 
möglich ist wie man den TIMER0 richtig einstellt.

MfG Unti

von Karl H. (kbuchegg)


Lesenswert?

Das hängt von der Taktfrequenz deines µC ab. Aber auch zb. ob du mit dem 
Timer0 einen CTC Modus machen kannst.

Der Rest ist ein wenig rumrechnen und Vorteiler durchprobieren.
FAQ: Timer

: Bearbeitet durch User
von Durchblick fehlt (Gast)


Lesenswert?

Karl Heinz schrieb:
> Das hängt von der Taktfrequenz deines µC ab. Aber auch zb. ob du
> mit dem
> Timer0 einen CTC Modus machen kannst.
>
> Der Rest ist ein wenig rumrechnen und Vorteiler durchprobieren.
> FAQ: Timer

Kannst du den benutzten UC raten?

von Stefan U. (unti)


Lesenswert?

Die Taktfrequenz von meinem PIC beträgt 8Mhz und CTC Modus ist nicht 
möglich

von Stefan U. (unti)


Lesenswert?

Der verwendet PIC ist der 16F690.

von Karl H. (kbuchegg)


Lesenswert?

Durchblick fehlt schrieb:
> Karl Heinz schrieb:
>> Das hängt von der Taktfrequenz deines µC ab. Aber auch zb. ob du
>> mit dem
>> Timer0 einen CTC Modus machen kannst.
>>
>> Der Rest ist ein wenig rumrechnen und Vorteiler durchprobieren.
>> FAQ: Timer
>
> Kannst du den benutzten UC raten?

Nö, kann ich nicht.
Aber es gibt ein paar Dinge, die universell sind. WIe zb der 
Zusammenhang zwischen Eingangsfrequenz und eingestelltem Vorteiler. Wie 
zb der Zusammenhang zwischen Bitbreite des Timers und davon abhängig, 
wann zb ein Overflow kommt. etc. etc.

Da das universell ist, ist das ganze Vorgeplänkel im FAQ Artikel auch 
überall mehr oder weniger auf allen µC die einen Timer haben dasselbe. 
Hier geht es mehr um das allgemeine Verständnis wie (eigentlich: wie 
simpel) das Ganze ist. Das alles ist kein Hexenwerk. Hat man es erst mal 
verstanden, ist es so einfach wie einem Baby den Schnuller klauen.

von Durchblick fehlt (Gast)


Lesenswert?

Da gibt es auch uCs bei denen CPU und Peripherie mit unterschiedlichen 
und sogar nicht synchronisierten Quellen arbeiten.

Nur einmal kluggesch.... ;-)

von Ottmar K. (wil1)


Lesenswert?

Hallo Stefan,
falls Du es inzwischen nicht selbst erfahren hast, hier die Auflösung:

Quarz/IntOsc = 8MHz
Fosc/4 = 2MHz (2.000.000 Arbeitstakte/s) = 0,5µs/Arbeitstakt

10ms Interruptperiode dauert somit 20.000 Arbeitstakte
größtmöglicher Vorteile zu TMR0 = 1:256

20.000/256 = 78,125 Takte für TMR0
nächstkleinerer Vorteiler ist 1:128

20.000/128 = 156,25 -> 156 Zähltakte

Preset TMR0 berechnen (overflow bei Takt 256 255->0)
256-156 = 100
Mit Preset = 100 für den TMR0 und dem Vorteiler 1:128 wird dieser 
Interruptzyklus erreicht: 19980 Arbeitszyklen = 9990µs

Preset 99 würde die Interruptperiode auf 20108 Arbeitszyklen =
10,054ms verlängern. Also muss noch etwas "gemogelt" werden, dazu sind 
noch 20 Arbeitszyklen zu "verbraten". Dies kann nun durche Hinfügen von 
z.B. 20 "nop"-Befehlen oder auch durch das Herunterzählen einer 
Variablen (vgl. Beispiel) erfolgen. 1x "nop" war dann noch zum 
Feinabgleich erforderlich.

Das könnte dann z.B. so aussehen:

    ORG  0x0004         ;Interrupt-Vector
ISR:
    movwf  tmpWREG     ;Copy W to TEMP register
    swapf  STATUS,w    ;Swap status to be saved into W
    clrf   STATUS      ;BANK 0, REGARDLESS OF CURRENT BANK
    movwf  tmpSTATUS   ;in Zwischenspeicher retten
    bcf    INTCON,T0IE ;DISABLE TMR0 overflow-interrupt
    bcf    INTCON,T0IF ;Clear Flag, "TMR0 has not overflowed"
    ;
    nop                ;Abgleich auf exakt 10.000ms
    movlw   d'6'
    movwf   d1
ISR_tune10ms:
    decfsz  d1,f
    GOTO    ISR_tune10ms
    ;
    movlw   .100       ;Preset TMR0
    movwf   TMR0
    ;
    nop                ;STOP TIME here = 20.000 cyclen = 10.000 ms

ISR_end:
   SWAPF  tmpSTATUS,w  ;WREG und STATUS wieder herstellen
   movwf  STATUS
   swapf  tmpWREG,f
   swapf  tmpWREG,w
   BSF    INTCON,T0IE  ;ENABLE TMR0 overflow-interrupt
   RETFIE
;*************************************************************
Init:
   banksel OPTION_REG    ;bank 1
   movlw   b'00000110'   ;Bit5=0 Clock source is Fosc/4
                         ;Bit3=0 TMR0+Prescaler
                         ;Bit2:0=110 Prescaler 1:128
   movwf   OPTION_REG
   banksel PORTA         ;back to bank 0
   ;
   bcf    INTCON,T0IF    ;set Flag "TMR0 has NOT overflowd"
   movlw  d'100'         ;Preset TMR0
   movwf  TMR0           ;Interruptperiode noch ohne Abgleich
   bsf    INTCON,GIE     ;enable Global interrupt
   bsf    INTCON,T0IE    ;enable TMR0 overflow-interrupt
;*************************************************************
Main

 GOTO Main
 END

vielleicht hilft's - mfG Ottmar

von Stefan U. (unti)


Lesenswert?

Danke für die Hilfestellung Ottmar K.
Möchte nur noch wissen wie man sich den Vorteiler ausrechnet.

von Ah. (Gast)


Lesenswert?

Aus'm Datenblatt die Moeglichkeiten suchen und den passenden einsetzen. 
Alternativ, wenn das zu anspruchsvoll ist, alle durchpermutieren und mit 
dem Scope nachmessen.

von Ottmar K. (wil1)


Lesenswert?

Hallo Stefan,

...gerne geschehen!
Im Datenblatt des 16F690, S.85 im Kapitel über den TMR0 (OPTION_REG) 
sind die verfügbaren Vorteilerwerte aufgeführt. Günstig ist es stets das 
kleinstmögliche Teilerverhältnis zu verwenden. Probieren geht über 
studieren!

mfG Ottmar

von Stefan U. (unti)


Lesenswert?

Danke nochmal Ottmar K. und auch an alle anderen.

von Stefan U. (unti)


Lesenswert?

Könnte mir noch jemand zum Schluss folgende Zeile erklären, bitte.
"setup_timer0(RTCC_INTERNAL | RTCC_DIV_16);"

MfG Unti

von Jens P. (picler)


Lesenswert?

Eine sehr gute Seite zum Thema PIC µCs ist www.sprut.de Da sind viele 
Grundlagen verständlich erklärt.

Das oben beschriebene Beispiel ist allerdings zu umständlich, 
insbesondere für den Anfänger. Wenn ich die Taktfrequenz frei wählen 
kann, nehme ich die für meine Aufgabe passende. In deinem Beispiel 
könntest du ein Quarz mit 3,2768 MHz nehmen und den Timer 0 mit einem 
Vorteiler von 64. Damit erzeugt der Überlauf von Timer 0 alle 10ms einen 
Interupt.

Außerdem kann man sich überlegen, ob die Zeitspanne wirklich 10ms sein 
muss. Oftmals geht auch ein anderer Wert, z.B. 7,8125 ms (1/128s). Da 
würden wieder andere Quarze gehen.

Das Vorladen eines Timer-Registers ist auch machbar, doch auch dort 
sollte man mit ganzzahligen Werten rechnen. Die oben beschriebene 
Methode ist kein sauberer Programmierstil. Wenn noch andere Interupts 
dazu kommen handelt man sich damit jede Menge Zeitfehler ein.

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.