⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msp430f169_fir.s43

📁 用C语言编写的基于低功耗单片机MSP430作为MCU的FIR滤波程序。
💻 S43
📖 第 1 页 / 共 2 页
字号:
;// THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
;// REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, 
;// INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 
;// FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR 
;// COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE. 
;// TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET 
;// POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY 
;// INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR 
;// YOUR USE OF THE PROGRAM.
;//
;// IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 
;// CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY 
;// THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED 
;// OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT 
;// OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM. 
;// EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF 
;// REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS 
;// OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF 
;// USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S 
;// AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF 
;// YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS 
;// (U.S.$500).
;//
;// Unless otherwise stated, the Program written and copyrighted 
;// by Texas Instruments is distributed as "freeware".  You may, 
;// only under TI's copyright in the Program, use and modify the 
;// Program without any charge or restriction.  You may 
;// distribute to third parties, provided that you transfer a 
;// copy of this license to the third party and the third party 
;// agrees to these terms by its first use of the Program. You 
;// must reproduce the copyright notice and any other legend of 
;// ownership on each copy or partial copy, of the Program.
;//
;// You acknowledge and agree that the Program contains 
;// copyrighted material, trade secrets and other TI proprietary 
;// information and is protected by copyright laws, 
;// international copyright treaties, and trade secret laws, as 
;// well as other intellectual property laws.  To protect TI's 
;// rights in the Program, you agree not to decompile, reverse 
;// engineer, disassemble or otherwise translate any object code 
;// versions of the Program to a human-readable form.  You agree 
;// that in no event will you alter, remove or destroy any 
;// copyright notice included in the Program.  TI reserves all 
;// rights not specifically granted under this license. Except 
;// as specifically provided herein, nothing in this agreement 
;// shall be construed as conferring by implication, estoppel, 
;// or otherwise, upon you, any license or other right under any 
;// TI patents, copyrights or trade secrets.
;//
;// You may not use the Program in non-TI devices.
;//
;-------------------------------------------------------------------------------
; Self contained demo code showing FIR filters
; FIR implementation using DMA channels for maximum performance of the filter.
; Requires 2*TAPNO word RAM buffer for input samples to minimize circular
; buffer overhead
; DMA ch. 0 used to move FIR filter coef from Program mem table to MULS register
; DMA ch. 1 used to move FIR up sample pointer.
; DMA ch.2 used to move FIR down sample pointer
; All three DMAs are enabled and disabled together by modulating
; TACCR0 register is toggled between 0(disable) and 0xb (trigger every 12 clocks).
; This scheme takes advantage of symmetrical nature of coef.  The algorithm loads
; a coefficient value once to MPYS via DMA ch 0, then moves two samples 
; sequentially to OP2. The first sample is controlled by ch 1 and second by ch 2.  
; ch 1 scans through 1/2 sample window by incrementing and ch 2 scans through 
; second half sample window by decrementing.  
; The Code written such that there is some foreground processor resources while 
; the FIR is running at highest possible sample rate. 
; Only 1/2 of the coefficients are stored in flash.  If the number of taps is even, 
; then exactly the first half are stored.  If the number of taps is odd, then the 
; number of coefficients stored is (N+1)/2 and the last coef value must be divided 
; by two.  
; Adapted from Code originally written by Alva Henderson
; Murugavel Raju  
; 10/31/2003   Version 0.0
; 10/23/2004   Version 0.1   
;-------------------------------------------------------------------------------

#include "msp430x16x.h"                         ; MSP430f169 definitions
#include "sine8192_12b.dat"                     ; 8192 pt sinewave table 
                                                ; 12 bit resolution
;-------------------------------------------------------------------------------
            RSEG    DATA16_N                    ; RAM Allocation
            EVEN
;-------------------------------------------------------------------------------
; Global variables
UP                  DS  2                       ; Temp Up pointer
DN                  DS  2                       ; Temp Down pointer
COEFNO              DS  2                       ; Number of coefficients
FREQINC             DS  2                       ; Sweep input resolution
BASE                DS  2                       ; Time base for input frequency
SWCNTR              DS  2                       ; Sweep counter
SWRATE              DS  2                       ; Input sweep rate variable
PDN_INIT            DS  2                       ; Up pointer
PUP_INIT            DS  2                       ; Down pointer
INPUT               DS  2                       ; Input data 
SAMPBUF             DS  2                       ; Pointer to sample buffer 
; INPUT sine wave constants to set sweep start freq, stop freq and sweep rate
FREQMAX             EQU     8192/2              ; freq = sample freq/2 
FREQMIN             EQU     10                  ; freq = sample freqX10/8192
TMAPER              EQU     0x0b                ; set Timer_A interval to 
                                                ; trigger DMA and execute FIR
;-------------------------------------------------------------------------------
            RSEG    CSTACK                      ; CPU stack
;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------
            RSEG    CODE                        ; Place code in program memory
            EVEN
;-------------------------------------------------------------------------------
Main        mov.w   #SFE(CSTACK),SP             ; Initialize stackpointer
            mov.w   #WDTHOLD+WDTPW,&WDTCTL      ; Stop watchdog timer            
SetupBC     bic.b   #XT2OFF,&BCSCTL1            ; XT2 = on
SetupOsc    bic.b   #OFIFG,&IFG1                ; Clear OSC fault flag 
            mov.w   #0FFh,R15                   ; R15 = Delay 
SetupOsc1   dec.w   R15                         ; delay to ensure start 
            jnz     SetupOsc1                   ;
            bit.b   #OFIFG,&IFG1                ; OSC fault flag set? 
            jnz     SetupOsc                    ; OSC Fault, clear flag again 
            bis.b   #SELM1+SELS,&BCSCTL2        ; MCLK = SMCLK = XT2 (safe)
RAMCLEAR    mov.w   #1000,R4                    ; Number of RAM locations to clear                
            mov.w   #0200h,R5                   ; RAM start                     
ZERORAM     clr.w   0(R5)                       ; Clear address pointed by R5
            add.w   #0x2,R5                     ; Next word
            dec.w   R4
            jnz     ZERORAM
            mov.w   &SWRATE,30                  ; Value for Sweep rate       
CLEARFMULT
            clr.w   &RESHI                      ; Clear multiplier result registers
            clr.w   &RESLO
;address pointers for ch 1 and ch 2 depend on if taps are even or odd
INITPTR     mov.w   &(FILTER+2),R4              ; read number of taps from table 
            add.w   #0x0,R4                     ; Clear carry flag
            rrc.w   R4                          ; Calculate actual coef number 
                                                ; and initial down pointer for ch 2
            jc      noteven                     ; this calculation is different if  
                                                ; tap number is odd or even
            jmp     eeven
noteven     add.w   #0x1,R4                     ; if not even number of coefficients
eeven       mov.w   R4,&COEFNO                  ; used for calculation is (N+1)   
            mov.w   &(FILTER+2),R4              ; reload tap to calculate up and 
                                                ; down pointer starting values                            
            rla.w   R4                          ; X 2 for reserving up circular buffer    
calc_pdn    mov.w   R4,R5                       ; save result
            rla.w   R5                          ; additional X 2 buffers for down buffer
            sub.w   #0x2,R5                     ;
            add.w   #SAMPBUF,R4                 ; calculate up buffer top pointer
            mov.w   R4,&PUP_INIT                ; store value in PUP_INIT
            mov.w   R4,&UP                      ; temp store in UP for DMA operation
            add.w   #SAMPBUF,R5                 ; initialize forward and backward 
                                                ; sample buffer pointers.
            mov.w   R5,&PDN_INIT                ; store value in PDN_INIT
            mov.w   R5,&DN                      ; temp store in DN for DMA operation
            mov.w   #0x0,&INPUT                 ; clear input sample
           
;Once configured the DMA executes the FIR algorithm 
DMA_setup   mov.w   #DMA2TSEL_1+DMA1TSEL_1+DMA0TSEL_1,&DMACTL0
                                                ; DMA Channels triggered by TACCIFG2           
; channel 0 is coef table
            mov.w   #DMASRCINCR_3,&DMA0CTL      ; Increment source address after transfer
            mov.w   #(FILTER+4),&DMA0SA         ; Points the first filled zero coefficient
            mov.w   #MACS,&DMA0DA               ; Hardware multiplier MACS operand
            mov.w   &COEFNO,&DMA0SZ             ; Size of transfer number of coefficients
; channel 1 addresses and sends to multiplier the first half sample window
            mov.w   #DMASRCINCR_3,&DMA1CTL      ; Increment source address after transfer 
            mov.w   &COEFNO,&DMA1SZ             ; Size of transfer number of coefficients
            mov.w   &PUP_INIT,&DMA1SA           ; Upper half data table
            mov.w   #OP2,&DMA1DA                ; Hardware multiplier operand 2
; channel 2  addresses and sends to multiplier the second half sample window
            mov.w   #DMASRCINCR_2,&DMA2CTL      ; Decrement source address after transfer 
            mov.w   &COEFNO,&DMA2SZ             ; Size of transfer number of coefficients
            mov.w   &PDN_INIT, &DMA2SA          ; Lower half data table
            mov.w   #OP2,&DMA2DA                ; Hardware multiplier operand 2

