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 13:40, local time: 2024/11/15 11:45,
3.142.194.27:LOG IN
|
©2024 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://linistepper.com/techref/scenix/lib/math/dsp/avga2d_sx.htm"> PIC Microcontroller Input / Ouput Method Averaging A2D results</A> |
Did you find what you needed? |