From Tony Nixon [sales at picnpoke.com] and Scott Dattalo
Tony says:
Heres a simple setup using the FSR. Averages for 8 readings though.CBLOCK Average: 8h tempH tempL ENDC movlw Average ; initialise FSR movwf FSR ... ; ; PLACE A2D RESULTS INTO A ROTATING BUFFER ; movf ADRES,W movwf INDF incf FSR movlw Average + 8h xorwf FSR,W btfss STATUS,Z goto NFSR movlw Average movwf FSR NFSR ... ;Scott Dattalo interjects: ;If you have only 8 samples, and you were willing to align the array on a mod 8 ;boundary, then advancing the pointer could be done easily: incf fsr,w andlw 7 addlw Average movwf fsr ;if you don't wish to align the array, then try this instead: incf fsr,w addlw -Average andlw 7 addlw Average movwf fsr ; ; AVERAGE OUT THE 8 STORED VALUES WHEN A RESULT IS NEEDED ; movlw Average movwf FSR clrf tempH clrf tempL avLoop movf INDF,W ; add up 8 word values addwf tempL btfsc STATUS,C incf tempH incf FSR movlw Average +8h xorwf FSR,W btfss STATUS,Z goto avLoop movlw Average movwf FSR bcf STATUS,C ; div result by 8 rrf tempH rrf tempL bcf STATUS,C rrf tempH rrf tempL bcf STATUS,C rrf tempH rrf tempL ....
And Scott also says:
Again, I think the best way to maintain a running average is by subtracting the oldest value and adding in the newest. Here's something I'll whip out as fast as I can type it - which means there's a good chance for a thinko.; avg_lo:avg_hi - 16bit cumulative sum of last 8 samples ; samples - a circular array that holds the last 8 samples ; assume that samples and avg_lo:avg_hi are initialized to zero ; ; FSR is initialized to the start of samples ; ; W = newest sample AVERAGE: addwf avg_lo,f ;add newest sample to the average skpnc incf avg_hi,f xorwf indf,f ; swap oldest and newest samples xorwf indf,w xorwf indf,f subwf avg_lo,f ;remove the oldest sample from the average skpc decf avg_hi,f incf fsr,w ;advance the sample pointer addlw -sample andlw 7 addlw sample movwf fsr return There - no more looping through all of the data after every sample is acquired. Now, I'm assuming that the division is not needed at every iteration. I tend to put off the difficult stuff as long as possible - often times, the intermediate calculations are more than sufficient. But, if you want, then this is how I'd do it: rrf avg_hi,w movwf temp_hi rrf avg_lo,w movwf temp_lo rrf temp_hi,f rrf temp_lo,f rrf temp_hi,f rrf temp_lo,w and if you wanted rounding: skpnc addlw 1 (You don't need to worry about clearing the carry because the average is guranteed to be less than or equal to 255.)