Vasile Surducan wrote: > > Roman, is not true, I saw it and is already copy in my timer folder, > but what do you say about showing us the whole code who done this ... > or maybe just initialising tmr0 with xtal value in 24 bits. > Vasile > Hi Vasile, sorry I don't really understand what you are asking! I initialsed TMR0 with no prescaler, so it clocks at 1:1 with the clock speed (fosc/4). With 16MHz crystal gives 4MHz clock speed. Then TMR0 generates an int every 256 instructions. This simply subtracts 256 "ticks" from the main 24bit variable. When the variable gets below 0 we just add another 4,000,000 ticks (1 second) to it and it keeps going. My system of testing <256 is better than <0 because it speeds the math. :o) -Roman > > > Roman Black wrote: > > > > > > Hi Guys, I've implemented a version of Bob's > > > zero-error one second timer. I added two changes > > > and the whole thing fits in just a handful of > > > instructions. It will give perfect results with > > > any crystal speed (that divides evenly by 4). > > > > > > Basic theory: (example 16MHz crystal, 4MHz instruction) > > > * put one second value in 24bit var (4,000,000 ticks) > > > * the TIMER0 int is every 256 instructions > > > * every int we subtract 256 from value > > > * when value gets <0 we generate the one second event, > > > and add another 4,000,000 ticks to var > > > > > > It has zero cumulative error and zero short-term > > > average error. There will be a max error per second > > > of 256 instructions (64uS at 16MHz crystal). > > > > > > The two changes I made from Bob's idea are; > > > * subtracting a set value of 256 (1x mid-byte) > > > * adding an extra 256 ticks at the start. > > > > > > The first change means that instead of doing a > > > proper 24bit subtract every int, you just need > > > to dec the mid byte of the var, (and do carry test > > > and dec msb if needed). Very fast and small code. > > > > > > The second change means the var never goes below > > > zero, instead our <0 test simply becomes a <256 > > > test.. This is very quick, we just test that > > > msb=0 AND mid=0. > > > > > > This condition means that now to add the 4,000,000 > > > ticks to the variable again we are guaranteed that > > > msb and mid bytes are 0, so we can simply load > > > the two values from literals straight into the > > > msb and mid bytes. We no longer need a proper > > > 24bit add! We must do an add on the lsb byte, > > > but this is only one byte add and one carry test. > > > If carry, we can just inc the mid byte, as it's > > > value is guaranteed. > > > > > > The whole thing is very small and quick as there > > > are no real 24bit add/subtracts needed. :o) > > > > > > ----------------------------------------------------- > > > My code is specific to my app but here is the > > > psuedo code: > > > > > > initialising: (assuming 16MHz crystal, 4MHz clock) > > > set TIMER0 to generate int every 256 clocks > > > put 4,000,000 in 24 bit var > > > add another 256 to var (inc mid byte) > > > > > > int handler: > > > save off status/w > > > > > > dec mid byte (subtract 256 from total value) > > > check carry and dec msb if needed > > > (that was our entire 24bit subtract!) > > > > > > now test for msb=0 AND mid=0 (detect <256) > > > if not, goto int exit (very quick int in most cases!) > > > > > > (here we have detected 1 sec event) > > > generate 1 second event > > > > > > (now we do the add 4,000,000 again) > > > load msb value into msb (msb was guaranteed 0) > > > load mid value into mid (mid was guaranteed 0) > > > add lsb value to whatever is left in lsb > > > if carry, inc mid > > > (that's our whole 24bit add done!) > > > > > > int exit: > > > restore status/w > > > ----------------------------------------------------- > > > > > > There are a lot of good things about Bob's system. > > > Any crystal can be used, if it gives x instructions/sec. > > > > > > It will also work great for other timing periods, > > > like my datalogger that needs an event at 2Hz, 4Hz, 8Hz, > > > selectable. I just change the total value of ticks > > > added to the 24bit var. This can be done on the fly > > > with no problems. > > > > > > Quirky thing? With my 16MHz crystal, the clock is 4MHz. > > > So a one second period is 4,000,000 ticks. This just > > > happens to be 3D 09 00 in 24bit hex. Notice the lsb > > > is zero. This means that there will be NO ERROR on a > > > one second period. No jitter, as the only jitter with > > > this system is the lsb averaging. That was good luck, > > > I found it by accident! :o) > > > > > > The jitter is not a big problem as with most crystals > > > it will be a short term average. With a 8MHz crystal, > > > (2,000,000 ticks) one second will be 128 ticks late, > > > the next second will be perfect. A 2-cycle average > > > with zero average error. A 4MHz crystal gives 4-cycle > > > average with every 4th second perfect. > > > > > > Hope all this makes sense. Thanks Bob for the cool > > > idea!:o) > > > -Roman > > > > > > PS. If you just need to update a real time clock each > > > second and don't want to spend time in an interrupt > > > every 256 instructions, you could change the TIMER0 > > > prescaler to 256. This gives an int every 256x256 > > > instructions. Then just subtract one msb every int, > > > using the same principle. Just as quick. Remember > > > to add an extra 256x256 ticks at the start instead > > > of just an extra 256 ticks. Error per second (jitter) > > > is larger, but cumulative and average errors are still > > > zero. Max jitter per second becomes 16ms. Averaging > > > will take 24 seconds. An almost perfect real-time clock > > > with extremely low processing time requirement. > > > -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.