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

📄 2nd_order_fir.s90

📁 硬件设计资料,刚上网查找资料,是个新手,望大家提携了,
💻 S90
字号:
;*****************************************************
;* File: 2nd_order_FIR.s90
;*
;*	Version: 1.0 
;*	Date:	01.06.15 [yy.mm.dd]
;*	Author: jllassen
;*
;*  Last modified 02.02.20, by jllassen
;*    Changes: ported the code from the AVR assembler to IAR assembler/compiler
;*
;* Target device: AVRs with HW multiplier
;*
;* Compiler:
;*    IAR EWAVR 2.26C
;*
;* Describtion: 
;*	  2nd order FIR filter. 
;*	  10-bit signed data. 
;*    13-bit signed filter coefficients.
;*
;* Usage:
;*	  Implemented so that the filter can be called from IAR EWAVR C compiler.
;*    Address to the filter nodes and filter coefficients should be provided
;*    as first calling argument (will thus be placed in R16:R17) and the new 
;*    input sample to the filter should be provided as the second calling
;*    argument (placed in R18:R19).
;*      
;*    int FIR_filter(*myFilter, newDataSample);
;*
;*    The structure for the filter nodes and filter coefficients should be
;*    as follows:
;*      
;*    struct FIR_filter{
;*	    int filterNodes[FILTER_ORDER];			    //memory nodes required to store x(n-1), x(n-2)
;*	    int filterCoefficients[(FILTER_ORDER)+1];   //filter coefficients B0, B1, B2
;*	    }, myFilter = {0, 0, B0, B1, B2} 
;*
;*    The filter nodes should be initialized prior to the first call of the 
;*    filter function and the filter coefficients should be scaled to use
;*    signed 13-bit resolution (max)
;*      
;* Registers usage:
;*	  r0-4, r16-23, Z (all scratch/volatile registers)
;*
;* Memory usage for variables and constants:
;*	  4 bytes SRAM for filter nodes (filter memory)
;*    6 bytes SRAM for filter coefficients
;*
;* Stats:
;*	  INIT:  Depending on compiler settings (135 cycles)
;*	  FILTER:  60 instructions; 80 cycles (excl. ret)
;*****************************************************
	NAME	assembly(16)
	PUBLIC	FIR2
	RSEG	CODE

;ZERO register (used to add carry flag)
#define ZERO  R2

#define ZL R30

;Accumulator - 24bit
#define AC2 R16
#define AC1 R17
#define AC0 R3

;First argument passed in the function call: the address to the filter struct (16 bit address pointer)
#define FILTER_POINTER r16

;Second argument passed in the function call: the new data sample
#define NDATAL R18
#define NDATAH R19

;Data samples mul register (used in multiplication)
#define DATAL R20
#define DATAH R21

;Filter coefficient mul register (used in multiplication)
#define COEFL R22
#define COEFH R23

;Filter nodes offset relative to filter struct address
#define X1  0*2
#define X2  1*2

;Filter coefficient offset relative to filter struct address
#define B0  2*2
#define B1  3*2
#define B2  4*2

;**************************************************
;* MACROS
;**************************************************
LOAD_NODE MACRO
	ldd	  DATAL,Z+\1		; Load low byte of node 
	ldd	  DATAH,Z+\1+1		; Load high byte of node
    ENDM

UPDATE_NODE MACRO
	std	  Z+\1, DATAL		; Update low byte of node to prepare next filter run
	std	  Z+\1+1, DATAH		; Update high byte of node to prepare next filter run
    ENDM

LOAD_COEF MACRO
	ldd	  COEFL,Z+\1		; Load low byte of node 
	ldd	  COEFH,Z+\1+1		; Load high byte of node
    ENDM

MUL_MOV_24 MACRO
	muls  COEFH, DATAH		; Signed multiply, coefficient high byte and data high byte
	mov	  AC2, r0			; Copy low byte into accumulator byte 2 (sign bit automatically correct)

	mul	  COEFL, DATAL		; Unsigned multiply, coefficient low byte and data low byte
	mov	  AC0, r0			; Mover result into accumulator byte 0:1
	mov	  AC1, r1
	
	mulsu COEFH, DATAL		; Signed-unsigned multiply, coefficient high byte and data low byte
	add	  AC1, r0			; Add low byte of result to accumulator byte 1
	adc	  AC2, r1			; Add with carry high byte of result to accumulator byte 2

	mulsu DATAH, COEFL		; Signed-unsigned multiply, data high byte and coefficient low byte
	add	  AC1, r0			; Add low byte of result to accumulator byte 1
	adc	  AC2, r1			; Add with carry high byte of result to accumulator byte 2
    ENDM

SMAC24 MACRO
	muls  COEFH, DATAH		; Signed multiply, coefficient high byte and data high byte
	add	  AC2, r0			; Copy low byte into accumulator byte 2

	mul	  COEFL, DATAL		; Unsigned multiply, coefficient low byte and data low byte
	add	  AC0, r0			; Add low byte of result to accumulator byte 0
	adc	  AC1, r1			; Add with carry high byte of result to accumulator byte 1
	adc	  AC2, ZERO			; Add carry to accumulator byte 2

	mulsu COEFH, DATAL		; Signed-unsigned multiply, coefficient high byte and data low byte
	add	  AC1, r0			; Add low byte of result to accumulator byte 1
	adc	  AC2, r1			; Add with carry high byte of result to accumulator byte 2

	mulsu DATAH, COEFL		; Signed-unsigned multiply, data high byte and coefficient low byte 
	add	  AC1, r0			; Add low byte of result to accumulator byte 1
	adc	  AC2, r1			; Add with carry high byte of result to accumulator byte 2
    ENDM
	
;*****************************************************
; FIR filter function
;*****************************************************
FIR2:
	clr   ZERO					; Clear ZERO register 
	movw  ZL, FILTER_POINTER	; Move Struct pointer to the Z-pointer (r30:r31)
	
;B2*x[n-2]
	LOAD_COEF B2
	LOAD_NODE X2
	MUL_MOV_24

;B1*x[n-1]
	LOAD_COEF   B1
	LOAD_NODE   X1
	UPDATE_NODE X2
	SMAC24
	
;B0*x[n]
	LOAD_COEF   B0
	movw        DATAL, NDATAL	; Load new sample into data multiply register
	UPDATE_NODE X1
	SMAC24

;Due to coefficient scaling (gain factor 2^12) the output requires "unscaling"
	asr   AC2			; Scaling to gain factor 2^11
	ror   AC1			; --

	asr   AC2			; Scaling to gain factor 2^10
	ror   AC1			; --

	asr   AC2			; Scaling to gain factor 2^9
	ror   AC1			; --

	asr   AC2			; Scaling to gain factor 2^8
	ror   AC1			; --
	
;Return the value stored in accumulator AC2 and AC1 (which are the return registers)
	ret
    
    END

⌨️ 快捷键说明

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