"David E. Olson" wrote: > > For those that replied to my 16-bit arithmetic. It all works now. Went the > route of shifting and ORing. > > Next issue: > > I'm working on a speedometer where I'm using CCP1 and firing an interrupt on > every falling edge so I can count the pulse. Then I have TMR1 rollover with > a 1:8 prescale. In that interrupt, I'm storing my pulse count, clearing the > pulse counter and moving on. > > This all works great but, every so often, TMR1 does not rollover properly. > Sometimes it skips 1 or 2 cycles so my pulse count suddenly doubles or > triples. Rather not indicate a sudden acceleration when there isn't one. > > Any way to stop this? I can do some threshold logic to make sure it doesn't > count when I'm, let's say, 50% on either side of the previous value but, it > seems like a hack. > > I'd like to stick with the pulse counting model since I need to also get an > odometer out of this. The pulse count route seems to be an easier way to get > the odometer and the speed at the same time. > > Think I should be using period measurement instead? At least I'd toss out > the TMR interrupt and just have to deal with CCP... > > TIA > > -DO I did a similar thing like this. Capture on falling edge at 1:8 TMR1 prescale. ; Interrupt routine may capture many speed values, ; but the capture registers are only read every 500mS ; for a display update. irqvec movwf W_Hold ; store w reg - ram page 0, 1 or whatever swapf status,w bcf status,rp0 ; ram page 0 movwf S_Hold ; store status in RP 0 clrf status clrf tmr1L ; reset tmr1 clrf tmr1H bcf pir1,ccp1if ; (2) clear capture interrupt bsf flag1,Dspeed ; (2) flag data available swapf S_Hold,w ; restore Status movwf status swapf W_Hold ; W reg restored from ram page swapf W_Hold,w retfie When main loop is ready to update the displays, it checks if DSpeed is set, and if so calls SpeedCal. ; It was determined during a calibration routine ; that at 64KPH, the capture value is 30Dh ; ; multiplied by 64, the value is C340h, which is the calibration constant. ; Any speed value will do, but 64 is easy to multiply with. ; ; EXAMPLE ; ; While running, a value of 26Dh is captured. ; ; C340 / 26D = 50h -> 80KPH ; ; KPH result is in nratorL after division routine ; Division is standard Microchip 16 bit / 16 bit ; SpeedCal clrf intcon ; disable interrupts clrf intcon movf ccpr1L,w ; get capture data movwf denomL movf ccpr1H,w movwf denomH movf BaseL,w ; calib H movwf nratorL movf BaseH,w ; calib L movwf nratorH call divizn ; do what ever with speed data ; re-enable interrupts bcf pir1,ccp1if ; (2) clear capture interrupt movlw b'11000000' ; re-enable interrupt movwf intcon ; gie and peie = 1 return -- Best regards Tony http://www.picnpoke.com mailto:sales@picnpoke.com