You are on page 1of 18

;IIR filter program example

list p=18c452
#include<p18c452.inc>

;specifies the processor used.

;*********************************************************************
;Low pass Butterworth filter
;cut-off frequency 500 Hz
;*********************************************************************
;specify the number of biquad sections in the following line
CONSTANT NUMBER_OF_SECTIONS=3
;*******************SECTION 1*****************************************
CONSTANT a1_0=0X4
CONSTANT a1_1=0X9
CONSTANT a1_2=0X4
CONSTANT b1_1=0x3B0
CONSTANT b1_2=0XD2
CONSTANT YK1=D 0 ;enter this value in decimal representation only
;*******************SECTION 2*****************************************
CONSTANT K2=0x40
CONSTANT a2_0=0X7
CONSTANT a2_1=0Xe
CONSTANT a2_2=0X7
CONSTANT b2_1=0X35b
CONSTANT b2_2=0X77
CONSTANT YK2=D 64 ;enter this value in decimal representation only
;*******************SECTION 3*****************************************
CONSTANT K3=0x40
CONSTANT a3_0=0x7
CONSTANT a3_1=0XF
CONSTANT a3_2=0X7
CONSTANT b3_1=0X376
CONSTANT b3_2=0X94
CONSTANT YK3=D 62 ;enter this value in decimal representation only
;*********************************************************************
;*********************************************************************
;High pass Butterworth filter
;cut-off frequency 600 Hz
;sampling frequency 8000 Hz
;*********************************************************************
;specify the number of biquad sections in the following line
CONSTANT NUMBER_OF_SECTIONS=3
;*******************SECTION 1*****************************************
CONSTANT a1_0=0X6c
CONSTANT a1_1=0X2d7
CONSTANT a1_2=0X6c
CONSTANT b1_1=0x39b
CONSTANT b1_2=0Xcb
CONSTANT YK1=D 0 ;enter this value in decimal representation only
;*******************SECTION 2*****************************************
CONSTANT K2=0x80
CONSTANT a2_0=0Xa8
CONSTANT a2_1=0X350
CONSTANT a2_2=0Xa8
CONSTANT b2_1=0X340
CONSTANT b2_2=0X66
CONSTANT YK2=D 0 ;enter this value in decimal representation only
;*******************SECTION 3*****************************************
CONSTANT K3=0x80
CONSTANT a3_0=0xb6
CONSTANT a3_1=0X36c

CONSTANT a3_2=0Xb6
CONSTANT b3_1=0X35c
CONSTANT b3_2=0X85
CONSTANT YK3=D 0 ;enter this value in decimal representation only
;*********************************************************************
CONSTANT IN_PORT=RA1

;Enter the input port used. Options


;available are RA1 RA2,RA3,RA4,RA5,RA6

CONSTANT OUT_PORT_HIGH=PORTD

;Enter the output port used for Most


;significant byte. Options available
;are PORTB, PORTC & PORTD.

CONSTANT OUT_PORT_LOW=PORTB

;Enter the output port used for


;least significant byte. Options
;available are PORTB, PORTC & PORTD.
;Do not use the same port used
;for OUT_PORT_HIGH.

CONSTANT INPUT=ADRESH

;Enter the sourec register of I/P


;samples to the filter

CONSTANT sample_freq=D'8000'

;Enter the desired sample frequency

CONSTANT clock_freq=D'20000000' ;Enter the processor clock frequency


;***********************************************************************
********
; Note:-Pins RA0-RA6 defined as analog i/p ports in this file. User can modify
; this file if any of RA's is to be used as digital i/o's
;******************************************************************************
;Following lines define the TRIS ports using the information entered by the
;user.
IF OUT_PORT_HIGH==PORTB
CONSTANT
TRIS_HIGH=TRISB
ENDIF
IF OUT_PORT_HIGH==PORTC
CONSTANT
TRIS_HIGH=TRISC
ENDIF
IF OUT_PORT_HIGH==PORTD
CONSTANT
TRIS_HIGH=TRISD
ENDIF
IF OUT_PORT_LOW==PORTB
CONSTANT TRIS_LOW=TRISB
ENDIF
IF OUT_PORT_LOW==PORTC
CONSTANT TRIS_LOW=TRISC
ENDIF
IF OUT_PORT_LOW==PORTD
CONSTANT TRIS_LOW=TRISD
ENDIF
;******************************************************************************
;Peripheral initialisation constants
;Timer1 initialisation.

;8 bit read/write enable bit


;1:1 prescale, oscillator off, clock source: internal, TMR1 off
CONSTANT TMR1_INIT=B'00000000'
;CCP module initialisation
;Compare mode, Trigger special event
CONSTANT CCP2_INIT=B'00001011'
;A/D convereter settings
;conversion clock select Fosc/32 for 20Mhz system clock
;channel user selected
;Vref+ Vdd, Vref- Vss
;conversion not started
;A/D powered on
CONSTANT ADCON0_INIT=B'10000001'
CONSTANT ADCON1_INIT=B'00000000' ;AN0-AN7 are analog i/ps.
;******************************************************************************
;***********************************************************************
*******
;Assembler variables
VARIABLE i
;******************************************************************************
UDATA_ACS 0x0
i=1
WHILE i<=NUMBER_OF_SECTIONS
buf#v(i) RES 3
;buf#v(i) stores the present input value to BIQUAD section
output#v(i)_1 RES 3 ;i, buf#v(i)+1 & buf#v(i)+2 stores previous & previous to
output#v(i)_2 RES 3 ;previous input values respectively. output#v(i)_1 stores
i+=1

;MS byte of the previous ouput value. output#v(i)_1+1 store

ENDW

;middle significant byte & output#v(i)_1+2 stores least


;significant byte of the previous output value.
;Similarly output#v(i)_2,output#v(i)_2+1 & output#v(i)_2+2
;corresponds to previous to previous output value.
;The input value for each BIQUAD section is an 8 bit
;number. Output of each BIQUAD section is a signed
;2's complement 24 bit number.

buf#v(i) RES 3

sum

RES 4

;The final output value (o/p of last BIQUAD section)


;(approximated to 8 bits) is available at this location.

;The result of multiply accumulate operation is available


;here. location sum corresponds to the most significant byte

.
;location sum+3 corresponds to least significant byte.
;Higher locations have lower significance.
;-----------------------------------------------------;user memory assignments

;-----------------------------------------------------;***********************************************************************
*******
CLEAR MACRO loc
;This macro clears consecutive 3 locations
clrf loc
;loc,loc+1 & loc+2.
clrf loc+1
clrf loc+2
ENDM
;******************************************************************************
UNSIGNXSIGN_0 MACRO x,coef,acc
;This macro multiplies unsigned value in register 'x' with the signed literal
;value 'coef'.The result is spread over the locations acc,acc+1,acc+2,acc+3. acc
;holds the most significant byte of the result, while acc+3 holds the least
;significant byte of the result. This macro is intended to be used at the
;beginning of series of multiply accumulate operations, as this macro moves
;result directly to locations acc's instead of adding to acc's after
;multiplication. To better illustrate this point consider that the value
;contained in x is A and the value of coef is B. This macro computes product AB
; and then moves the result directly to locations acc's. Had we used the macro
; UNSIGNXUNSIGN to compute the same result, we would have to clear acc's before
; using UNSIGNXUNSIGN. This macro would then compute the product and add it
;to the contents of acc's. Thus using macro UNSIGNXSIGN at the beginning of
; series of multiply accumulate operations will require more number of
;instructions. Hence a separate macro for use at the beginning of series
;of multiply accumulate operations is written.
;
;example of interpretation of values
;x--B'01000000'-represents a decimal value of 64
;coef--B'1110100001'--represents a decimal value of -(1+1/2+1/8+1/256)=-1.628906
25
;The content of acc's after execution of code in this macro is as follows.
;acc------B'11111111'\
;acc+1----B'10010111' \__Together represents a decimal value of -104.25
;acc+2----B'11000000' /
;acc+3----B'00000000'/
;acc:acc+1:acc+2:acc+3--represents H'ff97c000'
;
;-(acc_7)*2^15+(acc_6)*2^14+(acc_5)*2^13+(acc_4)*2^12+(acc_3)*2^11+(acc_2)*2^10+
;(acc_1)*2^9+(acc_0)*2^8+(acc+1_7)*2^7+(acc+1_6)*2^6+(acc+1_5)*2^5+(acc+1_4)*2^4
;+(acc+1_3)*2^3+(acc+1_2)*2^2+(acc+1_1)*2^1+(acc+1_0)*2^0+(acc+2_7)*2^(-1)
;+(acc+2_6)*2^(-2)+(acc+2_5)*2^(-3)+(acc+2_4)*2^(-4)+(acc+2_3)*2^(-5)
;+(acc+2_2)*2^(-6)+(acc+2_1)*2^(-7)+(acc+2_0)*2^(-8)+(acc+3_7)*2^(-9)
;+(acc+3_6)*2^(-10)+(acc+3_5)*2^(-11)+(acc+3_4)*2^(-12)+(acc+3_3)*2^(-13)
;+(acc+3_2)*2^(-14)+(acc+3_1)*2^(-15)+(acc+3_0)*2^(-16)=-104.25
;# instructions required
;___________________________________
;coef value
# instructions
;___________________________________
;0x0
4
;0x1
5
;0x201
6
;0x100
5
;0x300
6
;>=1
9
;0<coef<1
8
;<= -1
15
;-1<coef<0
12

;******************************************************************************
clrf acc+3

;location acc+3 initialised to zero so as to contain


;correct result.

IF coef==0
CLEAR acc
EXITM
ENDIF

;if coef value is zero the result is always zero. Hence


;all locations acc's are cleared and macro is exited.

IF coef==0x1
;coef value=1/256.
movff x,acc+2
clrf acc+1
clrf acc
EXITM
ENDIF
IF coef==0x201
movf x,W
negf WREG
movwf acc+2
setf acc+1
setf acc
EXITM
ENDIF

;coef value=-1/256
;coef being -ve and x being +ve the product is -ve.
;Hence, x is 2's complemented and stored at acc+2
;(since coef=-1/256). Since product is -ve acc+1
;& acc are sign extensions and hence set to h'ff'.

IF coef==H'100'
movff x,acc+1
clrf acc+2
clrf acc
EXITM
ENDIF

;coef value=1
;Since coef=1 the product of x & coef is
;x itself. Hence x is moved to acc+1.

IF coef==H'300'
movf x,W
negf WREG
movwf acc+1
clrf acc+2
setf acc
EXITM
ENDIF

;coefficient value=-1
;coef being -ve and x being +ve the product
;stored at acc+1 is -ve. Hence, x is 2's
;complemented and (since coef=-1). Since
;product is -ve acc is sign extension and
;hence set to h'ff'.

;all the code in this macro between IF & ENDIF statements above consider
;specific cases of coefficient values. Next part of the macro deals with
;non-specific cases of coefficients.
;If the coef is +ve and the coef value is not equal to any of the values above
;then the following macro is executed.
IF (coef & H'200') ==H'000'
movf x,W
mullw coef

;coef +ve

;This multiplication takes only the least 8 significant


;bits of the literal value coef. For example: if the
;actual value of coef is 1.83, then the product x*0.83
;is only computed here.

movff PRODL,acc+2
IF(coef & H'100') ==H'100'
addwf PRODH,W

;coef>=1. The unit value in coef is


;taken into account in these

movwf acc+1
clrf acc
rlcf acc
EXITM

;instructions. For example: if the


;actual value of coef is 1.83, then
;the result due to x*1 is
;considered here.

ENDIF
movff PRODH,acc+1
clrf acc
;If the coef is -ve and the coef value is not equal to any of the specific
;specific values above, then the following macro is executed.
ELSE
CLEAR acc
movf x,W
mullw coef

;coef -ve
;This multiplication takes only the least 8 significant
;bits of the literal value coef. For example: if the
;actual value of coef is -1.83, then the product
;x*(-0.83) is only computed here.

IF (coef & H'100')==H'100'


subwf acc+1
clrf WREG
subwfb acc
ENDIF

;coef<=1. The unit value in coef is


;taken into account in these
;instructions. For example: if the
;actual value of coef is -1.83, then
; the result due to x*(-1) is
;considered here.

movf PRODL,W
subwf acc+2
movf PRODH,W
subwfb acc+1
clrf WREG
subwfb acc
ENDIF
ENDM
;******************************************************************************
UNSIGNXSIGN MACRO x,coef,acc
;This macro multiplies unsigned value in register 'x' with the signed literal
;value 'coef'. The result is available in locations acc,acc+1,acc+2,acc+3. acc
;holds the most significant byte of the result. acc+3 holds the least
;significant byte the result. This macro is intended to be used after using the
;the macro UNSIGNXSIGN_0 at the beginning of a series of multiply accumulate
;operations.
;example of interpretation of values
;x--B'01100000'-represents a decimal value of 96
;coef--B'0110100001'--represents a decimal value of 1+1/2+1/8+1/256=1.62890625
;content of acc's before execution of code H'ff97c000'
;acc------B'11111111'
;acc+1----B'10010111'
;acc+2----B'11000000'
;acc+3----B'00000000'
;The content of acc's after execution of code in this macro is as follows.

;acc------B'00000000'\
;acc+1----B'00110100' \__Together represents a decimal value of 52.125
;acc+2----B'00100000' /
;acc+3----B'00000000'/
;acc:acc+1:acc+2:acc+3--represents H'00342000'
;
;-(acc_7)*2^15+(acc_6)*2^14+(acc_5)*2^13+(acc_4)*2^12+(acc_3)*2^11+(acc_2)*2^10+
;(acc_1)*2^9+(acc_0)*2^8+(acc+1_7)*2^7+(acc+1_6)*2^6+(acc+1_5)*2^5+(acc+1_4)*2^4
;+(acc+1_3)*2^3+(acc+1_2)*2^2+(acc+1_1)*2^1+(acc+1_0)*2^0+(acc+2_7)*2^(-1)
;+(acc+2_6)*2^(-2)+(acc+2_5)*2^(-3)+(acc+2_4)*2^(-4)+(acc+2_3)*2^(-5)
;+(acc+2_2)*2^(-6)+(acc+2_1)*2^(-7)+(acc+2_0)*2^(-8)+(acc+3_7)*2^(-9)
;+(acc+3_6)*2^(-10)+(acc+3_5)*2^(-11)+(acc+3_4)*2^(-12)+(acc+3_3)*2^(-13)
;+(acc+3_2)*2^(-14)+(acc+3_1)*2^(-15)+(acc+3_0)*2^(-16)=52.125
;# instructions required
;____________________________________
;coef value
# instructions
;____________________________________
;0
0
;0x1
5
;0x201
5
;0x100
4
;0x300
4
;>=1
11
;0<coef<1
8
;<=-1
11
;-1<coef<0
8
;******************************************************************************
IF coef==0
EXITM
ENDIF

;if coef value is zero the result is always zero. Hence


;macro is exited doing nothing.

IF coef==0x1
;coef value=1/256
movf x,W
addwf acc+2
clrf WREG
addwfc acc+1
addwfc acc
EXITM
ENDIF
IF coef==0x201
movf x,W
subwf acc+2
clrf WREG
subwfb acc+1
subwfb acc
EXITM
ENDIF

;coef value=-1/256
;coef being -ve and x being +ve the product is -ve.
;Hence result of multiplication is subtracted
;from acc's

IF coef==H'100' ;coef value=1


movf x,W
addwf acc+1
clrf WREG
addwfc acc
EXITM
ENDIF
IF coef==H'300'
movf x,W

;coef value=-1
;coef being -ve and x being +ve the product

subwf acc+1
clrf WREG
subwfb acc
EXITM

;is -ve. Hence result of multiplication is


;subtracted from acc's

ENDIF
;all the code in this macro between IF & ENDIF statements above consider
;specific cases of coefficient values. Next part of the macro deals with
;non-specific cases of coefficients.
;If the coef is +ve and the coef value is not equal to any of the specific
;values above then the following macro is executed.
IF (coef & H'200')==H'000'
movf x,W
mullw coef

;coef value +ve

;This multiplication takes only the least 8 significant


;bits of the literal value coef. For example: if the
;actual value of coef is 1.83, then the product x*0.83
;is only computed here.

IF (coef & H'100')==H'100' ;coef value>=1. The unit value in


addwf acc+1 ;coef is taken into account in these
clrf WREG
;instructions. For example: if the actual value
addwfc acc
;of coef is 1.83, then the result due to x*1 is
ENDIF
;considered here.
movf PRODL,W
addwf acc+2
movf PRODH,W
addwfc acc+1
clrf WREG
addwfc acc
;If the coef is -ve and the coef value is not equal to any of the
;specific values above, then the following macro is executed.
ELSE
movf x,W
mullw coef

;coef value -ve.


;This multiplication takes only the least 8 significant
;bits of the literal value coef. For example: if the
;actual value of coef is -1.83, then the product
;x*(-0.83) is only computed here.

IF (coef & H'100')==H'100'


subwf acc+1
clrf WREG
subwfb acc
ENDIF

movf PRODL,W
subwf acc+2
movf PRODH,W
subwfb acc+1
clrf WREG

; coef value<=1. The unit value in coef


;is taken into account in these
;instructions. For example: if the
;actual value of coef is -1.83, then
;the result due to x*(-1) is considered
;here.

subwfb acc
ENDIF
ENDM
;******************************************************************************
SIGNXSIGN MACRO x,coef,acc
;This macro multiplies signed value stored at locations x,x+1 & x+2 with the
;signed value supplied through literal constant coef. The product is subtracted
;from the value stored in locations acc, acc+1,acc+2 & acc+3. The significance
;of value stored in x's & acc's are as follows.
;location Significance
;x
Most significant byte
;x+1
Middle significant byte
;x+2
Least significant byte
;acc
;acc+3

Most significant byte Higher locations have lower significance.


Least significant byte

;example of interpretation of values


;x----B'00000000'\
;x+1--B'00110100' |----Together represents a decimal value of 52.125
;x+2--B'00100000'/
;coef--B'0110100011'--represents a decimal value of 1+1/2+1/8+1/128+1/256=1.6367
1875
;content of acc's before execution of code H'ffd7c400'
;acc------B'11111111'\
;acc+1----B'11010111' \__Together represents a decimal value of -40.234375
;acc+2----B'11000100' /
;acc+3----B'00000000'/
;The content of acc's after execution of code in this macro is as follows.
;acc------B'11111111'\
;acc+1----B'10000010' \__Together represents a decimal value of -125.54833984375
;acc+2----B'01110011' /
;acc+3----B'10100000'/
;acc:acc+1:acc+2:acc+3--represents H'ff8273a0'
;
;-(acc_7)*2^15+(acc_6)*2^14+(acc_5)*2^13+(acc_4)*2^12+(acc_3)*2^11+(acc_2)*2^10+
;(acc_1)*2^9+(acc_0)*2^8+(acc+1_7)*2^7+(acc+1_6)*2^6+(acc+1_5)*2^5+(acc+1_4)*2^4
;+(acc+1_3)*2^3+(acc+1_2)*2^2+(acc+1_1)*2^1+(acc+1_0)*2^0+(acc+2_7)*2^(-1)
;+(acc+2_6)*2^(-2)+(acc+2_5)*2^(-3)+(acc+2_4)*2^(-4)+(acc+2_3)*2^(-5)
;+(acc+2_2)*2^(-6)+(acc+2_1)*2^(-7)+(acc+2_0)*2^(-8)+(acc+3_7)*2^(-9)
;+(acc+3_6)*2^(-10)+(acc+3_5)*2^(-11)+(acc+3_4)*2^(-12)+(acc+3_3)*2^(-13)
;+(acc+3_2)*2^(-14)+(acc+3_1)*2^(-15)+(acc+3_0)*2^(-16)=52.125
;____________________________________
;coef value
# instructions
;____________________________________
;>=1
30
;0<coef<1
26
;<=-1
30
;-1<coef<0
26
;******************************************************************************
IF (coef & H'200')==H'000'
;If coef is +ve then the following code is invoked.
movf x+2,W
mullw coef ;This multiplication takes only the least 8 significa
nt
;bits of the literal value coef. For example: if the
;actual value of coef is 1.83, then the product x*0.8
3

;is only computed here.

IF (coef & H'100')==H'100' ;absolute value of coef>=1.


;The product of unit value in coef &
subwf acc+2
;content of location x+2 is taken into
clrf WREG
;account in these instructions.
subwfb acc+1
;For example: if the actual value of coef
subwfb acc
;is 1.83, then the result due to
;(content of (x+2))*1 is considered here.
ENDIF
movf PRODL,W
subwf acc+3
movf PRODH,W
subwfb acc+2
movlw coef
mulwf x+1
movf PRODH,W
subwfb acc+1
IF (coef & H'100')==H'100'
movf x,W

;absolute value of coef>=1.


;The product of unit value in
;coef & content of location x
; is taken into account with
;this instruction.
;For example: if the actual
;value of coef is 1.83, then
;then the result due to
;(content of x)*1 is
;consideredhere.

ELSE
clrf WREG
ENDIF
subwfb acc
movf PRODL,W
subwf acc+2
IF (coef & H'100')==H'000'
clrf WREG
ELSE
movf x+1,W

ENDIF
subwfb acc+1
movf x,W
mullw coef

;absolute value of coef>=1.


;The product of unit value in coef &
;content of location x+1 is taken into
;account with this instruction.
;For example: if the actual value of
;coef is 1.83, then then the result
;due to (content of x+1)*1 is considered
;here.

movf PRODH,W
subwfb acc
movf PRODL,W
subwf acc+1
clrf WREG
btfsc x,7 ;checks the sign of content of x.
movlw -coef ;correction if the x's contain -ve value.
subwfb acc
EXITM
ELSE
;If coef is -ve then the following code is invoked.
movf x+2,W
mullw coef ;This multiplication takes only the least 8 significa
nt
;bits of the literal value coef. For example: if the
;actual value of coef is -1.83, then the product
; x*(-0.83)
;is only computed here.
IF (coef & H'100')==H'100' ;absolute value of coef>=1.
addwf acc+2
;The product of unit value in coef &
clrf WREG
;content of location x+2 is taken int
o
addwfc acc+1
addwfc acc

;account in these instructions.


;For example: if the actual value of

coef
ENDIF

;is -1.83, then the result due to


;(content of (x+2))*(-1) is consider

ed here.
movf PRODL,W
addwf acc+3
movf PRODH,W
addwfc acc+2
movlw coef
mulwf x+1
movf PRODH,W
addwfc acc+1
IF (coef & H'100')==H'000'
clrf WREG
ELSE
;absolute value of coef>=1.
movf x,W ;The product of unit value in coef &
;content of location x is taken into
;account with this instruction.
;For example: if the actual value of
;coef is -1.83, then then the result
;due to (content of x)*(-1) is considered
;here.
ENDIF
addwfc acc
movf PRODL,W
addwf acc+2
IF (coef & H'100')==H'000'
clrf WREG
ELSE
;absolute value of coef>=1.

movf x+1,W

;The product of unit value in coef &


;content of location x+1 is taken into
;account with this instruction.
;For example: if the actual value of
;coef is -1.83, then then the result
;due to (content of x+1)*(-1) is considered
;here.

ENDIF

addwfc acc+1
movf x,W
mullw coef
movf PRODH,W
addwfc acc
movf PRODL,W
addwf acc+1
clrf WREG
btfsc x,7 ;checks the sign of content of x.
movlw -coef ;correction if the x's contain -ve value.
addwfc acc
ENDIF
ENDM
;******************************************************************************
BIQUAD
MACRO input,a0,a1,a2,b1,b2,output,output1,output2
;This macro implements one BIQUAD IIR filter section
;Basically it implements the equation
;y[n]=a0*x[n]+a1*x[n-1]+a2*x[n-2]-b1*y[n-1]-b2*y[n-2]
;where x's & y's refers to input & output values of
;the BIQUAD IIR filter. a0,a1,a2,b1 & b2 are filter coefficients.
;Description of arguments
;input:
memory location used to store x[n]---represent decimal values 0-255
;input+1: memory location used to store x[n-1]--represent decimal values 0-255
;input+2: memory location used to store x[n-2]--represent decimal values 0-255
;
;a0,a1,a2,b1 &b2: literal values ranging from H'0' to H'3ff'
;The literal values represent decimal values as given in Table-1
;
;output: memory location used to store most significant byte of y[n]
;output,output+1,output+2 & output+3 together store 4 byte value of y[n].
;output+3 stores least significant byte of y[n]. Higher the location lower the
;significance of the byte.
;
;ouput1: memory location used to store most significant byte of y[n-1]
;output1,output1+1,output1+2 together store 3 byte value of y[n-1].
;output1+1 stores middle significant byte of y[n-]
;output1+2 stores least significant byte of y[n-1]
;
;ouput2: memory location used to store most significant byte of y[n-2]
;output2,output2+1,output2+2 together store 3 byte value of y[n-2].
;output2+1 stores middle significant byte of y[n-2]
;output2+2 stores least significant byte of y[n-2]
;
;decimal value representation in output1's:
;decimal value=
;-output1_7*2^15+output1_6*2^14+output1_5*2^13+output1_4*2^12+output1_3*2^11+out

put1_2*2^10
;+output1_1*2^9+output1_0*2^8+(output1+1)_7*2^7+(output1+1)_6*2^6+(output1+1)_5*
2^5
;+(output1+1)_4*2^4+(output1+1)_3*2^3+(output1+1)_2*2^2+(output1+1)_1*2^1+(outpu
t1+1)_0*2^0
;(output1+2)_7*2^(-1)+(output1+2)_6*2^(-2)+(output1+2)_5*2^(-3)
;+(output1+2)_4*2^(-4)+(output1+2)_3*2^(-5)+(output1+2)_2*2^(;6)+(output1+2)_1*2^(-7)+(output1+2)_0*2^(-8)
;example: if output1's contains values as below
;output: H'ff'\
;output+1: H'd7' |--These 3 bytes together represent decimal value -40.234375
;output+2: H'c4'/
;
;representation of value in output2's is same as output1's
;
;example of output computation:
;values before execution of code in the macro
;input:---0xff--represent decimal value 255
;input+1--0x97--represent decimal value 151
;input+2--0xc0--represent decimal value 192
;a0--0x4---represent decimal value 0.015625
;a1--0x9---represent decimal value 0.03515625
;a2--0x4---represent decimal value 0.015625
;b1--0x3b0-represent decimal value -1.6875
;b2--0xd2--represent decimal value 0.8203125
;output1----0x00\
;output1+1--0x0b |---Together represent a decimal value of 11
;output1+2--0x00/
;output2----0x00\
;output2+1--0x17 |---Together represent a decimal value of 23.375
;output2+2--0x60/
;
;values in output after execution of code in the macro
;output----0x00\
;output+1--0x0b \___ Together represent a decimal value 11.6806640625
;output+2--0xae /
;output+3--0x40/
;
;decimal value representation in output's
;decimal value=
;-output_7*2^15+output_6*2^14+output_5*2^13+output_4*2^12+output_3*2^11+output_2
*2^10
;+output_1*2^9+output_0*2^8+(output+1)_7*2^7+(output+1)_6*2^6+(output+1)_5*2^5
;+(output+1)_4*2^4+(output+1)_3*2^3+(output+1)_2*2^2+(output+1)_1*2^1+(output+1)
_0*2^0
;(output+2)_7*2^(-1)+(output+2)_6*2^(-2)+(output+2)_5*2^(-3)
;+(output+2)_4*2^(-4)+(output+2)_3*2^(-5)+(output+2)_2*2^(;6)+(output+2)_1*2^(-7)+(output+2)_0*2^(-8)+(output+3)_7*2^(-9)+(output+3)_6*2^(
-10)
;+(output+3)_5*2^(-11)+(output+3)_4*2^(-12)+(output+3)_3*2^(-13)+(output+3)_2*2^
(-14)
;+(output+3)_1*2^(-15)+(output+3)_0*2^(-16)
local xa0,xa1,xa2,xb1,xb2

xa0

UNSIGNXSIGN_0 input,a0,output

xa1

UNSIGNXSIGN input+1,a1,output

;computes a0*x[n] and moves result to


;output's
;computes a1*x[n-1] and adds to

;output's
xa2

UNSIGNXSIGN input+2,a2,output

;computes a2*x[n-2] and adds to


;output's

xb1

SIGNXSIGN output1,b1,output

xb2

SIGNXSIGN output2,b2,output

;computes b1*y[n-1] and subtracts from


;output's
;computes b2*y[n-2] and subtracts from
;output's

ENDM

;******************************************************************************
TRNSFR MACRO x,y
;This macro shifts the contents of locations x,x+1 & x+2 to locations y,y+1 &
;y+2 respectively.
movf x+2,W
movwf y+2
movf x+1,W
movwf y+1
movf x,W
movwf y
ENDM
;******************************************************************************
INIT_FILTER MACRO
;Initialises the buffers used by the filter.
CLEAR buf1 ;Clears x[n]'s for first BIQUAD section.
;For BIQUAD sections other than the first the x[n]'s are initialised with
;constants Ki supplied from .inc file, at the beginning of the program.
i=2
WHILE i<=NUMBER_OF_SECTIONS
movlw K#v(i)
movwf buf#v(i)
movwf buf#v(i)+1
movwf buf#v(i)+2
i+=1
ENDW

CLEAR output1_1
CLEAR output1_2

;y[n]'s cleared for first BIQUAD section at the


;beginning of the program

;For BIQUAD sections other than the first y[n]'s are initialised with YKi's
;at the beginning of the program
i=2
WHILE i<=NUMBER_OF_SECTIONS
IF YK#v(i)>=0
movlw YK#v(i)
movwf output#v(i)_1+1
movwf output#v(i)_2+1
clrf output#v(i)_1
clrf output#v(i)_2
clrf output#v(i)_1+2

clrf output#v(i)_2+2
ELSE
movlw YK#v(i)
movwf output#v(i)_1+1
movwf output#v(i)_2+1
setf output#v(i)_1
setf output#v(i)_2
clrf output#v(i)_1+2
clrf output#v(i)_2+2
ENDIF
i+=1
ENDW
ENDM
;******************************************************************************
IIR_FILTER MACRO
;This macro implements an IIR filter in the form of BIQUAD sections connected
;in cascade. The number of BIQUAD sections used and the coefficients for each
;section are input from .inc file.
movff INPUT,buf1 ;moves sampled value to buf1 which is the
;i/p buffer for IIR filter.
i=1
WHILE i<=NUMBER_OF_SECTIONS
BIQUAD buf#v(i),a#v(i)_0,a#v(i)_1,a#v(i)_2,b#v(i)_1,b#v(i)_2,sum,outp
ut#v(i)_1,output#v(i)_2
tr#v(i)_1
TRNSFR output#v(i)_1,output#v(i)_2
tr#v(i)_2
TRNSFR sum,output#v(i)_1
movf buf#v(i)+1,W
movwf buf#v(i)+2
movf buf#v(i),W
movwf buf#v(i)+1
rlcf sum+2,W
IF i==NUMBER_OF_SECTIONS
movlw -YK#v(i)
ELSE
movlw K#v(i+1)-YK#v(i)
ENDIF
addwfc sum+1,W
movwf buf#v(i+1)
i+=1
ENDW
ENDM
;******************************************************************************
;***********************************************************************
*******
INIT_PERIPHERALS MACRO
;This macro sets up/initialises input port, output port,
;A/D converter, CCP module & Timer1.
clrf TRIS_HIGH
clrf TRIS_LOW

;clears TRIS bits in order to make


;corresponding ports as output ports.

bsf TRISA,IN_PORT

;Sets PORTA IN_PORT as input port.

;______________________________________________________________________________
;Timer1 along with CCP module is used to set sampling rate of the analog signal
;input to A/D converter.
;Timer1 initialisation.
;8 bit read/write enable bit
;1:1 prescale, oscillator off, clock source: internal, TMR1 off
movlw
movwf
clrf
clrf

TMR1_INIT
T1CON
TMR1L
TMR1H

;******************************************************************************
;Following lines compute literal values comph, compl for loading compare
;register using the information entered by the user for clock frequency &
;sampling ffequency.
comp=(clock_freq/(4*sample_freq))-1
comph=comp/D'256'
compl=comp-comph*D'256'
;******************************************************************************
;CCP module along with Timer1 is used to set sampling rate of the analog
;signal input to A/D converter.
;CCP module initialisation
;It is recommended to turn off CCP module before initialisation.
clrf CCP2CON

;Turns off CCP module.

;Compare mode, Trigger special event


movlw CCP2_INIT
movwf CCP2CON
;value loaded to CCPR2L:CCPR2H decides the sampling rate of analog signal.
;The literal values compl & comph are computed from using the entered value for
;the sampling fequency 'sample_freq' and clock frequency 'clock_freq'.
movlw
movwf
movlw
movwf

compl
CCPR2L
comph
CCPR2H

bcf
bcf

T3CON,T3CCP2
T3CON,T3CCP1

;Timer1 is used as clock source for


;CCP modules

;______________________________________________________________________________
;The external analog signal to be filtered is input to the A/D converter
;channel assigned to IN_PORT . It is to be noted that the A/D converter output i
s
;unsigned 8 bit number.
;A/D convereter settings
;conversion clock select Fosc/32 for 20Mhz system clock

;channel 1
;Vref+ Vdd, Vref- Vss
;conversion not started
;A/D powered on
i=0
WHILE i<=6
IF IN_PORT==RA#v(i)
CH=i*8
movlw ADCON0_INIT|CH
ENDIF
i+=1
ENDW
movwf ADCON0
movlw ADCON1_INIT
movwf ADCON1

;AN0,AN1 & AN3 are analog i/ps.


;Remaining digital I/O.

;Note that bit GO of ADCON0 is automatically set when Timer1 reaches value
;set in CCPR2L:CCPR2H because of special event trigger option selected in
;CCP2 module.
ENDM
;******************************************************************************
;***********************************************************************
*******
SET_INTR_FILTER MACRO
;sets up interrupt for real time operation of the filter.
bsf RCON,IPEN

;Enables interrupt priority level

clrf IPR1
bsf IPR1,ADIP
clrf IPR2

;Assign low priority for all interrupts


;except A/D converter
;interrupt.

bsf PIE1,ADIE ;Enables A/D interrupt.


bsf INTCON,GIEH ;Enables high priority interrupt.
ENDM
;******************************************************************************
CODE 0x0
rst
goto start
int_hi CODE 0x8
goto int_service_hi
int_low CODE 0x18
goto int_service_low
main

CODE

start
INIT_PERIPHERALS
;Initialises peripherals
;******************************************************************************
; user can enter code here to set interrupts he is using

;note interrupt priority is enabled & all user interrupts should be assigned
;low priority.
;******************************************************************************
SET_INTR_FILTER

;Sets interrupt settings for filter

INIT_FILTER

;Initialises filter buffers.

bsf T1CON,TMR1ON

;Now that every thing is set timer


;is switched on now to begin sampling.
;******************************************************************************
;user's code can be entered here
;******************************************************************************
goto $
int_service_hi
here

bcf PIR1,ADIF

;clears A/D interrupt flag

IIR_FILTER

;Filters the signal supplied through


;buf1.Filtered o/p (32 bit 2's
;complement) available in locations
;sum, sum+1, sum+2 & sum+3.

there

rlcf sum+2,W
movwf OUT_PORT_LOW
rlcf sum+1,W
movwf OUT_PORT_HIGH

;filtered o/p shifted left to get


;a gain of 2 and output on
;output ports

retfie FAST
;******************************************************************************
int_service_low
;Users interrrupt service routine
retfie
;******************************************************************************
END

You might also like