Timer0 beim PIC18

OP #2758934
Lesenswert?

Servus, ich nochmal,
ich brauche einen Taktgeber, welcher mit einem PIC18 realisiert werden 
soll. Habe ich auch alles bis jetzt fertig und dachte: super. Dann habe 
ich den Ausgang an ein Oszi angeschlossen und war enttäuscht von dem, 
was ich sah. Der Timer ist nicht gerade sehr genau. Meine Vermutung ist, 
dass meine Interruptroutine zu langsam ist. Ich möchte einen Takt habe, 
welcher mindestens die Auflösung von 1 µs hat. In der ersten Periode 
sieht es auch noch gut aus, aber ab dann driftet der Wert irgendwie ab.
Woran kann es liegen? Mein Pic arbeitet mit einer Taktfrequenz von 16 
MHz. Hier mal die Interruptroutine:
1
  if(LED){
2
    LED = 0;
3
  }
4
  else{
5
    LED = 1;
6
  }
7

8
  T0CON = 0x00;
9
  TMR0H = ((tmr0 >> 8) & 0xFF);
10
  TMR0L = (tmr0 & 0xFF);
11
  INTCONbits.TMR0IE = 1;
12
  INTCONbits.TMR0IF = 0;

Falls es wirklich an der Interruptroutine liegen sollte? Wie kann ich 
Sie schneller machen? Ich habe auf jeden Fall vor, diese in Assambler zu 
implementieren.

Danke im vorraus

David
OP #2759168
Lesenswert?

@Frank K.: Ok, das werde ich mal sofort ändern, danke für den Hinweis.


@Peter Dannegger:  Das Problem ist nur folgendes. Und zwar soll der Takt 
nicht immer so wie da oben aussehen(Es ist nur der einfachst Fall). 
Später soll eine Bitfolge eingegeben werden können. Zum Beispiel: 
1,0,1,1,1,0,0,1,0,0,1,1,1. Deswegen denke ich nicht, dass mir die PWM 
hier weiterhilft.

Weiß vielleicht jemand, wie hoch der externe Takteingang für den Timer 
getaktet werden kann? Also wäre es möglich z.B. ein 40 MHz Oszilator 
dafür zu verwenden?

Gruß
David
(Firma: Atelier Klippel) #2759198
Lesenswert?

Welchen PIC benutzt Du? Wie initialisierst Du den Timer? Warum setzt Du 
T0CON jedesmal neu im Interrupt, etc., etc?

Wenn Du eine Bitfolge ausgeben willst dann nimm SPI dafür. Und wie Peter 
schon schrieb muss man auch auf die benutzten Taktzyklen achten. Bedenke 
das ein PIC den Oszillator-Takt durch 4 teilt um den Befehlstakt zu 
erhalten. Das heisst wenn Du den PIC mit 4MHz taktest ergibt sich ein 
Befehlstakt von 1MHz.

Wenn man jetzt mal einen moderneren 18er PIC nimmt, z.B. den 18F26K20. 
Der kann bis 64MHz getaktet werden. Das ergibt 16MHz Befehls-Takt. Um 
auf 1MHz (also die 1µS Auflösung) zu kommen hast Du maximal 16 Befehle 
Zeit.

IRQ löst aus, Routine wird angesprungen = 2 Takte
IRQ Flag vom Timer löschen = 1 Takt
TMR H/L register neu laden = max. 4 Takte
Pin toggeln = 1 Takt
Rücksprung aus dem IRQ = 2 Takte

Macht also zusammen schon mal 10 Takte. Da bleibt nicht mehr viel von 
den 16 Takten, die man maximal hat, übrig. Wenn Du jetzt auch noch 
gezielt eine Bitfolge ausgeben willst wird es schon extrem eng, je 
nachdem was man will sogar unmöglich.

Anders sieht es aus wenn Du den SPI benutzt. Einfach den Teiler 
entsprechend setzen so das sich eine Bitrate von 1MBit/sec. ergibt. Da 
man das SPI Ausgabe-Register aber immer mit einem Byte lädt ergibt sich 
so 8µS zwischen jedem Byte, was bei der gleichen Taktfrequenz wie oben 
dann in 16 * 8 = 128 Befehelen resultiert.

Davon würden dann im SPI Interrupt benötigt:

IRQ anspringen = 2 Takte
IRQ Flag löschen = 1 Takt
Byte in SSP Buffer kopieren = 2 Takte
IRQ verlassen = 2 Takte

Also zusammen 7 Takte. Da hat man dann noch 121 Takte frei zur Verfügung 
für andere Sachen.

Achja: Ich gehe davon aus das der High-Priority Interrupt verwendet 
wird, und dieser ausschließlich für diese eine Aufgabe benutzt wird. Das 
hat den Vorteil das die wichtigsten Register automatisch gesichert und 
wiederhergestellt werden und das man nicht erst prüfen muss welcher IRQ 
denn nun behandelt werden muss.

Grüße,

Chris

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren