📄 sub_process_adcsamples.s
字号:
;START_HEADER
;
; dsPIC30F6014 Demo Source File
; (c) Copyright 2005 Microchip Technology, All rights reserved
;
; --------------------------------------------------------------------------
; File Revision History:
; --------------------------------------------------------------------------
;
; $Log: sub_process_adcsamples.s,v $
; Revision 1.3 2005/04/04 23:38:34 VasukiH
; Updated comments in header
;
; Revision 1.2 2005/04/04 23:14:05 VasukiH
; Updates for MPLAB C30 v1.30 compatiblity
;
; Revision 1.1.1.1 2003/08/23 00:38:33 VasukiH
; First import of demo source into CVS Repository
;
;
;
; --------------------------------------------------------------------------
;
; Software and Development Tools Info:
; --------------------------------------------------------------------------
; Tool Version
; --------------------------------------------------------------------------
; MPLAB IDE 7.0
; MPLAB C30 Toolsuite 1.30
; dsPICDEM(TM) Processor Board 1.10
; --------------------------------------------------------------------------
;
; File Notes:
; 1. This routine is responsible for calling all DSP-centric routines
; for performing digital filtering - IIR or FIR, FFT, Magnitude computa-
; tion.
; 2. This routine also calls the data-acquisition subroutine and subroutines
; to update the LCD and UART displays.
;
;END_HEADER
.include "p30fxxxx.inc"
.include "common.inc"
.global Magnitude, FilteredOutput, ANxInputSignal
.global PeakFrequecy, PeakBin
.global FilterType, FFTTime, FilteringTime
.section .xbss, bss, xmemory ;Uninitialized X- space
.align CPLXWORD*FFT_SIZE
Magnitude:
FilteredOutput: .space WORD * FFT_SIZE ;o/p from Filter and i/p to FFT and o/p from FFT
ANxInputSignal: .space WORD * FFT_SIZE ;i/p to filter, merged into o/p from FFT
.section .nbss, bss, near ;Uninitialized Near space
.align WORD
PeakFrequecy: .space WORD ;Stores the Peak frequency from a given Magnitude array
PeakBin: .space WORD ;Stores the bin number for the peak frequency
.section .ndata, data, near ;Initialized Near space
.align WORD
FilterType: .hword 0x0000 ;If bit 1 is set, it indicates no filtering
;If bit 1 is cleared, then if bit 0 is set,
;FIR filtering is chosen, else IIR is chosen.
FilteringTime: .hword 0x0000 ;32-bit value saved from Timer5:Timer4
.hword 0x0000 ;indicates total filtering time for a set of
;256 samples, expressed in Tcy
FFTTime: .hword 0x0000 ;32-bit value saved from Timer5:Timer4
.hword 0x0000 ;indicates total FFT time for a set of
;256 samples, expressed in Tcy
.global _sub_process_adcsamples
.section .text
_sub_process_adcsamples:
bclr ADCON1, #ADON ;Turn Off A/D
mov #0x0000, w0 ;Clear 32-bit timer
mov w0, TMR5 ;in preparation for a filtering routine
mov w0, TMR4 ;benchmarking excercise
;Has the User chosen Line noise Filtering? Check here
btsc FilterType, #1 ;Check if filtering should be performed
bra do_FFT ;on the data set
;Call the Appropriate Filtering routine (FIR or IIR)
btsc FilterType, #0 ;If yes, check if the filtering should be
;FIR or IIR?
bra do_FIR_Filter
filtering:
;Set up pointers to Filter Initialization Routine
mov #_LineNoiseIIRFilter, W0 ;Initalize W0 to filter structure
call _IIRTransposeFilterInit ;Call this function once
do_IIR_Filter:
mov #_LineNoiseIIRFilter, w0 ;Initalize W0 to filter structure
mov #ANxInputSignal, w1 ;Initalize W1 to input buffer
mov #FilteredOutput, w2 ;Initalize W2 to output buffer
mov #FFT_SIZE, w3 ;Initialize W3 with number of required output samples
bset PORTD, #RD4
bset T4CON, #TON
rcall _sub_iirt_filter ;Call IIR Transposed filter as many times as needed
bclr T4CON, #TON
bclr PORTD, #RD4
bra do_FFT ;Jump to the FFT routine
do_FIR_Filter:
mov #_LineNoiseFIRFilter, w0 ;Initalize W0 to filter structure
mov #ANxInputSignal, w1 ;Initalize W1 to input buffer
mov #FilteredOutput, w2 ;Initalize W2 to output buffer
mov #FFT_SIZE, w3 ;Initialize W3 with number of required output samples
bset PORTD, #RD5
bset T4CON, #TON
rcall _sub_fir_filter ;Call Block FIR rooutine as many times as needed
bclr T4CON, #TON
bclr PORTD, #RD5
do_FFT:
mov TMR4, w0
mov TMR5, w1
mov w0, FilteringTime ;Save off the Filtering Time value
mov w1, FilteringTime+2
clr TMR4
clr TMR5
;Data setup for Bit-reverse and FFT routines
mov #FilteredOutput,w0
mov #y_twid,w1
mov #FFT_SIZE, w2 ;Initialize W2 with number of required output samples (256)
mov #FFT_STAGES, w3 ;Log-base2(256) = 8
bset PORTD, #RD6
bset T4CON, #TON
rcall _sub_fft ;Call the FFT routine
bclr T4CON, #TON
bclr PORTD, #RD6
mov TMR4, w0
mov TMR5, w1
mov w0, FFTTime ;Save the FFT time
mov w1, FFTTime+2
clr TMR4
clr TMR5
;Data setup for squared-magnitude routine
mov #FilteredOutput,w0 ;Set input and output pointers to the
mov #Magnitude,w1 ;same location
mov #FFT_SIZE, w2 ;Initialize W2 with number of required output samples
rcall _magnitude ;Call the Magnitude computation routine
;Find Frequency and PeakBin
mov #FFT_SIZE/2, w0 ;Find the largest magnitude and it's associated Bin value
mov #Magnitude, w1
mov #PeakBin, w2
rcall _sub_vector_max ;Call a Vector-Maximum routine
sl [w2], w2 ;Shift the value by one bit to the left
mov #20, w4 ;Compare against a threshold value
;If the value is lesser than threshold then
;the frequency estimate should be "0 Hz"
cp w0, w4
bra ge, get_freq
clr w2
clr PeakBin
get_freq:
push PSVPAG
push CORCON
bset CORCON, #PSV
mov #psvpage(FreqBins256), w0 ;If the value is greater than the threshold,
mov w0, PSVPAG ;then index into the array of frequencies
mov #psvoffset(FreqBins256), w0 ;stored in Program Space and retrieve the
add w0, w2, w0 ;frequency value corresponding to the Peak bin.
mov [w0], w1
mov w1, PeakFrequecy
pop CORCON
pop PSVPAG
display_res:
rcall _sub_data_acq ;Find the Potentiometer voltages and Temperature
;Sensor Measurement
rcall _sub_refresh_display_buffers ;Call Display buffer refresh Routines for LCD
;and UART2
rcall _sub_apply_menu_choice ;Use the user choices collected at the switches
;to update/change the display screen or an item
;within the screen.
rcall _sub_lcd_menu_disp ;Call routine that kicks of SPI2 communication
;with the LCD controller
Check_Cursor_Menu: ;If current screen selection =5 (DTMF with cursor)
mov #5, w0 ;then update the cursor else skip the
cp ScreenSelection ;cursor management routine
bra nz, skip_cursor_ctrl
rcall _sub_cursor_control
skip_cursor_ctrl:
btsc PlayRecSequence, #1 ;If a Tone sequence needs to be played, then
rcall _sub_play_tone_seq ;call the sub_play_tone_seq routine.
rcall DelayLoop ;Call a 16 millisecond delay loop
clr ADCDataAvailable ;Clear the ADCDataAvailable flag and turn on
bset ADCON1, #ADON ;the A/D module
return ;Return to the main routine
;------------------------------------------------------------------------
_magnitude:
; C-callable routine
; w0 contains pointer to FFT output array
; w1 contains pointer to magnitude output array
; w2 contains FFT size
push.d w4
push w8
mov w0,w8 ;w8 points to beginning of FFT output array
dec w2,w2 ;Adjust loop count
clr A,[w8]+=2,w4
do w2, magend
mpy w4*w4,A,[w8]+=2,w5 ;Compute Xr^2
mac w5*w5,A,[w8]+=2,w4 ;Squared Magnitude = Xr^2 + Xi^2
magend: sac.r A,#0,[w1++] ;Store result in magnitude array
inc w2,w2 ;Restore w2 value
pop w8
pop.d w4
return
DelayLoop:
push.d w0
mov #0x2, w0
delay_outer:
mov #0xFFFF, w1
delay_inner:
dec w1, w1
bra nz, delay_inner
dec w0, w0
bra nz, delay_outer
pop.d w0
return
.end ;EOF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -