Searching \ for '[PIC]: TMR0 update dead time' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/time.htm?key=time
Search entire site for: 'TMR0 update dead time'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: TMR0 update dead time'
2000\08\13@130045 by w. v. ooijen / f. hanneman

picon face
I try to get my 16F84 interrupt routine called at a certain interval, with
0 cumulative error. The interval is not 256 * the instruction rate (but for
instance N * times, N < 256), so I must update TMR0 inside the interrupt
routine. My first attempt was to set TMR0 to a fixed value, but that does
not work because the interrupt latency varies depending on the instruction
being executed. Now I add a fixed delta to TMR0, but I do no find
sufficient information in the 16F84 datasheet to calculate this delta.
Emperically I come up with ( 5 - N ), which would mean that the update of
TMR0 causes it to miss 5 increments.

Q1: Can this magical value somehow be derived from the datasheets?

Q2: Would this value be the same when I use a prescaler factor other than
1?

Wouter

--
http://www.piclist.com hint: To leave the PICList
spam_OUTpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu>

2000\08\13@132818 by Bob Blick

face
flavicon
face
Hi Wouter,

The datasheet shows that TMR0 will not increment for a few cycles after
being written to. They are processor cycles, so if you use the prescaler
the effect is not so severe.

Calculating the delay never seems to work for me, I have to count cycles
for it to work out :-(

Cheers,

Bob

At 06:55 PM 8/13/2000 +0200, you wrote:
{Quote hidden}

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestspamKILLspammitvma.mit.edu>

2000\08\13@152634 by Oliver Broad

flavicon
face
I think if you add a value to the TMR0 instead of overwriting it you can
minimise the error, which presumeably comes from the write being several
cycles into the ISR. Alternatively you might resynchronise by adding the
residual value of TMR0 to the PC and then having a long string of NOPs. I
believe this technique was raised in an early appnote as an alternative to
interrupts. It would leave the PC and TMR0 in step so that your ISR code
would execute at exactly the right time at the expense of an intel-like
interrupt latency.

If a prescaler is used I think it is difficult to see how to get rid of the
error absolutely as the prescaler gets cleared by writing anything at all to
TMR0. To get rid of the error you would need to synchronise to the
prescaler, in order that the counts lost when the prescaler was cleared were
the same every time.

I guess you might try something like first roughly synchronising:

X1 BTFSS TMR0,0
   GOTO X1
;TMR0 BIT0 IS NOW KNOWN TO BE SET

then synchronising to 2 cycles accuracy.

BTFSS TMR0,0
GOTO X2
BTFSS TMR0,0
GOTO X2
BTFSS TMR0,0
GOTO X2
BTFSS TMR0,0
GOTO X2
;REPEAT PRESCALER/2 TIMES, or insert padding code before the tests.
;THIS NEARLY SYNCHRONISES, BUT WE MIGHT STILL BE
;ONE CYCLE OUT
;BOTTOM BIT OF TMR0 NOW CLEAR
X2    ;INSERT N CYCLES OF PADDING CODE
   BTFSS TMR0,0;IF BOTTOM BIT OF TMR0 IS STILL CLEAR THEN
        ;WE DETECTED IT EARLY AND SHOULD INSERT
       ;1 CYCLE DELAY
GOTO X3
X3

Without playing with the simulator a lot I cannot tell you what N needs to
be, the aim is to reach the last test just before or just after the last
transition so we first determine roughly when the transition will occur,
then trap it more and more accurately. I think this code might still lose
cycles if the bottom bit toggled from set to clear immediately after the
first test instruction but I hope you can see the idea and see how to
tighten it up. Alternatively you might find it easier to implement a
'postscaler' in software.

Personally I think the TMR0 interrupt is not very usefull for generating
acurately timed interrupts. If the interrupt is never masked in the main
program I presume the uncertainty in the interrupt is only one cycle, which
could be corrected by checking when bit TMR0,0 becomes set again, knowing
that it could only set on one of two program cycles, corresponding to two
locations in the ISR.

Can you wear having polls at periodic locations in your main loop, because I
think the simplest way to greater timer period accuracy can be achieved by
maintaining a TMR0 shadow, which is compared with the TMR0 value, then when
(TMR0-shadow) mod256 is positive then execute your 'ISR' code and add an
increment to the shadow to set when the next call should occur. By not
writing to TMR0 ever the prescalar is left to free-run, so though there will
be errors in the call timing they will not accumulate.

Oliver.



{Original Message removed}

2000\08\13@180519 by Olin Lathrop

flavicon
face
> I try to get my 16F84 interrupt routine called at a certain interval, with
> 0 cumulative error. The interval is not 256 * the instruction rate (but
for
> instance N * times, N < 256), so I must update TMR0 inside the interrupt
> routine. My first attempt was to set TMR0 to a fixed value, but that does
> not work because the interrupt latency varies depending on the instruction
> being executed. Now I add a fixed delta to TMR0, but I do no find
> sufficient information in the 16F84 datasheet to calculate this delta.
> Emperically I come up with ( 5 - N ), which would mean that the update of
> TMR0 causes it to miss 5 increments.

This sounds very high.  I don't happen to have the 16F84 data sheet in front
of me, but I do have the 16F87x data sheet, which probably has the same
timer 0 module.  This data sheet says "If the TMR0 register is written, the
increment is inhibited for the following two instruction cycles", which
seems quite clear.  It also says "When assigned to the Timero module, all
instruction writing to the TRM0 register will clear the prescaler".
Therefore the delta is not predictable when using the prescaler since an
unpredictable number of clocks get lost, up to the prescaler divide value -
1.

Therefore if you have to generate regular interrupts with no cumulative
error, and you have to use timer 0, then you can't use the prescaler.  If
you need longer periods between interrupts than 256 instruction cycles, you
have to take multiple interrupts and count the timer 0 overflows yourself.
Fortunately this is pretty easy.


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, .....olinKILLspamspam.....cognivis.com, http://www.cognivis.com

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspam_OUTspamTakeThisOuTmitvma.mit.edu>

2000\08\14@042936 by Snail Instruments

flavicon
face
Hi Wouter,

you should _add_a constant to the TMR0 instead of loading it with constant
value. If you need interrupt after N cycles, the constant is -N+2 (assuming
no prescaler). The +2 reflects that TMR0 isn't incremented two cycles when
it is written to.

>I try to get my 16F84 interrupt routine called at a certain interval, with
>0 cumulative error. The interval is not 256 * the instruction rate (but for
>instance N * times, N < 256),
>...

>
>Q1: Can this magical value somehow be derived from the datasheets?

Probably yes, combining the interrupt latency and updating TMR0 sections.

>Q2: Would this value be the same when I use a prescaler factor other than
>1?

Using prescaler is problematic. Prescaler gets always cleared, when TMR0 is
updated. You could go thru some sychronizing the code to the TMR0
prescaler, but counting multiple interrupts instead of using prescaler
seems more feasible to me.

BTW, I'd bet you are working on a new library of interrupt driven UART (or
delay) routines for JAL. Am I correct? ;-)

Josef

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements

2000\08\14@151157 by w. v. ooijen / f. hanneman

picon face
> > Emperically I come up with ( 5 - N ), which would mean that the update
of
> > TMR0 causes it to miss 5 increments. [Wouter]

I have pieced the answer together. The numbers between braces are the
'missed' increments.

(2) After a TMR0 update the increments are blocked for 2 instructions.
(1) The read part of an instruction happens in Q2, the write part in Q4,
but TMR0 update is in Q3!
(2) The update code is MOVFW TMR0; ADDWF DELTA, W; MOVWF TMR0

Hence a total of 5. I will sleep better now that theory and practical
results are in agreement....

As often I overlooked the solution because there were two problems that I
overlooked: the one updated missed in a read-modify-write instruction and
the fact that Jal generates this stupid code (I assumed MOVFW DELTA; ADDWF
TMR0, F). Which will of course be cured. Classical case of "the problem can
not be a) because then .... and it can not be b) because .....": no dummy,
the problem is a) + b).

> Calculating the delay never seems to work for me, I have to count cycles
> for it to work out :-( [Bob]

It seems to work. After 20 hours running the PIC has run ~ 10 seconds too
fast, or about 1 in 1000. Is this to be expected without tuning a C? I use
a 16F84-10 with 10 MHz Xtal and tow 20 pf C's.

> BTW, I'd bet you are working on a new library of interrupt driven UART
(or
> delay) routines for JAL. Am I correct? ;-) [Josef]

Actually it is for a data logger, but I will reorganize the Jal interval
library that was haunted by the interrupt jitter accordingly.

Wouter

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements

2000\08\14@151614 by Andrew Kunz

flavicon
face
>It seems to work. After 20 hours running the PIC has run ~ 10 seconds too
>fast, or about 1 in 1000. Is this to be expected without tuning a C? I use
>a 16F84-10 with 10 MHz Xtal and tow 20 pf C's.

I think 1 in 1000 (0.1%) is a pretty bad value unless you are using an RC
circuit for a clock or running at temperature extremes.

Andy

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements

2000\08\14@152234 by Dan Michaels

flavicon
face
Wouter wrote:
.........
>
>> Calculating the delay never seems to work for me, I have to count cycles
>> for it to work out :-( [Bob]
>
>It seems to work. After 20 hours running the PIC has run ~ 10 seconds too
>fast, or about 1 in 1000. Is this to be expected without tuning a C? I use
>a 16F84-10 with 10 MHz Xtal and tow 20 pf C's.
.........
>

For rapid developemnt/testing of this sort of thing, you might try
setting/resetting a pin inside the timing loop, and looking with a scope.
By triggering on the pin, it is very easy to tell whether an extra clock
cycle gets inserted every now and then.

- danM

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements

2000\08\15@132710 by Barry Gershenfeld

picon face
>>It seems to work. After 20 hours running the PIC has run ~ 10 seconds too
>>fast, or about 1 in 1000. Is this to be expected without tuning a C? I use
>>a 16F84-10 with 10 MHz Xtal and tow 20 pf C's.
>
>I think 1 in 1000 (0.1%) is a pretty bad value unless you are using an RC
>circuit for a clock or running at temperature extremes.

10 seconds in 20 hours is more like 1 in 7200, for .015%   That's
better...seems like hobby grade crystals used to be .005% or .01% so
that's not so bad.  It's always good when you come out high
because you can add a little more picofarads to get down to
the frequency you want.

Barry

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...