SX Microcontroller Input / Ouput Method

Averaging A2D results

By Nikolai Golovchenko, Tony Nixon [sales at picnpoke.com] and Scott Dattalo

 DEVICE SX28L, OSCHS2, TURBO, STACKX, OPTIONX
 RESET start
 ORG 08ドル ;global bank
rand0 DS 1 ;random generator state
count DS 1 ;general purpose counter
temp	DS 1		;temp needed in Scott's version
tempH DS 1 ;temps needed in Tony's version
tempL DS 1 ;
 ORG 10ドル ;bank 0
av_bank EQU $
samples EQU $ ;alias name for 'average'
average DS 8 ;circular buffer for 8 bytes
av_ptr DS 1 ;circular buffer pointer (0..7)
avg_lo DS 1 ;cumulative average (required in Scott's version)
avg_hi DS 1 ;
 ORG 000ドル ;page 0
;************************************************************************
start
;make w addressable
 mov w, #7ドルF
 mov !OPTION, w
;x--- ---- 0 = register 01h addresses w 
;-x-- ---- 1 = RTCC roll-over interrupt is disabled
;--x- ---- 1 = RTCC increments upon transition on RTCC pin
;---x ---- 1 = RTCC increments on high-to-low transitions
;---- x--- 1 = Prescaler is assigned to WDT, and divide rate on
; RTCC is 1:1
;---- -xxx 111 = Prescaler divider 1:128 (WDT)
; * METHOD 1 *
;enter 8 entries in the buffer and calculate the average
;using method 1
 bank av_bank ;select working bank
 clr rand0 ;init the random generator state
 clr av_ptr ;clear buffer pointer
 mov w, #8
 mov count, w
loop1
 call Rand8 ;generate a random input value in w
 call av_put ;put it into the buffer
 decsz count 
 jmp loop1 ;repeat 8 times
 call av_calc ;calculate average and return in w
	;input data = 35,F6,93,1C,61,F2,1F,F8
 ;result w = 88
; * METHOD 2 *
;enter 8 entries in the buffer and calculate the average
;using method 2
 bank av_bank ;select working bank
 clr rand0 ;init the random generator state
	call av_init2	;init average calculation
 mov w, #8
 mov count, w
 
loop2
 call Rand8 ;generate a random input value in w
 call av_put2 ;put it into the buffer
 decsz count 
 jmp loop2 ;repeat 8 times
 
 call av_calc2 ;calculate average and return in w
 ;result w = 88
 call av_calc3 ;calculate average and round
 ;result w = 89
 jmp $ ;halt
;************************************************************************
Rand8
 clc
 rl rand0 ; w = (32 * rand) % 256
 mov w, <>rand0
 and w, #$E0
 rr rand0 ; restore rand
 add w, rand0 ; rand' = (w + 3 * rand) % 256=
 add w, rand0 ; = (32 * rand + 3 * rand) % 256
 add rand0, w
 not rand0 ; rand'' = -rand'-1
 mov w, #36ドル ; rand = (53 - 32 * rand - 3 * rand) % 256
 add rand0, w
 mov w, rand0 ; copy result to w
 retp ; Done
;************************************************************************
;
; PLACE A2D RESULTS (w) INTO A ROTATING BUFFER
; (by Tony Nixon and Scott Dattalo)
;
;************************************************************************
av_put
 mov temp, w ;save w in temp (in global bank)
 mov w, #average ;initialise FSR
 mov FSR, w
 mov w, av_ptr
 add FSR, w
 mov w, temp ;get input
 mov IND, w ;save in buffer
 ;update pointer
 mov w, ++av_ptr 
 and w, #07ドル ;implement wrap-around
 mov av_ptr, w
 retp
;************************************************************************
;
; AVERAGE OUT THE 8 STORED VALUES WHEN A RESULT IS NEEDED (return in w)
;
;************************************************************************
av_calc
 mov w, #average ;initialise FSR
 mov FSR, w
 clr tempH
 clr tempL
;add up 8 word values
av_loop
 mov w, IND ;load pointed value
 add tempL, w ;add to tempH:tempL
 snc
 inc tempH
 inc FSR
 mov w, #average + 8
 xor w, FSR
 sz
 jmp av_loop
;div result by 8
 rr tempH
 rr tempL
 rr tempH
 rr tempL
 rr tempH
 mov w, >>tempL ;last shift result place in w
 retp ;return with result in w
;************************************************************************
; Scott Dattalo says:
; Again, I think the best way to maintain a running average is by
; subtracting the oldest value and adding in the newest.
;
; 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
;************************************************************************
av_put2
	mov 	temp, w		;save input
 mov w, #average ;initialise FSR
 mov FSR, w
 mov w, av_ptr
 add FSR, w
 
	mov	w, temp		;read input 
 add avg_lo, w ;add newest sample to the average
 snc
 inc avg_hi
 xor IND, w ;swap oldest and newest samples
 xor w, IND
 xor IND, w
 sub avg_lo, w ;remove the oldest sample from the average
 sc
 dec avg_hi
 mov w, ++av_ptr ;advance the sample pointer
 and w, #07ドル
 mov av_ptr, w
 retp
;************************************************************************
;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:
;************************************************************************
av_calc2
 bank av_bank ;select working bank
 mov w, >>avg_hi
 mov temp, w
 mov w, >>avg_lo
 rr temp
 rr WREG
 rr temp
 rr WREG
 retp 
;and if you wanted rounding:
av_calc3
 bank av_bank ;select working bank
 mov w, >>avg_hi
 mov temp, w
 mov w, >>avg_lo
 rr temp
 rr WREG
 rr temp
 rr WREG
 snc
 inc WREG
 retp
;************************************************************************
; Initialize buffer
;************************************************************************
av_init2
 mov w, #average	;init bank and FSR pointer
 mov FSR, w
 clr av_ptr ;clear buffer pointer
 clr avg_hi ;clear running average
 clr avg_lo ;
 mov w, #8
 mov temp, w
av_init2_loop
 clr IND		;clear the buffer
 inc FSR
 decsz temp
 jmp av_init2_loop
 retp
;************************************************************************
	ORG 200ドル	;page 1

file: /Techref/scenix/lib/math/dsp/avga2d_sx.htm, 8KB, , updated: 2004年6月10日 14:40, local time: 2025年9月3日 11:23,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://techref.massmind.org/techref/scenix/lib/math/dsp/avga2d_sx.htm"> PIC Microcontroller Input / Ouput Method Averaging A2D results</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here:
if you want a response, please enter your email address:
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

Welcome to massmind.org!

Welcome to techref.massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /