Author Topic: PIC TMR0 adjustment - Trap for young players?  (Read 3553 times)

0 Members and 1 Guest are viewing this topic.

Offline igendelTopic starter

  • Frequent Contributor
  • **
  • Posts: 359
  • Country: il
    • It's Every Bit For Itself (Programming & MCU blog)
PIC TMR0 adjustment - Trap for young players?
« on: August 21, 2016, 11:10:49 am »
Hi,

While writing this, I have a feeling that the PIC programmer folk are snickering behind by back, but...  :)

I wanted to generate a 104us periodic interrupt on an 8-bit PIC (e.g. PIC12F675) using Timer0. The clock is the internal oscillator, effectively 1MHz (1us per instruction). Now, Timer0 can only generate an interrupt when its 8-bit counter, TMR0, overflows from 0xFF to 0x00 - meaning once per 256us, which is too slow for my requirements.

However, as the datasheet heartily suggests, we can write new values directly to TMR0. If we set TMR0 at the beginning of the ISR function to 152, it will only need 104 more cycles* to reach 0x00 and I'll have our desired 104us period.

* Yes, I know about the two-cycle count inhibition... let's ignore that for now

But here's the trap: try the above and you won't get 104us. It'll be closer to 125us. My understanding is that it's because there's a time gap between the interrupt event and the setting of TMR0: The MCU needs time to enter the ISR and run the instructions until the new value is in place. Makes sense, right? What's really weird for me is that I found no reference to this anywhere. Every online/offline "timer calculator" I tried, even Microchip's own "MPLAB Code Configurator" that generates code for you, makes the mistake of ignoring this time gap (I tested it on a PIC12F1840). Is everyone's timing off by ~20 clock cycles? Can anyone provide some feedback on this finding?

Thanks!
Maker projects, tutorials etc. on my Youtube channel: https://www.youtube.com/user/idogendel/
 

Offline ludzinc

  • Supporter
  • ****
  • Posts: 506
  • Country: au
    • My Misadventures In Engineering
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #1 on: August 21, 2016, 11:25:36 am »
Yep

Been there, empirically done that.

There's overhead to account for. Either calculate or measure.

I measured it, found it repetable across multiple devices (100 or so) and called it done.
 
The following users thanked this post: igendel

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #2 on: August 21, 2016, 11:30:28 am »
Quote
you won't get 104us. It'll be closer to 125us.

Something is at work here.

Generally, don't write to TMR0.

If you have to, use increments:

Code: [Select]
  TMR0+=-PERIOD; //load offset

However, you will likely see a small error that way, as the value of TMR0 will continue to increment as its value is being modified.

As to ISR overhead, it only impacts the very first period. After that, the same overhead is applied to consecutive ISR invocation so your timing (since the last invocation) is the same.
================================
https://dannyelectronics.wordpress.com/
 

Offline igendelTopic starter

  • Frequent Contributor
  • **
  • Posts: 359
  • Country: il
    • It's Every Bit For Itself (Programming & MCU blog)
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #3 on: August 21, 2016, 11:48:15 am »
Generally, don't write to TMR0.

 :)

If you have to, use increments:

Code: [Select]
  TMR0+=-PERIOD; //load offset

However, you will likely see a small error that way, as the value of TMR0 will continue to increment as its value is being modified.

That does make sense.

As to ISR overhead, it only impacts the very first period. After that, the same overhead is applied to consecutive ISR invocation so your timing (since the last invocation) is the same.

I'm not sure I understood this one... indeed there's the same overhead each time, so each and every period is off by that overhead; if I set TMR0 to 152, the next interrupt will be triggered after 104us, but will still require the extra time until I can actually set TMR0 again.
Maker projects, tutorials etc. on my Youtube channel: https://www.youtube.com/user/idogendel/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #4 on: August 21, 2016, 12:00:46 pm »
let's say the ISR overhead is 20ticks / 20us.

So 20 ticks after the TMR0 overflows, your ISR is executed; In your case, another 104us - 20us later, your TMR0 overflows, and 20us later, your ISR gets executed again.

The time between the two invocations is 104us - 20us + 20us = 104us.

The ISR overhead doesn't matter.

Going back to TMR0 offset, if you really want to get your timing right, do this:

Code: [Select]
  TMR0+=-PERIOD+TMR0_ERROR;

where TMR0_ERROR accounts for the time elapsed in modifying TMR0. Usually it is 2.
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #5 on: August 21, 2016, 12:03:08 pm »
Quote
Generally, don't write to TMR0.

The problem gets more interesting when a prescaler is used on a fast signal.
================================
https://dannyelectronics.wordpress.com/
 

Offline igendelTopic starter

  • Frequent Contributor
  • **
  • Posts: 359
  • Country: il
    • It's Every Bit For Itself (Programming & MCU blog)
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #6 on: August 21, 2016, 12:07:11 pm »
So 20 ticks after the TMR0 overflows, your ISR is executed; In your case, another 104us - 20us later, your TMR0 overflows, and 20us later, your ISR gets executed again.

Right - if I adjust for PERIOD as you suggested. I thought you meant the setup I described at the beginning.

We should also be careful if we change the ISR (add another interrupt-source check before checking the Timer0 flag), or if we change the compiler (e.g. from free to pro).
Maker projects, tutorials etc. on my Youtube channel: https://www.youtube.com/user/idogendel/
 

Offline igendelTopic starter

  • Frequent Contributor
  • **
  • Posts: 359
  • Country: il
    • It's Every Bit For Itself (Programming & MCU blog)
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #7 on: August 21, 2016, 12:13:50 pm »
The problem gets more interesting when a prescaler is used on a fast signal.

Heh, "Interesting" may not be the most accurate adjective here :D
What I still don't get is why this matter isn't mentioned anywhere (that I could find so far, anyway). It really is a trap, for instance if someone trusts the MPLAB Code Composer blindly.
Maker projects, tutorials etc. on my Youtube channel: https://www.youtube.com/user/idogendel/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #8 on: August 21, 2016, 12:15:27 pm »
Quote
We should also be careful if we change the ISR (add another interrupt-source check before checking the Timer0 flag), or if we change the compiler (e.g. from free to pro).

Short of a caveat, none of that matters to the approach I gave earlier.

Where it fails is if the timer has advanced so much and / or the value of PERIOD is so short so that the operation caused an overflow.
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #9 on: August 21, 2016, 12:16:47 pm »
Quote
What I still don't get is why this matter isn't mentioned anywhere (that I could find so far, anyway).

It is well documented in the datasheet.

Quote
It really is a trap, for instance if someone trusts the MPLAB Code Composer blindly.

Well, that's the fault of the person who trusts blindly, either MPLAB Code Composer or anything else.
================================
https://dannyelectronics.wordpress.com/
 

Offline igendelTopic starter

  • Frequent Contributor
  • **
  • Posts: 359
  • Country: il
    • It's Every Bit For Itself (Programming & MCU blog)
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #10 on: August 21, 2016, 12:25:34 pm »
Quote
We should also be careful if we change the ISR (add another interrupt-source check before checking the Timer0 flag), or if we change the compiler (e.g. from free to pro).
Short of a caveat, none of that matters to the approach I gave earlier.

The approach will still work, but the PERIOD value probably won't be the same. We'll have to measure/cycle-count it again, right? Edit: No, I get what you're saying now  :)

It is well documented in the datasheet.

But in entirely separate sections, not as a single topic/discussion as far as I can see.

Well, that's the fault of the person who trusts blindly, either MPLAB Code Composer or anything else.

Yeah well, of course I won't build an application without testing each and every part of it - that's how I found this issue - but still, one would expect some minimal correlation between MCC-generated code and the user requirements...  :P
« Last Edit: August 21, 2016, 12:40:31 pm by igendel »
Maker projects, tutorials etc. on my Youtube channel: https://www.youtube.com/user/idogendel/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #11 on: August 21, 2016, 01:31:17 pm »
Quote
one would expect some minimal correlation between MCC-generated code and the user requirements...  :P

Not sure. I would say generally no: the configurator's job is to provide you with building (code) blocks that you can assemble together for your application. It has no knowledge of your application and the responsibility has to reside with the user of such configurators to make sure that the generated code works to that specific application.

Putting too much faith in the configurator to get it right for your application is risky, as you have shown here.
================================
https://dannyelectronics.wordpress.com/
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #12 on: August 24, 2016, 12:55:47 am »
Every online/offline "timer calculator" I tried, even Microchip's own "MPLAB Code Configurator" that generates code for you, makes the mistake of ignoring this time gap
It's not a mistake. It's a well documented limitation of Timer0 that it cannot generate periodic interrupts with arbitrary timing. You can emulate it in software, but of course that will result in timing variations caused by the software overhead.

Is it a trap for young players? Yes, but only for those who think they can get away with programming a chip without knowing its features and limitations. The first step in working with any MCU should be to read the datasheet, so you know what it is capable of and how to use it.

Quote
Is everyone's timing off by ~20 clock cycles?

If they use that method then yes, their timing will be off. You can tweak the count to get close to the timing you want, but there is no guarantee that it will be single cycle accurate.  In many cases that is good enough. When it isn't you use a different method, eg. change the system clock to a frequency that gives the correct timing with a count of 256, or use a PIC which has a more advanced timer.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11631
  • Country: my
  • reassessing directives...
Re: PIC TMR0 adjustment - Trap for young players?
« Reply #13 on: August 24, 2016, 11:38:27 am »
what compiler? have you looked at disassembled code? tracing from interrupt vector to where you set the TMR0?
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf