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, #$7F
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/10/26 13:47,
216.73.216.188,10-3-157-36: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? <A HREF="http://massmind.ecomorder.com/techref/scenix/lib/math/dsp/avga2d_sx.htm"> PIC Microcontroller Input / Ouput Method Averaging A2D results</A> |
| Did you find what you needed? |
Welcome to ecomorder.com! |
Welcome to massmind.ecomorder.com! |
.