TMR0 Preloading Count
TMR0 Preloading Count
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
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
-
- 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
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: 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.
http://www.matrixmultimedia.com/mmforum ... =26&t=6623
It is a spreadsheet calculator which could give you the information you are after: 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 739 times
Martin
Re: TMR0 Preloading Count
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
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
-
- 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
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.
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
- Steve
- Matrix Staff
- Posts: 3422
- Joined: Tue Jan 03, 2006 3:59 pm
- Has thanked: 114 times
- Been thanked: 422 times
- Contact:
Re: TMR0 Preloading Count
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.
Of course, the approach used by Medelec is fine and needs to be adopted on the other timer modules.
-
- 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
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.
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.
-
- 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
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.
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
- 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
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.
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.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- 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
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.
If not was worth a try.
Martin
- 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
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"
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"
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- 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
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.
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
Re: TMR0 Preloading Count
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
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