Forum: Mikrocontroller und Digitale Elektronik pic timer 2 einstellung, damit alle 250 timerüerlauf


von pic_99 (Gast)


Lesenswert?

hallo kann mir vileicht hier jemand helfen?
programmiere einen pic microcontroller und möchte den timer 2 so 
einstellen dass er alle 250ms ein interrupt generiert. irgendwie kreige 
ich das nicht hin. Kann mir villeicht jemand helfen?
Programmiere pic16f877a und dieser wird mit 20Mhz getaktet.

Folgende Funktion stellt sich zur Verfügung:

setup_timer_2(T2_DIV_BY_16,250,10);

16 ist Pre - und 10 ist Postscaler ein Überlauf bei 250(ein beispiel aus 
einem Kurs)

von Daniel P. (ppowers)


Lesenswert?

Naja, das sieht eigentlich schlecht aus mit dem Timer2, da das ja nur 
ein 8-bit Timer ist.
Rechnerisch komme ich damit auf eine maximale Periodendauer von 13,107ms 
(man möge mich korrigieren...)

Hier die Rechnung dazu:
Dauer einer Instruction bei 20MHz = 1/(Fosc/4) = 0,2µs = T

Periodendauer des Timers Tp = T   x  256  x  16  x  16  = 13,107ms
                                     ^^^     ^^     ^^
                                    8-bit   Pre-   Post- Scaler

Die einzige Möglichkeit (bei Verwendung von Timer2) besteht darin, in 
dem Timerinterrupt von Timer2 einen Counter hochzuzählen.

Gruß
Daniel

von pic_99 (Gast)


Lesenswert?

Ja das klingt logisch: Dieser Wert hat mir so ein Berechungstool auch 
angegeben.(Wusste aber nicht genau öb ich dem trauen kann=) )
Dann müsste ich das mit dem Timer1 machen oder? Das ist ein 16 Bit Timer 
glaube ich?!?

von hugo (Gast)


Lesenswert?

hier hast du n beispiel, wo

der interrupt vom timer 255*255*60-Mal ein ereignis ausführt....

also genau das, was du suchst. Im übrigen ja, der timer 1 ist ein 
16bittiger! dh bis 65535 dann überlauf


Beitrag "Große Zahl aus drei Variablen"

von Daniel P. (ppowers)


Lesenswert?

pic_99 wrote:
> Dann müsste ich das mit dem Timer1 machen oder? Das ist ein 16 Bit Timer
> glaube ich?!?

Jein. Timer1 ist zwar ein 16-Bit-Timer, hat allerdings nur einen 
Prescaler und keinen Postscaler.
Damit erhälst Du:

Periodendauer des Timers Tp = T   x  65536  x  16   = 104,85ms
                                     ^^^^^     ^^
                                    16-bit    Prescaler

250ms sind für einen Mikrocontroller schon eine waaaaaaaaaaaahnsinnig 
lange Zeit. Würdest Du einen 4 MHz-Quarz verwenden, dann könntest Du die 
250ms Periodendauer mit der Timer1-Hardware erreichen. Sonst kommst Du 
um das Hochzählen in der Interruptfunktion nicht herum...

Gruß
Daniel

von hugo (Gast)


Lesenswert?

also der interrupt wird so oft ausgeführt, wie angegeben, aber nur bei 
jedem x-ten mal(letzter beitrag angegeben) wird das ereignis aufgerufen.

da ist genau deine idee von dem counter verwirklicht. In diesem Falle 
sogar bis zu über 16 Milionen counter.

wenn dein mcu und dein compiler das unterstützt, dann nutze doch ne 
unsigned 16 bzw 32Bit-Integer variable. So sparst du dir noch die ifs...

hier n code:

#pragma sharedAllocation
#include "int16CXX.h"
#pragma origin 4
interrupt serverX( void)
{
  int_save_registers
  if (TMR1IF)              // T1 übergelaufen?
  {
    TMR1IF = 0;
    T1OSCEN = 0;
    TMR1CS = 0;
    TMR1H = 238;   //hi und low byte vom timer 1 füllen
    TMR1L = 120;
    TMR1ON = 1;
    GIE = 1;
    PEIE = 1;
    TMR1IE = 1;
    TMR1IF = 0;
    //**hier ereignis bei jedem Interrupt von T1**//

  zaehl0++;

    if( zaehl0 == 255 ) {
      zaehl1++;
      if( zaehl1 == 255) {
        zaehl2++;
        if( zaehl2 == 222 ) {  // Multiplikation der drei mit 18ms 
ergibt die timerzeit
          //**hier Ereignis beim X*X*X-ten mal des Interrupts***//
      sleep_mode = 1;
          zaehl0 = zaehl1 = zaehl2 = 0;
        }
      }
    }

    overflowed = 1;
  }
  int_restore_registers
}                     // Interrupt-Routine zu ende

von Max (Gast)


Lesenswert?

Hallo,
Hab grad ein schulprojekt muss ein funkuhr programmiern hab ein pic 
16f88
brauch jetzt ein  Delay1ms mit timer2 ´kann mir einer ein c code 
schreiben , bin schon den ganzen tag dran schaff es aber nicht den timer 
einzustellen, Danke .

von Thomas M. (thomas1123) Benutzerseite


Lesenswert?

alle 250?
tomaten
sekunden
minuten
stunden
takte?

werd bitte etwas genauer was du vor hast und schreibe bitte bei was 
genau du dein problem hast bzw grenze es ein.
schaltplan und c-code den du bisher erstellt hast würde auch 
weiterhelfen deine frage zu beantworten.

mfg
thomas

edit: ach ja habe ich wiedermal geantwortet bevor ich gelesen habe mein 
fehler

von stepp64 (Gast)


Lesenswert?

Da der Timer2 wie schon gesagt bei 20MHz nicht bis 250ms kommt (egal was 
du einstellst) solltest du es so machen wie ich (allerdings schreibe ich 
alles in Assembler). Stelle den Timer2 so ein, das er alle 10ms einen 
Interrupt erzeugt und zähle dann in der Interruptroutine bis 25. Dann 
setzt du ein FlagBit, welches in deiner Hauptroutine abgefragt wird. 
Damit hast du ein Flag, welches alle 250ms gesetzt wird und gleichzeitig 
kannst du dir noch mehr flags einrichten für andere Zeiten. 10ms 
Grundtakt haben sich bei mir bisher ganz gut als Systemtakt gemacht.

Sven

von Latissimo (Gast)


Lesenswert?

Sieht stark nach meinem Code aus hugo.

Wenn du die Möglichkeit hast, einen langsameren Quartz zu nehmen, dann 
tu dies, ist bequemer für die Software, dann haste nix mit 
X-Timerüberläufen zu tun.(kingt so, als wäre das eher umständlich ;)

Oder du lässt die Hardware und benutzt doch n counter. Wie oben in 
meinem code von hugo gepostet, sind ja sogar mehrere counter.

Also einfach den timer 1 verwenden, die Berechnung ist dir ja 
mittlerweile klar, und dann könntest du den auf 50ms einstellen und dann 
nen counter bis 5 inkrementieren(denk ans rücksetzen des zählers, sonst 
bekommst du abwechselnd verschieden große Zeiten......


Aus Fehlern lernt man, also mache ich so viele wie möglich ;)

von Latissimo (Gast)


Lesenswert?

if (TMR1IF)              // T1 übergelaufen?
  {
    TMR1IF = 0;
    T1OSCEN = 0;
    TMR1CS = 0;
    TMR1H = 238;   //pass deine werte lt. rechung an!!
    TMR1L = 120;
    TMR1ON = 1;
    GIE = 1;
    PEIE = 1;
    TMR1IE = 1;
    TMR1IF = 0;
    //**hier 50ms EREIGNIS**//

    zaehl++;

    if( zaehl == 5 ) {zaehl = 0; //** hier 250ms EREIGNIS}

   }

von Christopher G. (peristikus)


Lesenswert?

Hallo!!!

Falls dein Porblem noch aktuell sein sollte.
Das ist ein Programmteil der selbst von mir geschrieben ist.

void init_delay()
{  T0CS=0;
  PSA=1;
}


void delay_ms(uns24 ms)
{
  TMR0=111;

  uns24 i;

  ms*=10;

  for(i=1;i<=ms;i++)
  {  while(T0IF==0);
    TMR0=111;
    T0IF=0;
  }
}

Der Code erklärt sich von selbst hoffentlich.

Eine gewisse genauigkeit ist gegeben, das gilt aber nur für einen 20MHz 
PIC. Das schreiben auf Timer0 und das erst nach 2 Takzyklen der Zähler 
anfängt zu zählen ist berücksichtigt worden.

MfG

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.