TMR0 Preloading Count

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

TMR0 Preloading Count

Post by Ron »

I found web page that describes a way to prelaod a value into the TMR0 counter so that it does not count 0 to 255 but rather from the "preloaded" value to 255.

20MHz, prescale 8 (2441.41Hz) with preload of 6 give me prefect 10ms multiplier when looped, based on their spreadsheet. I want to count time in multiples of 10ms.

http://www.vermontficks.org/pic_calculations.htm

I am trying to get TMR0 to be more accurate. I am running at a freq of 2441.41. I have tried alternating between 24 and 25 loops at this freq which on paper averages 10.07ms per TMR0 int but my timing is slightly off and this error grows as the target time increases. I am hoping to be able to use the technique they describe with the TMR0 component macro.

If I can preload TMR0 count with 6, based on their spreadsheet, then I should be able to get TMR0 working better.

Is it possible for the TMR0 component macro to be altered as they describe, and have it work as described?

If yes, how do I do it?

I also found this site which also describes something similar and mentions BoostC

http://forum.sourceboost.com/index.php? ... &pid=11038

search for tmr0 +=9; // add 9 to generate interrupt every 250us. to see.

I am hoping I can simply as a "C" block with this code in it for a value of 6.

Thank you,

Ron

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: TMR0 Preloading Count

Post by medelec35 »

Take a look here:
http://www.matrixmultimedia.com/mmforum ... =26&t=6623

It is a spreadsheet calculator which could give you the information you are after:
Int_cal.jpg
Int_cal.jpg (123.03 KiB) Viewed 12929 times
Also attached is the way in which a C box is added to start Timer0 at 6 - See Timer0_int macro. It also displays this information on my spreadsheet.
Hope this helps.
Attachments
V3 UsingTimer0.fcf
(4 KiB) Downloaded 737 times
Martin

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: TMR0 Preloading Count

Post by Ron »

Hi,

Thank you for the information.

I am having a problem in that tmr0 = 6; does not compile in my project.

I have compiled it in your project fine.

Any ideas as to why?

I even copied your block into my project and it fails to compile.


E:\Back Up Items\Step By Step\Flowcode Projects\18F 5 SEQ PAUSE REV 2\184620 5 Seq PAUSE REV 2.c(38388:2): error: unknown identifier 'tmr0'
E:\Back Up Items\Step By Step\Flowcode Projects\18F 5 SEQ PAUSE REV 2\184620 5 Seq PAUSE REV 2.c(38388:2): error: invalid operand 'tmr0'
E:\Back Up Items\Step By Step\Flowcode Projects\18F 5 SEQ PAUSE REV 2\184620 5 Seq PAUSE REV 2.c(38388:7): error: failed to generate expression
184620 5 Seq PAUSE REV 2.c success

failure

Return code = 1

Flowcode was unable to compile the flowchart's C code due to the following errors:


If your flowchart contains C code, please review this carefully. If your flowchart contains no C-code or you have thoroughly reviewed the code, contact Technical Support.

FINISHED

I am using an 18F4620 if that makes any difference.

Thank you,

Ron

Flowcode V3

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: TMR0 Preloading Count

Post by medelec35 »

Yes the microcontroller used can make a difference. Because you did not post any chip information, or a flowcode example, I used the most common example of16F88. This was used since it's the default chip when new flowcode is created and has a 8 bit timer0 so tmr0 = 6; is used for setting starting value.
I believe the 18F range has a 16 bit timer (uses tmr0l and tmr0h), but can be used in 8 bit mode. Therefore you need to add l (lowercase L not number 1) after tmr0.
So try tmr0l = 6;
Let us know is that helps.
Thanks.
Martin

User avatar
Steve
Matrix Staff
Posts: 3421
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: TMR0 Preloading Count

Post by Steve »

Flowcode already does this automatically without needing C code, but only with TMR2 on some chips (e.g. 16F88). If you look at the interrupt properties for this chip, there is a drop-down for the "roll-over value". You can actually type numbers into this (between 1 and 256) which will do what you are suggesting.

Of course, the approach used by Medelec is fine and needs to be adopted on the other timer modules.

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times
Contact:

Re: TMR0 Preloading Count

Post by Sean »

Just a quick warning about updating timer values.

Writing to a timer count register can be the cause of inaccuracies.

The write operation causes the current prescaler value to be reset. If the prescaler is set to 8:1, and the timer count value is updated when the prescaler has counted to 7, the prescaler will be reset and a further 8 source clock cycles will be required.

Writing tmr0l = 6 will cause further inaccuracies if the value in tmr0l was not zero when the command was executed.

Writing tmr0l += 6 is usually a better option, but will cause a 1 count error if the timer increments during the update process (read-modify-write).

If tmr2 is available (not used for PWM) it can provide error free, adjustable timer interrupts. The pr2 register is used to hold the maximum count value for the timer. Its default value is 255, allowing full 8-bit operation, but this can be reduced to shorten the interrupt period. Everything is handled in hardware, so no errors are introduced.

The capture/compare modules (ccp) associated with other timers can also provide very flexible and accurate timing functions. The MultiServo programs demonstrate these features using tmr1.

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: TMR0 Preloading Count

Post by medelec35 »

Thanks for that steve and sean that is certainly useful information. Do you think the rollover value entry on Timer2 could be extended to Timer0 and Timer1?
This would help to reduce inaccuracies, when timer0 or Timer1 are only timers available.
Last edited by medelec35 on Fri Nov 06, 2009 10:17 pm, edited 1 time in total.
Martin

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: TMR0 Preloading Count

Post by Benj »

Hello Medelec

Unfortunatley the only reason that timer 2 has the advanced rollover features in Flowcode is because it is supported by the hardware.

AVRs have similar features on all of their timer interrupts but PICs are limited to a single timer.

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: TMR0 Preloading Count

Post by medelec35 »

OK thanks ben. So there is no way for Flowcode to place an automatic tmr0 =+6 or tmr0l =+6 (or whatever ) during compiling sequence if there is a option to select required interrupt frequency?

If not was worth a try.
Martin

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: TMR0 Preloading Count

Post by Benj »

Hello

Yes this is possible to do, however there is still the potential for the problems that Sean mentioned before.

It should be possible to modify an FCD file to allow the timer interrupts to be more customizable.

Here is a line from the standard Flowcode v4.2 timer 0 interrupt definition in an FCD file.

HandlerCode="if (ts_bit(intcon, TMR0IF) && ts_bit(intcon, TMR0IE))\n{\n\tFCM_%n();\n\tcr_bit(intcon, TMR0IF);\n}\n"

You could change this to

HandlerCode="if (ts_bit(intcon, TMR0IF) && ts_bit(intcon, TMR0IE))\n{\n\tFCM_%n();\n\tcr_bit(intcon, TMR0IF);\n\ttmr0=tmr0+6;\n}\n"

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: TMR0 Preloading Count

Post by medelec35 »

That would be great if there was a drop-down box to select required int freq, and flowcode put the tmr0 = +6 etc. as previously stated.

At the moment if using timer0 or timer1, it is easier to use a C box rather than edit fcd file.

Although what you have posted about changing fcd is interesting.

Is there a good reference guide to fcd files? E.g. HandlerCode="if (ts_bit(intcon, TMR0IF) && ts_bit(intcon, TMR0IE))\n{\n\tFCM_%n();\n\tcr_bit(intcon, TMR0IF);\n}\n" and what it all means

Or is it a case of learn C then your fully understand fcd files

I understand about the accuracies, I did some testing and there was a trigger every 9985.20 uS which is -0.15% out.

This was with tmr0 = +6.

And

Trigger every 10105.20 uS
Which is 1% out.
This was with tmr0 = 6.

Note: set-up was a simulator and not real hardware, will try on real hardware later, and compare the difference. But the accuracy of results would only be as accurate as scope displaying results.
Martin

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: TMR0 Preloading Count

Post by Ron »

Hi,

It sounds like Timer 2 would be a better solution for me. I am using both 16F886/887 and 18F4620/2620 chips in my project, all running at 20MHz. I eventually want to get the 18F running at 40Mhz.

I would like to experiment with this. Can someone provide me with the required code to do it? Since there is no Timer 2 INT provided for the chips I am using. Any chance the component macros can be updated in V3 to support the other timers?

16F887/18F4620 - 20MHz - end goal is to count in 10ms periods. I would prefer to be required to do a loop count of at least 10. Currently I am using 400us time period for tmr0 INT. I would like the Timer INT time period to be 500 1ms if this is possible.

Thank you to everyone that has helped with my many TMR0/INT posts looking for an answer to these issues.

Ron

Post Reply