Heavy coding, 48 bits calcuations. I would not do this in the
interrupt procedure...

Looking at the code, I don't see how it works. You could test this
with an additional counter in the 38.14 ms isr, that is just
incremented and printed as a reference each second, together with
remainder_count, count1 and second_count. Let it run for a minute,
print the outcome on a sheet of paper (or put in in excel) and check
if it is exactly what you think it is. (my guess now is your clock is
about .4% off).

And at some more distance: you have a binary problem at hand and try
to solve it in a decimal way. This is quite inefficient from the
processor perspective.

0.14697265625 is 301 / 2048, which means you have to add 301 ms to the
clock every 2048 msecs. So a simple 11 bit counter does the job.

This is more smooth then your one-second jumps you have now, but you
can also split 301/2048 in 256 / 2048 + 45 / 2048 and limit the
'jumps' to 45ms - below the threshold of someone looking at your alarm
clock...
So: add a ms every 256/2048 = 1/8 step and correct for 45 ms every
2048. This gives you a pretty smooth correction.
And so on, 45 can be split in up to 4 parts.


If you take 301/2048 as a basis, you are 100% accurate (in the sense
that the software does not add any deviation) with little processing.

Joep


2010/4/8 vasile surducan <[email protected]>:
> Hi Matt,
> I will test this. If I understood right, you are defining 1 second with a
> resolution of 10pS, meaning a computing accuracy of 10ppt (part per
> trilion: http://en.wikipedia.org/wiki/Parts-per_notation), but still let the
> sentence "This program assumes a 20 MHz resonator or crystal" unchanged, and
> use 1S for test. How do you expect this can be tested?
>  Assuming the OCXO is around 1ppb,
> (http://www.bliley.com/ocxo/ocxo.htm )your computing is still too accurate
> with an order of 10exp-3.
> Vasile
> On Thu, Apr 8, 2010 at 7:02 AM, <[email protected]> wrote:
>>
>> Revision: 1895
>> Author: [email protected]
>> Date: Wed Apr  7 21:00:56 2010
>> Log: sample for timer
>> http://code.google.com/p/jallib/source/detail?r=1895
>>
>> Added:
>>  /trunk/sample/18f452_timer3_rtc.jal
>>
>> =======================================
>> --- /dev/null
>> +++ /trunk/sample/18f452_timer3_rtc.jal Wed Apr  7 21:00:56 2010
>> @@ -0,0 +1,144 @@
>> +-- Title: second counter using timer3
>> +-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all
>> rights reserved.
>> +-- Adapted-by:
>> +-- Compiler: >=2.4m
>> +--
>> +-- This file is part of jallib (http://jallib.googlecode.com)
>> +-- Released under the BSD license
>> (http://www.opensource.org/licenses/bsd-license.php)
>> +--
>> +-- Description: counts seconds with timer3
>> +--
>> +-- Sources:
>> +--
>> +-- notes:
>> +--
>> +
>> +-- include chip
>> +include 18F452                   -- target picmicro
>> +
>> +-- This program assumes a 20 MHz resonator or crystal
>> +-- is connected to pins OSC1 and OSC2.
>> +pragma target clock 20_000_000     -- oscillator frequency
>> +-- configuration memory settings (fuses)
>> +pragma target OSC  HS              -- HS crystal or resonator
>> +pragma target WDT  disabled        -- no watchdog
>> +pragma target LVP  disabled        -- no Low Voltage Programming
>> +
>> +-- set all IO as digital
>> +enable_digital_io()
>> +
>> +-- led def
>> +alias led             is pin_a1
>> +alias led_direction   is pin_a1_direction
>> +--
>> +led_direction = output
>> +
>> +-- setup uart for communication
>> +const serial_hw_baudrate  = 115200  -- set the baudrate
>> +include serial_hardware
>> +serial_hw_init()
>> +
>> +serial_hw_data = 0xAA
>> +serial_hw_data = 0xAA
>> +serial_hw_data = 0xAA
>> +serial_hw_data = 0xAA
>> +
>> +include print
>> +
>> +-- init pic interrupt settings
>> +intcon_gie  = on    ; enables all unmasked interrupts
>> +intcon_peie = on    ; enables all unmasked peripheral interrupts
>> +
>> +-- Set this to desired interval. timer3 will count up.
>> +-- Interupt will occur when timer_interval rolls
>> +-- over from 65535 to 0
>> +var word timer_interval = 0
>> +
>> +-- timer3 setup
>> +tmr3 = timer_interval  -- timer interval
>> +t3con_tmr3cs = 0       -- use internal clock
>> +pie2_tmr3ie  = 1       -- enable the timer3 interrupt bit
>> +t3con_tmr3on = 1       -- 1 = enables timer 3
>> +pir2_tmr3if  = off     -- clear overflow to start timer
>> +
>> +-- set timer3 clock prescaler
>> +t3con_t3ckps = 1 -- set prscal of 1:2
>> +
>> +-- define a rollover of 1 second
>> +-- holds 1 second: 1.00000000000 or 0x174876E800
>> +var byte*6 one_sec
>> +var byte one_sec_array[6] at one_sec
>> +one_sec_array[5] = 0x00
>> +one_sec_array[4] = 0x17
>> +one_sec_array[3] = 0x48
>> +one_sec_array[2] = 0x76
>> +one_sec_array[1] = 0xE8
>> +one_sec_array[0] = 0x00
>> +
>> +-- counter will roll over 38.14697265625 times in one second for 20mhz
>> clock
>> +-- (1sec / ( (timer freq    ) * clock increments ) / prescaller 1:2  =
>> interrupts per sec
>> +-- (1    / ( (1/20_000_000*4) * 65536            ) / 2               =
>> 38.14697265625
>> +-- holds 0.14697265625 or 36C0679D9 (the remainder)
>> +var byte*6 num_add
>> +var byte num_add_array[6] at num_add
>> +num_add_array[5] = 0x00
>> +num_add_array[4] = 0x03
>> +num_add_array[3] = 0x6c
>> +num_add_array[2] = 0x06
>> +num_add_array[1] = 0x79
>> +num_add_array[0] = 0xD9
>> +
>> +-- counts the remainder up to one second
>> +-- after count is > 1 second, we will minus 1 second within interrupt.
>> +var byte*6 remainder_count = 0
>> +var byte remainder_count_array[6] at remainder_count
>> +
>> +-- seconds counter, allow it to roll over to 0
>> +var byte second_count = 255
>> +-----------
>> +
>> +var byte count1 = 0 -- counts up to 38 (interupt every 38.14697265625
>> sec)
>> +procedure timer_isr() is
>> +   pragma interrupt          -- interupt procedure
>> +
>> +   if !PIR2_TMR3IF then      -- check if this is a timer3 interupt
>> +      return                 -- exit interupt if it is not
>> +   end if
>> +
>> +   PIR2_TMR3IF = off         -- clear timer overflow
>> +
>> +   count1 = count1 + 1       -- count the number of times an interrupt
>> occurs
>> +   if count1 == 38 then      -- if timer is at 1 sec
>> +
>> +      -- if remainder_count is > 1 sec
>> +      if remainder_count > one_sec then
>> +
>> +         -- remove one second from remainder_count
>> +         remainder_count = remainder_count - one_sec
>> +
>> +         -- remove one second from actual timing
>> +         count1 = count1 + 1
>> +      else
>> +         -- add 0.14697265625 (the remainder) to remainder_count
>> +         remainder_count = remainder_count + num_add
>> +      end if
>> +
>> +      second_count = second_count + 1 -- increment the seconds
>> +      if second_count == 60 then      -- reset seconds to 0 each min
>> +         second_count = 0
>> +      end if
>> +
>> +      -- send seconds to serial port
>> +      print_byte_dec (serial_hw_data,second_count)
>> +      serial_hw_data = 0x0D
>> +      serial_hw_data = 0x0A
>> +
>> +      led = !led -- switch led on/off each second
>> +      count1 = 0
>> +   end if
>> +end procedure
>> +
>> +-- main program here
>> +forever loop
>> +end loop
>> +
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jallib" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/jallib?hl=en.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "jallib" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/jallib?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jallib?hl=en.

Reply via email to