; set up timerA for  DMA channel trigger source
    	    mov.w   #0x0,&TACCR0                ; Start with CCR0 = 0, Trigger disable
            mov.w   #0x1,&TACCR2                ; compare point soon after counter starts. 
            mov.w   #OUTMOD_3,&TACCTL2          ; To trigger DMA
            mov.w   #TASSEL1+MC0,&TACTL  	;  
; TimerB, sample rate, ADC and DAC conversion triggers
            clr.w   &TBCCR0                     ; Clear TBCCR0
            mov.w   #TBSSEL1+MC0,&TBCTL         ; up mode SMCLK
            mov.w   &FILTER,R4                  ; get sample rate from table
            sub.w   #20,R4                      ; for ADC and DAC trigger pulse generation
            mov.w   R4,&TBCCR2                  ; compare value for TBCCR2
            sub.w   #15,R4                      ;
            mov.w   R4,&TBCCR1                  ; compare value for TBCCR1      
            mov.w   #OUTMOD_7,&TBCCTL1          ; to trigger ADC12
            mov.w   #OUTMOD_3,&TBCCTL2          ; to trigger DACs
                                            
; ADC - this peripheral is currently not used in this code but will 
; be used when input to FIR is an actual external analog signal.
            mov.w   #SHT1_0+SHT0_0+ADC12ON+REFON+REF2_5V,&ADC12CTL0
                                                ; REF is required for DACs
            mov.w   #SHS_3+ADC12DIV_0+ADC12SSEL_2+CONSEQ_0,&ADC12CTL1
            mov.w   #0x0,&ADC12IE               ; Disable ADC12 Interrupts              
; DACs - used to output both input and output of the FIR in this demo
            clr.w   &DAC12_0DAT                 ; Clear DAC0 data register                 
            mov.w   #DAC12AMP_7+DAC12LSEL_3+DAC12IR+DAC12DF+ENC,&DAC12_1CTL
            mov.w   #DAC12AMP_7+DAC12LSEL_3+DAC12IR+DAC12DF+ENC,&DAC12_0CTL
            bis.w   #DAC12CALON,&DAC12_1CTL
            bis.w   #DAC12CALON,&DAC12_0CTL     ; Self calibrate DAC0 and DAC1                                  
; Initialize input sine wave frequency parameters for software frequency sweep        
            clr.w   &BASE                       ; Clear the base frequency                 
            mov.w   #(2*FREQMIN), &FREQINC      ; Start frequency           

SetupFIR    mov.w   &FILTER,&TBCCR0             ; passed from filter table 
            bis.w   #CCIE,&TBCCTL0              ; start timerB
            bis.w   #GIE,SR                     ; enable global interrupt
            bis.w   #DMAEN,&DMA0CTL             ; enable DMA0
            bis.w   #DMAEN,&DMA1CTL             ; enable DMA1
            bis.w   #DMAEN,&DMA2CTL             ; enable DMA2
            mov.w   #TMAPER,&TACCR0             ; start FIR, by starting 
                                                ; trigger of DMA channels  
            mov.w   &FILTER,&TBCCR0             ; start TimerB and enable 
                                                ; ADC and DAC             
;-------------------------------------------------------------------------------
Userprogram   
            jmp     Userprogram                 ; USer program, TimerA and DMA 
                                                ; interrupt to execute the FIR              
;-------------------------------------------------------------------------------
; TimerB Interrupt Service Routine 
;-------------------------------------------------------------------------------
Timer_B0_ISR
            mov.w   &RESHI,&DAC12_1DAT          ; move FIR filter output to DAC1  
            mov.w   #0x0,&TACCR0                ; Stop DMA by stopping trigger
            bic.w   #CCIFG,&TACCTL2             ; Clear TimerA IFG
            clr.w   &RESLO                      ; Clear multiplier registers 
            clr.w   &RESHI                      ; for next FIR run           
            mov.w   #DMASRCINCR_3+DMAEN,&DMA0CTL;          
            mov.w   #DMASRCINCR_3+DMAEN,&DMA1CTL;         
            mov.w   #DMASRCINCR_2+DMAEN,&DMA2CTL; Reenable DMA channels and start        
            mov.w   #TMAPER,&TACCR0             ; set Timer_A period for next run             
            sub.w   #0x2,&UP                    ; update pointers for FIR
            cmp.w   #SAMPBUF,&UP                ; check if top of up buffer reached 
            jz      datamov                     ; if so reassign
            mov.w   &UP,R4                      ; pointer for up circular buffer
            mov.w   &INPUT,0(R4)                ; store input sample in circular buffer    
            mov.w   &DN,R4                      ; pointer for down circular buffer
            mov.w   &INPUT,0(R4)                ; Back fill double buffer for data move
            sub.w   #0x2,&DN                    ; update pointer for FIR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -