Jinx wrote: > Say its period is 0xFF00 (16.320ms), and the frequency being measured > is ~59.4Hz, ie a period of 16.832ms, or 0x10700 * 250ns. So that's (1 > rollover + 0x0700) of TMR1 between rising edges > >> This code grabs the timer 0 [1 ? typo ?] Oops, yes. Everything we are talking about is with timer 1. >> high byte, finds the delta >> from the last time it did that, then adds that delta into a software >> accumulator >> >> The procedure above makes the software accumulator up to date with >> the latest high byte of timer 1 > > Assuming the previous sample left 0x00 in the s/w acc, which was > loaded into TMR1H (as per paragraph below) > > This sample of TMR1H is 0xFF > > delta = 0x01 -> into s/w acc (*** did you mean absolute delta ?) > > Now, next edge comes along when TMR1H is 0x07 (rolled through 00). > So total increments since last edge is 0x010700 I think so. This is a lot more complicated to explain than to do, so here is a example. This example will extend the capture timer to 24 bits, so the sofware accumulator will be 16 bits wide. All numbers are in HEX: Starting out Timer 1: 0000 old timer1l: 00 old timer1h: 00 SW acc: 0000 then 1234h counts in the accumulator update routine is run: Timer 1: 1234 old timer1l: 00 old timer1h: 12 SW acc: 0012 The new timer1h was subtracted from the old timer1h: 12 - 00 = 12. This increment is added into the software accumulator: 0000 + 12 = 0012. The timer1h value found this time is saved as the old value for next time. Now let's say the timer 1 update routine was run again, this time at 8765h counts from the start: Timer 1: 8765 old timer1l: 00 old timer1h: 87 SW acc: 0087 The new timer1h is 87, and the old is 12. 87 - 12 = 75. This increment is added to the software accumulator: 0012 + 75 = 0087. The new timer1h (87) is then saved as the old timer1h for next time. Note that since so far there has been less than one total timer 1 wrap time, the result is the same whether the first iteration of the update code was run or not. It needs to get run at least a little more often than every 10000h timer 1 counts else a wrap will get lost. It's a good idea to run it more often than that to allow for slop. Every 10mS, for example, would be fine. So far this hasnt done much useful since the timer didn't wrap. So now let's say the update routine got run at 14567 ticks from the start. This is where it earns it's keep: Timer 1: 4567 old timer1l: 00 old timer1h: 45 SW acc: 0145 45 - 87 = BE (remember, this is unsigned math with the carry tossed). The software accumulator is updated: 0087 + BE = 0145. Then the old timer1h is updated to 45. Since we started at 0, the software accumulator directly shows the high 2 bytes of the 3 byte total elapsed ticks. If the original timer 1 value wasn't 0, this wouldn't be the case. Now there is a CCP capture event at 18592 total ticks from the start. The state on entry to the capture handler is: Timer1 capture: 8592 old timer1l: 00 old timer1h: 45 SW acc: 0145 The period since the last capture is assembled in pieces. The *signed* subtract of captured timer1l minus the old timer1l is 92 - 00 = 000092. The captured high byte minus the old high byte is 85 - 45 = 40. These plus the SW accumulator are added together to yield the complete 24 bit period since the last capture: 000092 + 40 + 0145 -------- 018592 <-- Don't you love it when it all works out! Then the state is reset to start accumulating the time delta to the next capture: old timer1l: 92 old timer1h: 85 SW acc: 0000 The captured timer 1 bytes are saved as the old bytes for the next time, and the software accumulator is cleared. Then you do it all again. ******************************************************************** Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products (978) 742-9014. Gold level PIC consultants since 2000. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist