Xtal unstable

JohnInTX

Joined Jun 26, 2012
4,787
With 2MHz XTAL your internal Tcyc time (the input to TMR2) is 2uS. (Fosc/4)

Consulting the 'Lil Professor:
1 Sec / 2uSec per Tcyc = 500,000 Tcyc per second i.e. you have to count 500K Tcyc then interrupt. This requires 19 bits of counting. You don't have 19 bits worth of timer, prescaler and postscaler so you cannot directly get 1sec from TMR2. You are one bit short. Consider:
19bits needed - 6bit prescaler(/64) - 4bit postscaler (/16) -8bits(PR2) leaves one bit. That is consistent with my calculations that if you max out everything (pre=64,post=16,PR2=255) you get a period of .52224sec. If you had that last bit, you could exceed 1 sec.

To get one second, you'll have set TMR2 up to interrupt on some integer factor of 1 sec (500ms, 100ms etc) then count those interrupts to accumulate one second. Keep in mind that using the /64 prescaler will make it difficult to get an exact multiple of one second (factor 500,000 and group terms into what you can achieve with the pre/post/PR2 settings and you'll see). Alternately, run the PIC at a slower speed.

All of this assumes your oscillator is working as it should.

FWIW:
At 2MHz Fosc, Pre=16, Post=10, PR2=125 gives interrupts at .04sec intervals. Count 25 of these and you get 1 sec.

Good luck.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
TMR1 can also take FOSC/4
If preset timer to 62500 ( F424 )
Prescale 1:8
500000 / 8 = 62500
That will give 1 sec interrupt ?
Not exactly.
TMR1 counts up and interrupts on rollover FFFF->0000. This means you have to set it to the complement of what you want: i.e. 2^16-desired count = 65536-62500=3036=0BDCh.
Note that with this PIC, if you want a recurring 1sec interrupt, you have to manually reload the timer every time it interrupts so unless you know exactly how many clock cycles it takes to reload TMR1H/L with 0Bh/DCh and restart the timer, you will accumulate errors. If you only need to load the timer, start it on some event then wait for interrupt, its OK. But, that's why TMR2 is your best bet, it does not need reloading on each interrupt.

Some PICs with capture/compare peripherals allow you to set TMR1 to compare with your count in a compare register, interrupt the PIC AND reset TMR1 automatically. TMR1 can then be a 16bit period register. Not all PICs have CCP and not all that do have the auto-reset feature, though.

What are you wanting to do with your 1sec time?
EDIT: FWIW, The_RB, a former member here, has several examples of how to do precision timing with free-running counters.
 
Last edited:

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Have this now

T2CKPS0=1;//Prescale 64
T2CKPS1=1;
T2OUTPS0=1; // postscale 10
T2OUTPS1=0;
T2OUTPS2=0;
T2OUTPS3=1;
PR2=0x7D; // 125

And the interrupt.
static void interrupt isr(void) // Here is interrupt function - the name is unimportant.
{
if(TMR2IF)
{
TMR2IF=0;
xpulse++;
if (xpulse==25)
{ xpulse=0;
sec=1;
RA2=!RA2;
}
}
}

Works fine but it run a Little to FAST
On 100 minutes it gain 10 seconds,
Why ?
 

JohnInTX

Joined Jun 26, 2012
4,787
I will try to Work with the internal, and set speed at 2mhz,
Works fine but it run a Little to FAST
On 100 minutes it gain 10 seconds,
Why ?
The freq. tolerance of the internal oscillator is +/-1%. Your time is within 0.2% so its running about what you can expect from INTOSC and better than spec. The 16F1509 does not have an OSCCAL register that allows the firmware to trim the oscillator speed so if you need better timing than that, I would consider an external crystal (not resonator) or better yet, an external oscillator module.

It comes down to how tight you need your timing and over what long term duration.

Have fun.
 
Last edited:
Top