Доброе время суток!
Слабо знаком с asm на avr поэтому нужна помощь в разборе кода, с последующей перепиской его на Си. Есть код Чана реализующий преобразование fft. До выполнения преобразования в коде присутствует вывод на дисплей исходной волны входного сигнала. Так вот интерисует алгоритм реализующий именно этот вывод, т.е. каким образом ищется 0 и так далее. Заранее бескрайне благодарен за помощь!
Кусок кода
.include "m8def.inc"
.include "avr.inc"
.include "akiglcd.inc"
.equ MOSI = 3 ;Port B bit definitions
.equ LCDCLK = 1 ;/
.equ RW = 5 ;Port C bit definitions
.equ E = 4 ;
.equ CS2 = 3 ;
.equ CS1 = 2 ;
.equ A0 = 1 ;
.equ RES = 0 ;/
.equ FFT_N = 128 ;Number of samples
.equ LCD_W = 122 ;LCD size
.equ LCD_H = 32 ;/
.equ WAV_W = (LCD_W-FFT_N/2)
.def _0 = r15 ;Zero
.def _Flags = r25 ;b0:In captureing
;b1:In pause
;b2:MOSI edge detector
;----------------------------------------------------------;
; Data memory area
.dseg
.org RAMTOP
CaptBuf:.byte FFT_N*2 ;Sampling buffer
BflyBuf:.byte FFT_N*4 ;Butterfly operation table, Wave form buffer
LvlBuf: .byte FFT_N/2 ;Spectrum bar length
AdPtr: .byte 1 ;Sampling pointer
LcdDiv: .byte 1 ;Divider for LCD drive
;----------------------------------------------------------;
; Program code area
.cseg
rjmp reset ; RESET
rjmp 0 ; INT0
rjmp 0 ; INT1
rjmp 0 ; TC2 COMP
rjmp 0 ; TC2 OVF
rjmp 0 ; TC1 CAPT
rjmp 0 ; TC1 COMPA
rjmp 0 ; TC1 COMPB
rjmp 0 ; TC1 OVF
rjmp 0 ; TC0 OVF
rjmp 0 ; SPI
rjmp 0 ; USART RXC
rjmp 0 ; USART UDRE
rjmp 0 ; USART TXC
; rjmp isr_adc ; ADC
; rjmp 0 ; EE_RDY
; rjmp 0 ; ANA_COMP
; rjmp 0 ; TWI
; rjmp 0 ; SPM_RDY
;----------------------------------------------------------;
; ADC interrupt (9.6ksps)
isr_adc:
push AL
in AL, SREG
pushw A
pushw Y
sbrs _Flags, 0 ;Skip if in Idle
rjmp adc_skip ;/
lds YL, AdPtr ;Write pointer
clr YH ;
addiw Y, CaptBuf ;/
inw A, ADC ;Store A/D value
subiw A, 32768 ;
stw Y+, A ;/
lds AL, AdPtr ;Next pointer
addi AL, 2 ;
sts AdPtr, AL ;/
brne PC+2 ;Terminate if 128 samples captured.
cbr _Flags, bit0 ;/
adc_skip:
lds AL, LcdDiv ;Drive LCD clock (2.4kHz)
inc AL ;
sts LcdDiv, AL ;
bst AL, 1 ;
in AL, PORTB ;
bld AL, LCDCLK ;
out PORTB, AL ;/
popw Y
popw A
out SREG, AL
pop AL
reti
;----------------------------------------------------------;
; Initialize peripherals (ATmega8-16AC @16MHz)
reset:
clr _0 ;Zero reg.
ldiw Z, RAMTOP ;Clear all variables
ldiw X, RAMEND-RAMTOP+1 ;
st Z+, _0 ;
sbiw XL, 1 ;
brne PC-2 ;/
sbiw ZL, 1 ;SP Џ‰Љъ‰»
outw SP, Z ;/
outi PORTB, 0b00101000 ;Port B Џ‰Љъ‰»
outi DDRB, 0b00010110
outi PORTC, 0b00001100 ;Port C Џ‰Љъ‰»
outi DDRC, 0b00111111
; Start TC1 with 444kHz on OC1B pin (for MAX293 clock)
ldiw A, 36-1 ;TOP value
outw ICR1, A ;/
ldiw A, 36/2 ;half value
outw OCR1B, A ;/
outi TCCR1A, 0b00100010 ;COM1B[1:0]=10, WGM1[1:0]=10
outi TCCR1B, 0b00011001 ;WGM1[3:2]=11, CS1[2:0]=001
; Start A/D with ch6, free running, 9.6ksps
outi ADMUX, 0b00100110 ;ADLAR=1, MUX[3:0]=0110
outi ADCSR, 0b11101111 ;ADEN=1,ADSC=1,ADFR=1,ADIE=1,ADPS[2:0]=111
rcall lcd_init
clr _Flags
sei
sbr _Flags, bit0 ;Start wave form captureing
;----------------------------------------------------------;
; Main
main:
sbrc _Flags, 0 ;Wait for end of wave captureing
rjmp PC-1 ;/
rcall make_wave ;Make wave form [410us]
rcall rfsh_wave ;Display wave form into LCD [480us]
rcall do_window ;Fill butterfly table [340us]
sbr _Flags, bit0 ;Restart captureing for next
rcall do_fft ;Butterfly operations [4.4ms]
rcall make_bars ;Get scalar values, update spectrum [3.3ms]
rcall rfsh_bars ;Display spectrum bars into LCD [660us]
rcall check_pause ;Check MOSI pin for Pause/Resume [0.8us]
rjmp main ; (approx. 70 cycles/sec)
;----------------------------------------------------------;
; Oscilloscope
make_wave:
ldiw Z, CaptBuf ;Search zero crossing point
ldiw C, FFT_N-WAV_W ;to still cyclic wave form.
lddw A, Z+0 ;
ldiw B, -2000 ;
cpw A, B ;
brge PC+2 ;
sbr CH, bit0 ;
ldiw B, 1000 ;
cpw A, B ;
brlt PC+3 ;
sbrc CH, 0 ;
rjmp PC+4 ;
adiw ZL, 2 ;
dec CL ;
brne PC-17 ;/
ldiw Y, BflyBuf ;Y = Destination
ldi CL, WAV_W ;Loop counter
ldw A, Z+ ;Get a value into A
addiw A, 32768 ;
mov AL, AH ;AL /= 2048 (LCD Y position)
lsr AL ;
lsr AL ;
lsr AL ;/
st Y+, AL ;Store value into destinatation
dec CL ;Repeat WAV_W times
brne PC-10 ;/
ldiw X, WAV_W*4 ;Clear drawing buffer
st Y+, _0 ;
sbiw XL, 1 ;
brne PC-2 ;/
sbiw YL, WAV_W ;Drawing start poitnt
movw T2L, YL ;/
ldiw Z, BflyBuf ;Express waveform into drawing buffer
ld AL, Z
mov AH, AL
andi AL, 7
clr BL
sec
ror BL
subi AL, 1
brcc PC-2
lsr AH
lsr AH
lsr AH
andi AH, 3
ldi AL, WAV_W
mul AL, AH
movw YL, T2L
subw Y, T0
ldi DH, WAV_W-1
dn_l1: ld CL, Z+
ld CH, Z
sub CL, CH
mov DL, CL
brcc PC+2
neg CL
mov CH, CL
lsr CH
dn_l2: ld AL, Y
or AL, BL
st Y, AL
subi CH, 1
brcc PC+2
adiw YL, 1
cpi DL, 0
breq PC+11
brmi PC+6
lsl BL
brne PC+8
ldi BL, 0x01
adiw YL, WAV_W
rjmp PC+5
lsr BL
brne PC+3
ldi BL, 0x80
sbiw YL, WAV_W
subi CL, 1
brcs PC+2
brne dn_l2
dec DH
brne dn_l1
ret
rfsh_wave:
sbrc _Flags, 1 ;Skip if in pause
ret ;/
ldiw Y, BflyBuf+WAV_W
clr BH
ldi BL, FFT_N/2
rcall lcd_setadr
ld AL, Y+
rcall lcd_put
cpi BL, 0
brne PC-3
cpi BH, 4
brcs PC-7
ret
ЗЫ исходник прикрепил
Раздел: AVR
Слабо знаком с asm на avr поэтому нужна помощь в разборе кода, с последующей перепиской его на Си. Есть код Чана реализующий преобразование fft. До выполнения преобразования в коде присутствует вывод на дисплей исходной волны входного сигнала. Так вот интерисует алгоритм реализующий именно этот вывод, т.е. каким образом ищется 0 и так далее. Заранее бескрайне благодарен за помощь!
Кусок кода
.include "m8def.inc"
.include "avr.inc"
.include "akiglcd.inc"
.equ MOSI = 3 ;Port B bit definitions
.equ LCDCLK = 1 ;/
.equ RW = 5 ;Port C bit definitions
.equ E = 4 ;
.equ CS2 = 3 ;
.equ CS1 = 2 ;
.equ A0 = 1 ;
.equ RES = 0 ;/
.equ FFT_N = 128 ;Number of samples
.equ LCD_W = 122 ;LCD size
.equ LCD_H = 32 ;/
.equ WAV_W = (LCD_W-FFT_N/2)
.def _0 = r15 ;Zero
.def _Flags = r25 ;b0:In captureing
;b1:In pause
;b2:MOSI edge detector
;----------------------------------------------------------;
; Data memory area
.dseg
.org RAMTOP
CaptBuf:.byte FFT_N*2 ;Sampling buffer
BflyBuf:.byte FFT_N*4 ;Butterfly operation table, Wave form buffer
LvlBuf: .byte FFT_N/2 ;Spectrum bar length
AdPtr: .byte 1 ;Sampling pointer
LcdDiv: .byte 1 ;Divider for LCD drive
;----------------------------------------------------------;
; Program code area
.cseg
rjmp reset ; RESET
rjmp 0 ; INT0
rjmp 0 ; INT1
rjmp 0 ; TC2 COMP
rjmp 0 ; TC2 OVF
rjmp 0 ; TC1 CAPT
rjmp 0 ; TC1 COMPA
rjmp 0 ; TC1 COMPB
rjmp 0 ; TC1 OVF
rjmp 0 ; TC0 OVF
rjmp 0 ; SPI
rjmp 0 ; USART RXC
rjmp 0 ; USART UDRE
rjmp 0 ; USART TXC
; rjmp isr_adc ; ADC
; rjmp 0 ; EE_RDY
; rjmp 0 ; ANA_COMP
; rjmp 0 ; TWI
; rjmp 0 ; SPM_RDY
;----------------------------------------------------------;
; ADC interrupt (9.6ksps)
isr_adc:
push AL
in AL, SREG
pushw A
pushw Y
sbrs _Flags, 0 ;Skip if in Idle
rjmp adc_skip ;/
lds YL, AdPtr ;Write pointer
clr YH ;
addiw Y, CaptBuf ;/
inw A, ADC ;Store A/D value
subiw A, 32768 ;
stw Y+, A ;/
lds AL, AdPtr ;Next pointer
addi AL, 2 ;
sts AdPtr, AL ;/
brne PC+2 ;Terminate if 128 samples captured.
cbr _Flags, bit0 ;/
adc_skip:
lds AL, LcdDiv ;Drive LCD clock (2.4kHz)
inc AL ;
sts LcdDiv, AL ;
bst AL, 1 ;
in AL, PORTB ;
bld AL, LCDCLK ;
out PORTB, AL ;/
popw Y
popw A
out SREG, AL
pop AL
reti
;----------------------------------------------------------;
; Initialize peripherals (ATmega8-16AC @16MHz)
reset:
clr _0 ;Zero reg.
ldiw Z, RAMTOP ;Clear all variables
ldiw X, RAMEND-RAMTOP+1 ;
st Z+, _0 ;
sbiw XL, 1 ;
brne PC-2 ;/
sbiw ZL, 1 ;SP Џ‰Љъ‰»
outw SP, Z ;/
outi PORTB, 0b00101000 ;Port B Џ‰Љъ‰»
outi DDRB, 0b00010110
outi PORTC, 0b00001100 ;Port C Џ‰Љъ‰»
outi DDRC, 0b00111111
; Start TC1 with 444kHz on OC1B pin (for MAX293 clock)
ldiw A, 36-1 ;TOP value
outw ICR1, A ;/
ldiw A, 36/2 ;half value
outw OCR1B, A ;/
outi TCCR1A, 0b00100010 ;COM1B[1:0]=10, WGM1[1:0]=10
outi TCCR1B, 0b00011001 ;WGM1[3:2]=11, CS1[2:0]=001
; Start A/D with ch6, free running, 9.6ksps
outi ADMUX, 0b00100110 ;ADLAR=1, MUX[3:0]=0110
outi ADCSR, 0b11101111 ;ADEN=1,ADSC=1,ADFR=1,ADIE=1,ADPS[2:0]=111
rcall lcd_init
clr _Flags
sei
sbr _Flags, bit0 ;Start wave form captureing
;----------------------------------------------------------;
; Main
main:
sbrc _Flags, 0 ;Wait for end of wave captureing
rjmp PC-1 ;/
rcall make_wave ;Make wave form [410us]
rcall rfsh_wave ;Display wave form into LCD [480us]
rcall do_window ;Fill butterfly table [340us]
sbr _Flags, bit0 ;Restart captureing for next
rcall do_fft ;Butterfly operations [4.4ms]
rcall make_bars ;Get scalar values, update spectrum [3.3ms]
rcall rfsh_bars ;Display spectrum bars into LCD [660us]
rcall check_pause ;Check MOSI pin for Pause/Resume [0.8us]
rjmp main ; (approx. 70 cycles/sec)
;----------------------------------------------------------;
; Oscilloscope
make_wave:
ldiw Z, CaptBuf ;Search zero crossing point
ldiw C, FFT_N-WAV_W ;to still cyclic wave form.
lddw A, Z+0 ;
ldiw B, -2000 ;
cpw A, B ;
brge PC+2 ;
sbr CH, bit0 ;
ldiw B, 1000 ;
cpw A, B ;
brlt PC+3 ;
sbrc CH, 0 ;
rjmp PC+4 ;
adiw ZL, 2 ;
dec CL ;
brne PC-17 ;/
ldiw Y, BflyBuf ;Y = Destination
ldi CL, WAV_W ;Loop counter
ldw A, Z+ ;Get a value into A
addiw A, 32768 ;
mov AL, AH ;AL /= 2048 (LCD Y position)
lsr AL ;
lsr AL ;
lsr AL ;/
st Y+, AL ;Store value into destinatation
dec CL ;Repeat WAV_W times
brne PC-10 ;/
ldiw X, WAV_W*4 ;Clear drawing buffer
st Y+, _0 ;
sbiw XL, 1 ;
brne PC-2 ;/
sbiw YL, WAV_W ;Drawing start poitnt
movw T2L, YL ;/
ldiw Z, BflyBuf ;Express waveform into drawing buffer
ld AL, Z
mov AH, AL
andi AL, 7
clr BL
sec
ror BL
subi AL, 1
brcc PC-2
lsr AH
lsr AH
lsr AH
andi AH, 3
ldi AL, WAV_W
mul AL, AH
movw YL, T2L
subw Y, T0
ldi DH, WAV_W-1
dn_l1: ld CL, Z+
ld CH, Z
sub CL, CH
mov DL, CL
brcc PC+2
neg CL
mov CH, CL
lsr CH
dn_l2: ld AL, Y
or AL, BL
st Y, AL
subi CH, 1
brcc PC+2
adiw YL, 1
cpi DL, 0
breq PC+11
brmi PC+6
lsl BL
brne PC+8
ldi BL, 0x01
adiw YL, WAV_W
rjmp PC+5
lsr BL
brne PC+3
ldi BL, 0x80
sbiw YL, WAV_W
subi CL, 1
brcs PC+2
brne dn_l2
dec DH
brne dn_l1
ret
rfsh_wave:
sbrc _Flags, 1 ;Skip if in pause
ret ;/
ldiw Y, BflyBuf+WAV_W
clr BH
ldi BL, FFT_N/2
rcall lcd_setadr
ld AL, Y+
rcall lcd_put
cpi BL, 0
brne PC-3
cpi BH, 4
brcs PC-7
ret
ЗЫ исходник прикрепил
Прикрепленные файлы:
Раздел: AVR