Beruflich Dokumente
Kultur Dokumente
list p=18c452
#include<p18c452.inc>
;*********************************************************************
;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
CONSTANT OUT_PORT_HIGH=PORTD
CONSTANT OUT_PORT_LOW=PORTB
CONSTANT INPUT=ADRESH
CONSTANT sample_freq=D'8000'
ENDW
buf#v(i) RES 3
sum
RES 4
.
;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
IF coef==0
CLEAR acc
EXITM
ENDIF
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
movff PRODL,acc+2
IF(coef & H'100') ==H'100'
addwf PRODH,W
movwf acc+1
clrf acc
rlcf acc
EXITM
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.
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==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
;coef value=-1
;coef being -ve and x being +ve the product
subwf acc+1
clrf WREG
subwfb acc
EXITM
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
movf PRODL,W
subwf acc+2
movf PRODH,W
subwfb acc+1
clrf WREG
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
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
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
coef
ENDIF
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
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
;output's
xa2
UNSIGNXSIGN input+2,a2,output
xb1
SIGNXSIGN output1,b1,output
xb2
SIGNXSIGN output2,b2,output
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
;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
bsf TRISA,IN_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
compl
CCPR2L
comph
CCPR2H
bcf
bcf
T3CON,T3CCP2
T3CON,T3CCP1
;______________________________________________________________________________
;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
;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
clrf IPR1
bsf IPR1,ADIP
clrf IPR2
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
INIT_FILTER
bsf T1CON,TMR1ON
bcf PIR1,ADIF
IIR_FILTER
there
rlcf sum+2,W
movwf OUT_PORT_LOW
rlcf sum+1,W
movwf OUT_PORT_HIGH
retfie FAST
;******************************************************************************
int_service_low
;Users interrrupt service routine
retfie
;******************************************************************************
END