Time run to slow

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
My time on 16F188777 runs to slow in this setup

Have a xtal 32,768 kHz on pin RC0 - RC1. with 2 15pf capasitor

have now been running for 11 hours and on this time the time has lost 37 min = 2220 seconds.
Around 6% lost,

So i think something must be wrong in setup ?

Here is a bit of code to it.

Code:
static void interrupt isr(void)   // Here is interrupt function - the name is unimportant.
{
   
if(TMR1IF)             // Was this a timer overflow?
    {
          TMR1IF=0;        // Clear interrupt flag, ready for next
        TMR1L=0x00;
         TMR1H=0x80;     // If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
        
         sec=1;             // adds a sec.  to main loop
      
    } 
}
  void setup(void)
{    
TRISA0=1; //set all A port in
TRISA1=1;
TRISA2=1;
TRISA3=1;
TRISA4=1;
TRISA5=1;
TRISA6=1;
TRISA7=1;

TRISB0=0; // port b0 = out
TRISB3=0; // PORT B3 = out
TRISB5=1;
TRISB6=1;
TRISB7=1;

TRISC0=1; // ALL C = IN
TRISC1=1;
TRISC2=1;
TRISC3=1;
TRISC4=1;
TRISC5=1;
TRISC6=1;
TRISC7=1;

TRISD0=0; // ALL D = out
TRISD1=0;
TRISD2=0;
TRISD3=0;
TRISD4=0;
TRISD5=0;
TRISD6=0;
TRISD7=0;

TRISE0=0; // E0 = out
TRISE1=1;
TRISE2=1;

ANSELA=0b00000000; // set alle digital.
ANSELB=0b00000000;
ANSELC=0b00000000;
ANSELD=0b00000000;
ANSELE=0b0000;

//timer 1 setup
T1CS0=0; // 0110 = SOCS
T1CS1=1;
T1CS2=1;
T1CS3=0;
T1CKPS0=0; // no prescale
T1CKPS1=0;
nT1SYNC=1; // no sync
   
}
 

ericgibbs

Joined Jan 29, 2010
18,873
hi FM,
I do not use 'C' language.
I see that you have set TMR1 to give a 1 second interrupt.??
I would suggest that you post the interrupt subroutine code, let us see the execution time.
E
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
when i left out TMR1L=0x00 then time gets at half speed,
then i read that i have enabled 16 bit read/write to timer1, now i have changed to 8 bit, and only write to high part of timer. 0x80
Will let it run for some hours again to see if more accurate
 

ericgibbs

Joined Jan 29, 2010
18,873
hi FM,
I see it, one day I will learn C..;)
You must allow for the short code execution time within the ISR, as this time will be added to the 0x8000 TMR1 time.
Have you checked the accuracy of the 32.768kHz xtal , using a frequency counter.?
E
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
If running PIC at 4 MHz FOSC/4 1 MHz, give me a 1 us pr instruction = max 2 instruction to new value is written,
500.000 seconds to give me a delay on 1 sec, dont think that is the case
Maybe the xtal is unprecise,
 

ericgibbs

Joined Jan 29, 2010
18,873
hi,
You could try using a lower value caps, say 10pF in place of the 15pF.
In other timing project I have used a 15pF trimmer in place of one of the caps, so that I can trim the frequency.
 

AlbertHall

Joined Jun 4, 2014
12,347
In the interrupt routine, do not change TMR1H or TMR1L.
In the setup, use a 1:2 prescaler so the overflow will happen every second.
The timing will then be as accurate as the crystal.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
In the interrupt routine, do not change TMR1H or TMR1L.
In the setup, use a 1:2 prescaler so the overflow will happen every second.
The timing will then be as accurate as the crystal.
If do so, will it not just roll over every 4 seconds, ?
if not changed in values, give a 2 sec interrupt, bit if prescale it , will add 2 more,
Prescale divide the numbers of input from xtal, so if 32768 pr sec, and prescale 1:2 give 2 sec before 32768 pulse. and if futhermore the timer goes from 32768 to 65536, will end up with 4 seconds ??
 

jpanhalt

Joined Jan 18, 2008
11,087
As others have suggested, let TMR1 run continuously. That way, the "overhead" time of dealing with the ticks does not affect the elapsed time.

