Timer0 Calculation - Page 1
Forum section: electronics / general

author: tahmod
author_rank: Contributor
timestamp: May 02, 2013, 07:50:55 am
content: ~I am using the microcontroller =>Datasheet=>http://seniordesign.ee.nd.edu/2008/Design%20Teams/Awesome-o/datasheets/39778b.pdfI read the datasheet and understood how I can make the timer start by making the INTCON,5 =1. But I dont know how change the time it take to overflower. My clock frequency is 4Mhz and I want the timer to overflow at 255 in 10 second.-1. I dont know how to divide the frequency correctly (you need to use prescaller?)-2. and what value to move on TMROH and TMROL?(From datasheet TMR0H Timer0 Register High Byte and TMR0L Timer0 Register Low Byte)movlwmovwf TMROHmovlwmovwf TMROL

author: westfw
author_rank: Super Contributor
timestamp: May 02, 2013, 09:28:23 am
content: QuoteIn general, the timers of microcontrollers aren't capable of timing events as long as 10 seconds.I calculate that even in 16-bit mode (max count 65535), with the maximum 256x prescale, the timer would overflow in about 4.2 seconds.(at 4 MHz, each clock cycle is 250nS. Multiply that by 256 for the max prescaler value (64 us for each tick out of the prescaler), and the amount that you'd count (up to 65536 * 64us = 4.1943 s))(This could be wrong in the details; I don't program PICs every day. But it should be approximately correct in principle.)The usual solution is to set up a convenient and possible timer (say, 10ms) to cause an interrupt, and then handle additional counting in software.

author: Psi
author_rank: Super Contributor
timestamp: May 02, 2013, 09:40:27 am
content: This shows a timer driven software counter using variables as flags for various time periodshttp://www.eevblog.com/wiki/index.php?title=Embedded_Programming_Tips_and_Tricks_for_Beginners#Repeating_Code_Using_Timer_Overflow_Interrupts

author: kripton2035
author_rank: Super Contributor
timestamp: May 02, 2013, 09:44:59 am
content: it would have been easier to say you 're using a PIC18F87J11you can get a nice free pic 16-18 timer calculator and play with it here :http://pictimer.picbingo.com/it will be easier to understand by practicing.regards,

author: ecat
author_rank: Frequent Contributor
timestamp: May 02, 2013, 10:04:40 am
content: Quote from: kripton2035 on May 02, 2013, 09:44:59 amHumm, I looked at that page a short while ago: Go to Download page and...PI Timer Calculator.exe is372KPI Timer Calculator - Setup.exe is5.8MBThe link for PI Timer Calculator.exe is broken so, if you want the app your only option is the 5.8MB setup file. I don't mind downloading 5.8MB if I know what's in the file but 372K program + 5.5MB of unknown data??? Humm, I gave it a miss.If the PIC18F87J11 is close enough to the 16F877A you could give this a go:http://eng-serve.com/pic/pic_timer.html

author: Niklas
author_rank: Frequent Contributor
timestamp: May 02, 2013, 11:43:58 am
content: Start the timer and setup its clock source and prescaler options16 bits, internal clock, prescaler 256T0CON = 0b10000111;Load TMR0H:TMR0L with appropriate values to get 10 seconds.Fosc = 4 MHz gives 1 us per instruction and 256*65536*1us = 16 777 216 us.We must calculate a new value to reload to TMR0H:TMR0L on each interrupt. 256*X*1us = 10 000 000 us gives X = 3906239062 is how many instruction cycles the timer must count and it will overflow on 65536. Reload value is 65536-39062+LatencyLatency is to compensate for the instructions executed between the overflow interrupt and the actual reload of TMR0H:TMR0L. Set a breakpoint in MPLAB Sim and check the actual time on the watch window.Enable interruptINTCONbits.TMR0IF = 0;INTCONbits.TMR0IE = 1;also set bits GIEH and GIEL in INTCONIn the interrupt routineTMR0H = ReloadValue>>8;TMR0L = ReloadValue&0xFF;INTCONbits.TMR0IF = 0;

author: Skimask
author_rank: Super Contributor
timestamp: May 02, 2013, 02:15:40 pm
content: Quote from: westfw on May 02, 2013, 09:28:23 amClose, but the PIC runs 4 clocks per instruction...therefore, @ 4Mhz, 1Mhz instruction rate / 65536 / 256 = ~16.7 seconds.But no matter, the O/P won't understand anyways. Read the rest of his posts.

author: westfw
author_rank: Super Contributor
timestamp: May 02, 2013, 03:28:14 pm
content: QuoteThanks for the correction; the time need not run at the instruction rate, but I see (looking more closely at the datasheet) that the timer does indeed run at Fosc/4. I guess that in this particular case, that makes a big difference!

author: kripton2035
author_rank: Super Contributor
timestamp: May 02, 2013, 04:06:44 pm
content: Quote from: ecat on May 02, 2013, 10:04:40 amthe 372K file should be ok and enoughtthe 5 Mb file may contain .net or something to install completelypeople already have the .net framework so try the 372K file first

author: glatocha
author_rank: Regular Contributor
timestamp: May 04, 2013, 02:09:22 am
content: Quote from: Niklas on May 02, 2013, 11:43:58 amThe Latency you could basically read from the Timer itself. When using 256 prescaller the latency should be 0 as the interrupt delay supposed to be ~4 cycles (AFAIR).But the trick is, that writing the Timer resets the prescaller. In my experience I was not able to do exact time calculation with the clock running with system speed.

author: Niklas
author_rank: Frequent Contributor
timestamp: May 05, 2013, 10:35:58 pm
content: Quote from: glatocha on May 04, 2013, 02:09:22 amThe interrupt latency of 4 cycles is not the same as the timer reload latency. The PIC18 series has 2 interrupt vectors and you must poll the interrupt flags inside the interrupt handler. I usually put critical timer reloads inside the high priority interrupt and first thing there.Code:void ISR_High(void){if(INTCON.T0IF && INTCON.T0IE){// Reload TMR0TMR0H = 0x11;TMR0L = 0x22;...Set flags and do other necessary things here...// Clear the interrupt flagINTCON.T0IF = 0;}if(INTCON.XXIF && INTCON.XXIE){}if(PIR1.XXIF && PIE1.XXIE){}}I would set a breakpoint on the line with TMR0H = 0x11 and use the stopwatch in MPLAB to tweak the reload value. Dont forget to set the correct frequency in the simulator settings! Run a couple of times and check for consistency.You have a good point about the prescaler reset upon timer reload. If the timer is a high priority interrupt and handled first in the ISR, the amount of "lost" cycles will be minimized. With a prescaler value of 256 and a timer value of almost 40000, I think the latency compensation might be overkill in this case.

author: glatocha
author_rank: Regular Contributor
timestamp: May 06, 2013, 12:33:17 am
content: Yes, the amount of lost cycles will be small. And I think reasonably stable. Just the case is for what reason you need it. You will not make RTC on that, but should be sufficient for other purpose.In the picture you have my software PWM timing. I have aimed for 10kHz interrupt. Got ~10,05 cause by the reset of prescaller.

author: tahmod
author_rank: Contributor
timestamp: May 06, 2013, 11:26:50 am
content: I have done a mistake the clock frequency is 8Mhz and not 4Mhz .The first calculator I download it did not work by kripton2035.ecat it is different the instruction code.-This is my code for the interupt, what wrong with it?-I tried to calculate like westfw said I did not able to get 10 second. What can I do?bsf INTCON,GIE ;enable global interuptStatebsf INTCON,5 ;enable interupt (the TMRO overflow)Interuptbcf INTCN,5 ;disable timer interupt so no further disturbance of flow of programclrf INTCON,2 ;clear the interuptmovlwmovwl TMROHmovlwmovwf TMROLbsf DLretfie ;making GIE enable for further interrupt

author: kripton2035
author_rank: Super Contributor
timestamp: May 06, 2013, 11:34:07 am
content: max you can get with 4MHz clock is some 4 sec delay ... so with 8MHz it will be 2 sechere is a setup that will give you 2 sec precisely. run it 5 times and you will get your 10 sec.Code:// Timer0 Registers:// 16-Bit Mode; Prescaler=1:256; TMRH Preset=B; TMRL Preset=DC; Freq=0.50Hz; Period=2.00 sT0CON.TMR0ON = 1;// Timer0 On/Off Control bit:1=Enables Timer0 / 0=Stops Timer0T0CON.T08BIT = 0;// Timer0 8-bit/16-bit Control bit: 1=8-bit timer/counter / 0=16-bit timer/counterT0CON.T0CS = 0;// TMR0 Clock Source Select bit: 0=Internal Clock (CLKO) / 1=Transition on T0CKI pinT0CON.T0SE = 0;// TMR0 Source Edge Select bit: 0=low/high / 1=high/lowT0CON.PSA = 0;// Prescaler Assignment bit: 0=Prescaler is assigned; 1=NOT assigned/bypassedT0CON.T0PS2 = 1;// bits 2-0 PS2:PS0: Prescaler Select bitsT0CON.T0PS1 = 1;T0CON.T0PS0 = 1;TMR0H = 0xB; // preset for Timer0 MSB registerTMR0L = 0xDC; // preset for Timer0 LSB register

author: Niklas
author_rank: Frequent Contributor
timestamp: May 06, 2013, 01:34:30 pm
content: Quote from: kripton2035 on May 06, 2013, 11:34:07 amHave a look at Figure 13-2 on page 194 in the datasheet of PIC18F87J11.With Fosc = 4MHz you will get 1us per instruction and the timer is clocked with 1 MHz (4MHz/4).With the prescaler set to 256 it will take 256 us for it to overflow and clock TMR0H:TMR0L once. TMR0H:TMR0L is setup as a 16 bit timer and will timeout in maximum 65536*Tprescaler, 65536*256us = 16777216 us.At Fosc = 8 MHz you will get a maximum timeout period of 8388608 us.Our values differ by a factor of 4 so I assume that you have the 4xPLL enabled. My calculations assumes the PLL is turned off.

author: Niklas
author_rank: Frequent Contributor
timestamp: May 06, 2013, 01:42:23 pm
content: Quote from: tahmod on May 06, 2013, 11:26:50 amCan you post the complete code for the interrupt routine?You dont have to clear the bit INTCON,5 in the interrupt routine as the global interrupt enable is disabled during interrupt. The GIE bit is set by the retfie command at the end of the interrupt handler. The second line in the interrupt is wrong. Replace clrf with bcf and move that line down to bsf DL to minimize the timer reload latency.

author: kripton2035
author_rank: Super Contributor
timestamp: May 06, 2013, 06:25:53 pm
content: Quote from: Niklas on May 06, 2013, 01:34:30 pmyes you're right.but with pll turned off and prescaler to 256, you can't get exact 5 sec period (you get 4.999936 sec)as 10 can only be divided by 5 or 2, I gave an answer with 2 sec.

author: glatocha
author_rank: Regular Contributor
timestamp: May 06, 2013, 11:08:55 pm
content: Quote from: kripton2035 on May 06, 2013, 06:25:53 pmWhat do you mean by that?You have many options. You can divide 10 by 3 and run Timer in 3.33s. By 4 and run 2.5s and so on...tahmod- how precise your 10s needs to be? How big error will you accept?

author: kripton2035
author_rank: Super Contributor
timestamp: May 07, 2013, 06:35:37 am
content: Quote from: glatocha on May 06, 2013, 11:08:55 pmyes it depends on required precision.10 is exactely divisible by 2 and 510 divided by 3 is 3.3333333333333333333333333333333333... and I miss an infinite amount of 3all depends on precision.