📄 specana.asm
字号:
;-----------------------------------------------------------------------------;
;
; ( ;
;-----------------------------------------------------------------------------;
; Edited by Fabian "ape" Thiele Jan 26, 2005 ;
; me@apetech.de ;
; http://www.apetech.de ;
; ;
; MPU: ATmega32 ;
; Clock: 18.432MHz ;
;-----------------------------------------------------------------------------;
;
.include "m32def.inc"
.include "avr.inc"
.include "akiglcd.inc"
.equ FFT_N = 128 ;Number of samples
.equ FFT_SCALE = 256/2 ;FFT scaling
.equ FFT_BDEC = 4 ;Bar decay rate
.equ FFT_PS = 6 ;Peak Speed
.equ TWI_ADR = 0x10 ;TWI Slave Address
.equ TWI_RECV_ACK = (1<<TWIE) | (1<<TWEN) | (1<<TWINT) | (1<<TWEA)
.equ TWI_RECV_NACK = (1<<TWIE) | (1<<TWEN) | (1<<TWINT)
.equ TWI_TRANS_ACK = (1<<TWIE) | (1<<TWEN) | (1<<TWINT) | (1<<TWEA)
.equ TWI_TRANS_NACK = (1<<TWIE) | (1<<TWEN) | (1<<TWINT)
.equ TWI_NOT_ADDR = (1<<TWIE) | (1<<TWEN) | (1<<TWINT) | (1<<TWEA)
.def _0 = r15 ;Zero
.def _Flags = r25 ;b0: capture loRes, b1: capture hiRes, b7: ADC hiRes-Mode: 1st/2nd Sample
;----------------------------------------------------------;
; Data memory area
.dseg
.org RAMTOP
CaptBuf: .byte FFT_N*2 ;Sampling buffer
BflyBuf: .byte FFT_N*4 ;Butterfly operation table, Wave form buffer
AdPtr: .byte 2 ;Sampling pointer for hiRes FFT
hiResPS: .byte 1 ;Software ADC prescaler for high resolution prescaling
TwiPtr: .byte 2 ;TWI read pointer
TmpLvlBuf1: .byte FFT_N/2 ;Temp level buffer for hiRes FFT
PeakSpeedBuf1: .byte FFT_N/2 ;Peak speed buffer for hiRes FFT
TmpLvlBuf2: .byte FFT_N/2 ;Temp level buffer for loRes FFT
PeakSpeedBuf2: .byte FFT_N/2 ;Peak speed buffer for loRes FFT
TmpLvlBuf3: .byte 78 ;Temp level buffer for interpolated FFT
PeakSpeedBuf3: .byte 78 ;Peak speed buffer for interpolated FFT
LvlBuf1: .byte FFT_N/2 ;Spectrum bar length for hiRes FFT
PeakBuf1: .byte FFT_N/2 ;Peak buffer for hiRes FFT
LvlBuf2: .byte FFT_N/2 ;Spectrum bar length for loRes FFT
PeakBuf2: .byte FFT_N/2 ;Peak buffer for loRes FFT
LvlBuf3: .byte 78 ;Spectrum bar length for interpolated FFT
PeakBuf3: .byte 78 ;Peak buffer for interpolated FFT
;----------------------------------------------------------;
; Program code area
.cseg
jmp reset ; RESET
jmp 0 ; INT0
jmp 0 ; INT1
jmp 0 ; INT2
jmp 0 ; TC2 COMP
jmp 0 ; TC2 OVF
jmp 0 ; TC1 CAPT
jmp 0 ; TC1 COMPA
jmp 0 ; TC1 COMPB
jmp 0 ; TC1 OVF
jmp 0 ; TC0 COMP
jmp 0 ; TC0 OVF
jmp 0 ; SPI
jmp 0 ; USART RXC
jmp 0 ; USART UDRE
jmp 0 ; USART TXC
jmp isr_adc ; ADC
jmp 0 ; EE_RDY
jmp 0 ; ANA_COMP
jmp isr_twi ; TWI
jmp 0 ; SPM_RDY
;----------------------------------------------------------;
; ADC interrupt (22.2ksps)
isr_adc:
push AL
in AL, SREG
pushw A
pushw B
pushw Y
push CL
; Sample for high resolution FFT
sbrs _Flags, 0 ;Skip if in Idle
rjmp adc_loRes ;/
ldsw Y, AdPtr ;load pointer
addiw Y, CaptBuf ;/
inw A, ADC ;load A/D value
sbrs _Flags, 7 ;1st or 2nd sample?
rjmp isr_adc_l1
ldw B, Y+ ;load value
subiw Y, 2 ;/
addw B, A ;add sample
lsrw B ;value = value / 2
stw Y+, B ;store down-sampled value
subiw Y, CaptBuf ;store incremented pointer
stsw AdPtr, Y ;/
cbr _Flags, bit7 ;clear flag for 2nd sample
cpiw Y, FFT_N*2 ;Terminate if FFT_N/2 samples captured.
brne adc_skip
clrw A
stsw AdPtr, A
cbr _Flags, bit0 ;/
rjmp adc_skip
isr_adc_l1:
stw Y+, A ;store sample
sbr _Flags, bit7 ;set flag for 2nd sample
adc_loRes:
; Sample for low resolution FFT
sbrs _Flags, 1 ;Skip if in Idle
rjmp adc_skip ;/
ldsw Y, AdPtr ;load pointer
addiw Y, CaptBuf ;/
inw A, ADC ;load A/D value
stw Y+, A ;store sample
subiw Y, CaptBuf ;
stsw AdPtr, Y ;/
cpiw Y, FFT_N*2 ;Terminate if FFT_N/2 samples captured.
brne adc_skip
clrw A
stsw AdPtr, A
cbr _Flags, bit1 ;/
adc_skip:
pop CL
popw Y
popw B
popw A
out SREG, AL
pop AL
reti
;----------------------------------------------------------;
; TWI interrupt
isr_twi:
push AL
in AL, SREG
pushw A
pushw Y
in AL, TWSR
andi AL, 0xF8
;Slave Receiver Status Codes
cpi AL, 0x60 ; SLA+W received, ACK returned
breq twi_sla_w
cpi AL, 0x80 ; Data received, ACK returned
breq twi_data_recv_ack
cpi AL, 0x88 ; Data received, NACK returned
breq twi_data_recv_nack
;Slave Transmitter Status Codes
cpi AL, 0xA8 ; SLA+R received, ACK returned
breq twi_sla_r
cpi AL, 0xB8 ; Data byte in TWDR transmitted, ACK received
breq twi_data_trans_ack
cpi AL, 0xC0 ; Data byte in TWDR transmitted, NACK received
breq twi_data_trans_nack
cpi AL, 0xC8 ; Last byte transmitted, ACK received
breq twi_last_data_trans_ack
outi TWCR, TWI_NOT_ADDR ; Default: Switch to not addressed slave mode
rjmp isr_twi_end
twi_sla_w:
outi TWCR, TWI_RECV_ACK ; receive data, return ACK
rjmp isr_twi_end
twi_data_recv_ack:
in AL, TWDR ; get 1st (high) address byte
sts TwiPtr+1, AL ; /
outi TWCR, TWI_RECV_NACK ; receive next byte, return NACK
rjmp isr_twi_end
twi_data_recv_nack:
in AL, TWDR ; get 2nd (low) address byte
sts TwiPtr, AL ; /
outi TWCR, TWI_NOT_ADDR ; Switch to not addressed slave mode
rjmp isr_twi_end
twi_sla_r:
ldsw Y, TwiPtr ; get requested address
addiw Y, LvlBuf1 ; /
ld AL, Y+ ; Load first level into TWDR
out TWDR, AL ; /
stsw TwiPtr, Y ; Store next pointer
outi TWCR,TWI_TRANS_ACK ; Start TWI transmission
rjmp isr_twi_end
twi_data_trans_ack:
ldsw Y, TwiPtr ; Load next address
ld AL, Y+ ; Load next level into TWDR
out TWDR, AL ; /
stsw TwiPtr, Y ; Store next pointer
cpiw Y, PeakBuf3+78 ; Stop transmission if end of spectrum memory reached
breq twi_stop_trans ; /
outi TWCR, TWI_TRANS_ACK ; Start TWI transmission
rjmp isr_twi_end
twi_stop_trans:
outi TWCR, TWI_TRANS_NACK ; Start (last) TWI transmission
rjmp isr_twi_end
twi_data_trans_nack:
outi TWCR, TWI_NOT_ADDR ; Switch to not addressed slave mode
rjmp isr_twi_end
twi_last_data_trans_ack:
outi TWCR, TWI_NOT_ADDR ; Switch to not addressed slave mode
isr_twi_end:
popw Y
popw A
out SREG, AL
pop AL
reti
;----------------------------------------------------------;
; Initialize peripherals (ATmega32)
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 ;/
; Two Wire Interface (Slave Mode)
outi TWAR, TWI_ADR
outi TWCR, (1<<TWEA) | (1<<TWEN) | (1<<TWIE)
; Start A/D with ch0, free running, 11.1ksps
outi ADMUX, 0b00000000 ;MUX[3:0]=0000
outi ADCSR, 0b11101111 ;ADEN=1,ADSC=1,ADFR=1,ADIE=1,ADPS[2:0]=110
; MAX297 clock;
outi DDRD, (1<<5) ;clock pin -> output
ldiw A, 135-1 ;136.5kHz -> 2.73kHz cut off
outw ICR1, A ;
ldiw A, 135/2-1 ;
outw OCR1A, A ;/
outi TCCR1A, 0b10000010 ;COM1A[1:0]=10, WGM1[1:0]=10
outi TCCR1B, 0b00011001 ;WGM1[3:2]=11, CS1[2:0]=001
clr _Flags
sei
sbr _Flags, bit0 ;Start wave form hiRes captureing
;----------------------------------------------------------;
; Main
main:
outi PORTB, 0b00000100
rcall calc_peaks1
rcall calc_peaks2
rcall calc_mixed_spec ;calculate interpolated spectrum
rcall calc_peaks3
;------------------------------------------
; High Resolution FFT
;------------------------------------------
sbrc _Flags, 0 ;Wait for end of 5.5kHz wave captureing
rjmp PC-1 ;Here is a lot of CPU time wasted...
;Change MAX297 clock
ldiw A, 36-1 ;512kHz -> 10.2kHz cut off
outw ICR1, A ;
ldiw A, 36/2-1 ;
outw OCR1A, A ;
outi TCNT1L, 0 ;
outi TCNT1H, 0 ;/
rcall do_window ;Fill butterfly table [300us]
;Start captureing for loRes FFT
outi ADCSR, 0b11101110 ;22.2kHz Sampling Rate
sbr _Flags, bit1 ;set flag to start captureing
rcall do_fft ;Butterfly operations [3.8ms]
ldiw Y, TmpLvlBuf1 ;Temp bar length buffer
rcall make_bars ;Get scalar values, update spectrum [2.9ms]
;------------------------------------------
; Low Resolution FFT
;------------------------------------------
sbrc _Flags, 1 ;Wait for end of 22.2kHz wave captureing
rjmp PC-1 ;/
;Change MAX297 clock
ldiw A, 135-1 ;136.5kHz -> 2.73kHz cut off
outw ICR1, A ;
ldiw A, 135/2-1 ;
outw OCR1A, A ;
outi TCNT1L, 0 ;
outi TCNT1H, 0 ;/
rcall do_window ;Fill butterfly table [300us]
;Start captureing for hiRes FFT
outi ADCSR, 0b11101111 ;11.1kHz Sampling Rate
sbr _Flags, bit0 ;set flag to start captureing
rcall do_fft ;Butterfly operations [3.8ms]
ldiw Y, TmpLvlBuf2 ;Temp bar length buffer
rcall make_bars ;Get scalar values, update spectrum [2.9ms]
rjmp main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -