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)
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
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?!?
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"
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
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
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 .
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
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
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 ;)
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} }
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.