В помощь определяющим апогей.
Блок усреднения данных высотомера, работающего по принципу, описанному Serge77, по скользящему среднему на 2,4,8,16,32,64,128 точек и хранение их за последние 5 секунд.
;--------------------------регистры
;
; $060-$15F - кольцевой буфер (рабочий) для вычисления усредненных данных на
; (2^N) N=1...7 значений (A)
; $160-$28C - кольцевой буфер последних 150 значений (300 байт)
; сглаженных данных в SRAM (Б)
;
; r0 - N
; r1 - счетчик начала отсчета скользяшего среднего
; r2 - текущее смещение в буфере (A) (Low)
; r3 - рабочий
; r4 - рабочий
; r5 - рабочий
; r6 - рабочий
; r7 - текущее смещение в буфере Б (High)
; r8 - текущее смещение в буфере Б (Low)
; r9 -
; r10 -
; r11 -
; r12 -
; r13 -
; r14 -
; r15 -
; r16 -
; r17 - рабочий
; r18 -
; r19 -
; r20 - Сумма ADC (Low)
; r21 - Сумма ADC (High)
; r22 -
; r23 -
; r24 -
; r25 -
; r26 - регистр X (Low)
; r27 - регистр X (High)
; r28 -
; r29 -
; r30 -
; r31 -
;
;--------------------------------Начальные установки
clr r20
clr r21
clr r1
clr r7
clr r8
clr r2
ldi r17,3 ;----N=1,2,3,4,5,6,7
mov r0,r17
sei
idle: rjmp idle ;---Idle
................................................
;------------------------Сюда приходит суммированное 64 раза значение АЦП (r21:r20)
inc r2 ;--------увеличиваем указатель в буфере усреднения
inc r2
push r21
push r20
rcall power
add r6,r6
cp r2,r6
brne ac1
clr r2 ;--------конец буфера? на начало
ac1: ldi r26,$060
clr r27
clr r17
add r26,r2
adc r27,r17
st X+,r20 ;--------запись полученного значения в кольцевой буфер усреднения
st X+,r21
inc r1
rcall power
cp r1,r6 ;--------пора начинать усреднение?
brne accno ;--------рано
;--------------------------------Подсчет суммы в цикле
ldi r26,$060
clr r27
clr r20
clr r21
clr r4
clr r3
clr r17
ac2: ld r6,X+
ld r5,X+
add r20,r6 ;--------сложение 2-ух трёхбайтных чисел
adc r21,r5
adc r4,r3
rcall power
inc r17
cp r17,r6
brne ac2
;-----------------------получили сумму, делим 3-х байтовое число на 2^N
clr r17
ac3: ror r4
ror r21
ror r20
inc r17
cp r17,r0
brne ac3
;--------------------------теперь всегда усреднять
rcall power
mov r1,r6
dec r1
;--------------------------запись в кольцевой буфер сглаженных значений за последние 5 секунд
;--------------------------(это у меня 5 секунд, потому что 30 опросов в секунду)
;--------------------------иначе буфер надо расширить
ldi r26,$60
ldi r27,1
add r26,r8
adc r27,r7
st X+,r20
st X+,r21
;----------указатель смещаем
clr r4
inc r4
inc r4
clr r3
add r8,r4
adc r7,r3
;----------по кольцу
mov r17,r8
cpi r17,$2C
brne accno
mov r17,r7
cpi r17,1
brne accno
clr r7
clr r8
;-----------------------------запись r20,r21 в EEPROM
accno: pop r20
pop r21
..........................
;-------------------------------п/п возведения в степень
;
; r0 - N
; r6 - 2^^N
;
power: push r17
ldi r17,2
mov r6,r17
clr r5
pow1: inc r5
cp r5,r0
breq powfin
push r0
push r1
push r18
mov r18,r6
fmul r18,r17
ror r1
ror r0
mov r6,r0
pop r18
pop r1
pop r0
rjmp pow1
powfin: pop r17
ret
Здесь привожу подпрограмму доступа к этим данным.
;
; Вход: r3:r4 - индекс запрашиваемых данных 0 - 149
; 0-самое свежее значение, 1-следующее и т.д.
; Выход: r21:20 - знчаение
;
; При работе в многозадачной среде при вызове п/п следует запретить прерывания,
? если необходимо, после - разрешить.
;
get_v: push r5
push r6
push r26
push r27
push r16
push r17
push r3
push r4
add r4,r4
adc r3,r3
ldi r26,$60
ldi r27,$1
add r26,r8
adc r27,r7
clr r6
inc r6
inc r6
clr r5
sub r26,r6
sbc r27,r5
sub r26,r4
sbc r26,r3
cpi r27,1
brlt plus
breq pnext
rjmp noplus
pnext: cpi r26,$60
brlt plus
noplus: rjmp gload
plus: ldi r16,$2C
ldi r17,1
add r26,r16
adc r27,r17
gload: ld r20,X+
ld r21,X+
pop r4
pop r3
pop r17
pop r16
pop r27
pop r26
pop r6
pop r5
ret