|
|
View previous topic :: View next topic |
Author |
Message |
micro_debugger
Joined: 08 Oct 2009 Posts: 73
|
PIC16F1823 TIMER1 INTERRUPT - some clarifications needed |
Posted: Thu Feb 27, 2014 2:22 pm |
|
|
Hi,
I have some questions about the #INT_TIMER1 interrupt:
1. What is the latency before handling of it by controller. I mean, not the default described by microchip (4-5 cycles) but the interrupt handler provided by the CCS. The latency before interrupt occurs, and the first instruction of the
#INT_TIMER1 interrupt routine will be executed?
2. When the timer1 is running, and fire-up the interrupt (due to 0x0000 pass), the timer is still running, or waiting until interrupt will be handled?
I mean, when I will read the timer1 value with ticker=get_timer1(); it will be zero or a value of some ticks, due to latency.
I tested it, and always is zero
Any help, will release me for this point.
My compiler version is 5.020
Thank you in advance
Warmest Regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 27, 2014 3:38 pm |
|
|
Quote: | but the interrupt handler provided by the CCS. The latency before
interrupt occurs, and the first instruction of the #INT_TIMER1 interrupt
routine will be executed?
|
The entry code of the CCS interrupt handler is 19 instruction cycles long,
on the little test program that I made.
Quote: |
When the timer1 is running, and fire-up the interrupt (due to 0x0000
pass), the timer is still running, or waiting until interrupt will be handled? |
The Timer doesn't stop just because an interrupt occurs. It keeps running.
Quote: | I mean, when I will read the timer1 value with ticker=get_timer1(); it will be zero or a value of some ticks, due to latency.
I tested it, and always is zero. |
It depends on your PIC oscillator frequency and the Timer1 frequency.
A fast PIC with a slow counting timer might give you 0.
If you want a more detailed answer, you need to post a small, complete
test program. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Feb 28, 2014 4:53 am |
|
|
PCM has explained to you the tiny technical details, but for you to get the best help it is helpful when you tell us what your higher level problem is. For example, when reading your questions it seems to me that you want to know how much time has passed from the moment the interrupt was triggered and when the interrupt routine is entered?
Am I right?
And why do you need this timing info?
There are a few well known problems here that we can provide a ready answer to, but without knowing the context we can't give you the best help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri Feb 28, 2014 4:55 am |
|
|
Also, remember the value read 'from' the timer, will depend on the prescaler selected. More data needed.... |
|
|
micro_debugger
Joined: 08 Oct 2009 Posts: 73
|
|
Posted: Fri Feb 28, 2014 5:06 am |
|
|
Dear ckielstra,
You are absolutely right!!!
In my project I'm using an simulated RTC, based on 32768 Hz crystal and processor running with internal clock.
I have an interrupt every 1 second, therefore the code of the interrupt is looking like this
ticker=get_timer1();
set_timer1(0x8000 + ticker);
a very simple handler for the timer1.
However as I'm doing also other interrupt with higher priority (I2C) some times, this timer1 interrupt is delayed
for that reason I'm using the ticker variable, in order to see how far the timer1 goes, before I handled its interrupt
I can not use the perfect code for the software RTC provided on the LIB, because I need to have it every second update.
I have some delays, about 2 seconds over 24 hours, so I'm looking how to make it more precise, crystal are very good, pcb also, capacitors seems to be OK, so I'm looking to have better timing.
Any comments or suggestions, are welcome
If needed I can send more code, no problem.
MY question is quite simple, how to make as much as precise the timer1 based RTC
Thank you in advance |
|
|
micro_debugger
Joined: 08 Oct 2009 Posts: 73
|
|
Posted: Fri Feb 28, 2014 5:34 am |
|
|
Dear Ttelmah,
here it is
Code: |
setup_oscillator(OSC_16MHZ | OSC_INTRC | OSC_PLL_ON);
setup_timer_0(T0_INTERNAL | T0_DIV_256);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_ENABLE_T1OSC);
setup_timer_2(T2_DIV_BY_16, 50, 0);
setup_wdt(WDT_4S); //~4,0 s reset
| Any help or guidelines is welcome !!!!
Warmest Regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri Feb 28, 2014 5:58 am |
|
|
First problem is that the timer only 'ticks' at a very low rate compared to the CPU. A variable number of machine cycles could have passed, but you can't tell, because the timer hasn't incremented yet. I see you have posted your clock details, and 'yes', this is the problem.
So:
On updating the timer, don't do it as you show. Problem is, what if the timer incremented between being read, and the value written back?.
This is why code doing this on the Microchip site, does it by just setting the top bit in the register. If you code as:
Code: |
#byte TIMER1H = getenv("SFR:TMR1H")
#bit TIMER1b16 = TIMER1H.7
TIMER1b16=TRUE;
//This will set the top bit of timer1, in one instruction.
|
Avoids this problem.
Now, if you want to do something close to 'synchronous' to this timer, then wait for the next count. So:
Code: |
#byte TIMER1L = getenv("SFR:TMR1L")
#bit TIMER1b0 = TIMER1L.0
while (TIMER1L.0==0) ;
//This will wait for the first count edge _after_ the interrupt
|
Unless your other code delays the interrupt being serviced by more than 30.5uSec, what happens after this point will be within three instruction times of the same point in the timer timing. This however has no effect on the long term accuracy.
The basic long term accuracy of the will not be affected by the latency, _except_ if the count update does occur as mentioned.
Now, 2 seconds in 24hours, is 23 parts per million. You need to be aware of the limitations of 'watch' crystals. They only give good timing accuracy, if kept at approximately 'body' temperature. Even then, the quoted accuracy for most such crystals is only 20PPM, which is almost exactly what you are seeing....
Have a look at AN1155 on the MicroChip site.
You can get better accuracy, by switching to units that have some form of inbuilt temperature correction. Look at the Maxim DS32kHz module, which gives guaranteed better than 1 minute/year for normal room temperatures.
For real accuracy, you start having to move to temperature controlled crystals, GPS synced timing, Internet synced timing, or receiving MSF transmissions. You are already nearly as good as a standard watch crystal will manage.....
Best Wishes |
|
|
micro_debugger
Joined: 08 Oct 2009 Posts: 73
|
|
Posted: Fri Feb 28, 2014 6:07 am |
|
|
Thank you so much for your advices
Warmest Regards |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|