Got a little project going where I want to set or clear a bit depending on whether an input trigger pulse is above or below 120Hz. I grab the 1.25MHz counter reading every trigger pulse and take the average of the last 16 readings and compare it to a value. The thing is, if I don't use the averaged value it sets or clears as good as dead on 120Hz, no problem, but if I use the averaged value it sets or clears at 119.09Hz. Sure, I lose the the 4 LSBs when I right shift 4 times, but this is an error approaching 1%, way more than those 4 bits would account for. Pretty sure the lost bits are all zeros anyway. I just can't figure out what's happening. This is the relevant portion of the code. And, yeah, it's hardly optimal, I know, but it should work. Any ideas? assembly suggestions only, not C.
********************************************************************************
WAIT_TRIG BRSET TRIG,PORTB,WAIT_TRIG ;inverted trigger from coil
LDHX TCNTH ;get current counter value (1.25MHz)
STA TCNTH ;reset counter
STHX TEMP_CTR_MSB
JSR PUSH_DOWN ;push previous counter readings down one place
LDHX TEMP_CTR_MSB ;latest count
STHX MSB_1 ;put latest on the pile
BCLR TOF,TSC ;just in case
JSR ADD_UP ;add up last 16 timer periods
JSR DIV_16 ;average = MSB_TOT:LSB_TOT
*********************************************
LDHX MSB_TOT ;averaged count
CPHX #10417 ;1800rpm or less, 120Hz, 8.333mS
BHS CLR_BIT ;clear if < 120Hz
BSET 0,PORTA ;set if > 120Hz
JMP WAIT_TRIG
CLR_BIT BCLR 0,PORTA ;
JMP WAIT_TRIG
********************************************************************************
;push last 16 counter readings down one place
PUSH_DOWN LDHX MSB_15
STHX MSB_16
LDHX MSB_14
STHX MSB_15
LDHX MSB_13
STHX MSB_14
LDHX MSB_12
STHX MSB_13
LDHX MSB_11
STHX MSB_12
LDHX MSB_10
STHX MSB_11
LDHX MSB_9
STHX MSB_10
LDHX MSB_8
STHX MSB_9
LDHX MSB_7
STHX MSB_8
LDHX MSB_6
STHX MSB_7
LDHX MSB_5
STHX MSB_6
LDHX MSB_4
STHX MSB_5
LDHX MSB_3
STHX MSB_4
LDHX MSB_2
STHX MSB_3
LDHX MSB_1
STHX MSB_2
RTS
*************************************
;Add up latest 16 counter readings
ADD_UP CLR LSB_TOT
CLR MSB_TOT
CLR EXT_TOT
LDA LSB_TOT
ADD LSB_1
STA LSB_TOT
LDA MSB_TOT
ADC MSB_1
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_2
STA LSB_TOT
LDA MSB_TOT
ADC MSB_2
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_3
STA LSB_TOT
LDA MSB_TOT
ADC MSB_3
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_4
STA LSB_TOT
LDA MSB_TOT
ADC MSB_4
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_5
STA LSB_TOT
LDA MSB_TOT
ADC MSB_5
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_6
STA LSB_TOT
LDA MSB_TOT
ADC MSB_6
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_7
STA LSB_TOT
LDA MSB_TOT
ADC MSB_7
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_8
STA LSB_TOT
LDA MSB_TOT
ADC MSB_8
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_9
STA LSB_TOT
LDA MSB_TOT
ADC MSB_9
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_10
STA LSB_TOT
LDA MSB_TOT
ADC MSB_10
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_11
STA LSB_TOT
LDA MSB_TOT
ADC MSB_11
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_12
STA LSB_TOT
LDA MSB_TOT
ADC MSB_12
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_13
STA LSB_TOT
LDA MSB_TOT
ADC MSB_13
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_14
STA LSB_TOT
LDA MSB_TOT
ADC MSB_14
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_15
STA LSB_TOT
LDA MSB_TOT
ADC MSB_15
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
LDA LSB_TOT
ADD LSB_16
STA LSB_TOT
LDA MSB_TOT
ADC MSB_16
STA MSB_TOT
LDA EXT_TOT
ADC #0
STA EXT_TOT
RTS
*************************************
;divide total of last 16 counter readings by 16
DIV_16 LSR EXT_TOT
ROR MSB_TOT
ROR LSB_TOT
LSR EXT_TOT
ROR MSB_TOT
ROR LSB_TOT
LSR EXT_TOT
ROR MSB_TOT
ROR LSB_TOT
LSR EXT_TOT
ROR MSB_TOT
ROR LSB_TOT
RTS
********************************************************************************
********************************************************************************
ORG $FFFE
FDB START
********************************************************************************