Use the CCP module in compare mode and preset the CCPxH/L register pair to count 32768 ticks for each second. Since that register pair is 16-bit, you will need to reset the seed value in CCPxH/L after each 1-second tick. I would just xor with 0x8000 (actually 0x80 with CCPxH) to flip the bit. Each time a match is obtained, you get a tick on CCPxIF.

For starters, though, I would just live with the 2-second ticks to be sure my crystal was right. I suspect you do not have an actual datasheet for that crystal, so those capacitors may be making it run a little slow.
 

nerdegutta

Joined Dec 15, 2009
2,684
Hi,

Memory lane back to 2012:

C:
static void interrupt
isr(void)   // Here is interrupt function - the name is
    // unimportant.
{
if(TMR1IF)
  {// Was this a timer overflow?
      TMR1IF=0;//Clear interrupt flag, ready for next
   TMR1H=0x80;
        //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
     timer_tick=1;
blink=!blink;
           LED=blink;
        
  sec++;
  if (sec==60)
{
minut_tick=1;
sec=0;
}
  }//we are done here
}
This is one of your interrupt routines. Did this also drift away?

Post is here.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
Hi,

Memory lane back to 2012:

C:
static void interrupt
isr(void)   // Here is interrupt function - the name is
    // unimportant.
{
if(TMR1IF)
  {// Was this a timer overflow?
      TMR1IF=0;//Clear interrupt flag, ready for next
   TMR1H=0x80;
        //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
     timer_tick=1;
blink=!blink;
           LED=blink;
       
  sec++;
  if (sec==60)
{
minut_tick=1;
sec=0;
}
  }//we are done here
}
This is one of your interrupt routines. Did this also drift away?

Post is here.
hi, yes it driftet away but only a minut a week.give or take.

I will try to run full scale, 65536 and get the "2 sec" tick instead , this is the simplest way.
 

ebp

Joined Feb 8, 2018
2,332
15 pF capacitors, for 7.5 pF loading of the crystal, ignoring the pin & stray capacitance is too high for some 32 kHz crystals (and low for most higher frequency crystals). Look carefully at the data sheets for the processor and the crystal.
 

ebp

Joined Feb 8, 2018
2,332
OFF TOPIC!

I see it, one day I will learn C

C isn't too bad, but there are many weirdities that are concessions made to efficient compilation. That really has been unnecessary for a great many years.

One of the most frequent sources of problems for learners that know other languages is the distinction between assignment operators and comparison operators

x = 2
if (x = 3) ... returns true because the expression in paren's assigns 3 to x
if (3 = x) ... should generate an error message at compile time because assignment is unpossible
if (x == 3) ... compares x & 3 as does
if (3 == x)

Some of the PIC C composters I've used are pretty awful. I've spent a lot of time looking at the assembly listings from the compiler to figure out what is actually going on. (for that matter, 8 bit PICs are pretty awful, though I've used many)
 

AlbertHall

Joined Jun 4, 2014
12,347
OFF TOPIC!

I see it, one day I will learn C

C isn't too bad, but there are many weirdities that are concessions made to efficient compilation. That really has been unnecessary for a great many years.

One of the most frequent sources of problems for learners that know other languages is the distinction between assignment operators and comparison operators

x = 2
if (x = 3) ... returns true because the expression in paren's assigns 3 to x
if (3 = x) ... should generate an error message at compile time because assignment is unpossible
if (x == 3) ... compares x & 3 as does
if (3 == x)

Some of the PIC C composters I've used are pretty awful. I've spent a lot of time looking at the assembly listings from the compiler to figure out what is actually going on. (for that matter, 8 bit PICs are pretty awful, though I've used many)
The XC8 PIC compiler deliberately adds pointless instructions so it can boast how wonderful the paid for optimisations are.
http://www.t4f.org/articles/optimization-of-microchip-pic-xc8-compiler-in-free-and-pro-mode/
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
702
have now changed it to run to 65536, interrupt routine is here
Code:
static void interrupt isr(void)   // Here is interrupt function - the name is unimportant.
{
   
if(TMR1IF)             // Was this a timer overflow?
    {
          TMR1IF=0;        // Clear interrupt flag, ready for next
           sec=1;             // adds a sec.  to main loop
      
    } 
}
And changed the main , to deal with only a 2 sec tick.
Time/clock has been running for last 30 hours, and still accurate +-1 sec.

'
 

jpanhalt

Joined Jan 18, 2008
11,087
Great news and thanks for the follow-up. Now if you want a 1-second tick or just the experience, try using the CCP module in compare mode.
John
 
Top