FIR LOW Pass FIlter with Keypad and LCD
Enter the Filter CO-Efficients by keypad, view in LCD, then execute.
The Assembly Code:
;adc 0808 interfacing with atmel 89c51 uc
;wait till conversion is done
;define adc pins connected to the pins of microcontroller
;filter coefficients
;k0 equ 21
;k1 equ 27
;k2 equ 115
;k3 equ 27
;k4 equ 21
ADC_A BIT P2.0 ;column1 for keypad
ADC_B BIT P2.1 ;column2 for keypad
ADC_C BIT P2.2 ;column3 for keypad
ADC_SC BIT P2.3 ;column4 for keypad
ADC_ALE BIT P2.4 ;row4 for keypad
ADC_OE BIT P2.5 ;row3 for keypad
ADC_EOC BIT P2.6 ;row2 for keypad
RS BIT P3.0
EN BIT P3.2
COLUMN1 BIT P3.3
COLUMN2 BIT P3.4
COLUMN3 BIT P3.5
ROW4 BIT P2.3
ROW3 BIT P2.4
ROW2 BIT P2.5
ROW1 BIT P2.7
;define input and o/p ports
MYDATA EQU P1
OUT_D EQU P0
.ORG 0000H ;set start address to 0000h
AJMP MAIN ;jump to main program
L1: ;subroutine to off the lcd
MOV A, #08H
LCALL COMMAND
LJMP OVER
L2: ;subroutine to type '1'
MOV A, #'1'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY2
L3: ;subroutine to type '4'
MOV A, #'4'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY3
L4: ;subroutine to type '7'
MOV A, #'7'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY4
L5: ;subroutine to type '0'
MOV A, #'0'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY5
L6: ;subroutine to type '2'
MOV A, #'2'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY6
L7: ;subroutine to type '5'
MOV A, #'5'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY7
L8: ;subroutine to type '8'
MOV A, #'8'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY8
L9: ;subroutine to enter 1 coefficient
MOV A, #01H
LCALL COMMAND
LCALL COMPUTE
LJMP ANOTHER
L10: ;subroutine to type '3'
MOV A, #'3'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY10
L11: ;subroutine to type '6'
MOV A, #'6'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY11
L12: ;subroutine to type '9'
MOV A, #'9'
MOV @R0, A
INC R0
LCALL LCD_DATA
LCALL DELAY_HALFSEC
LJMP KEY12
MAIN: ;main program
LCALL INITIALISE_LCD ;call initialise lcd
MOV R7, #31H
MOV R1, #60H
ANOTHER: MOV R0, #70H
LCALL INSTRUCTION
ACALL KEYPAD
LJMP SAMPLING
;keypad programming to enter filter coefficients
KEYPAD:
CLR P3.3 ;clear 1st column
JNB P2.3, L1_1 ;check if 'e' pressed
KEY1: JNB P2.4, L2_1 ;check if '1' pressed
KEY2: JNB P2.5, L3_1 ;check if '4' pressed
KEY3: JNB P2.7, L4_1 ;check if '7' pressed
KEY4: SETB P3.3 ;if no key is pressed in column 1 rhen set 1st column
CLR P3.4 ;clear 2nd column
JNB P2.3, L5_1 ;check if '0' pressed
KEY5: JNB P2.4, L6_1 ;check if '2' pressed
KEY6: JNB P2.5, L7_1 ;check if '5' pressed
KEY7: JNB P2.7, L8_1 ;check if '8' pressed
KEY8: SETB P3.4 ;if no key is pressed in column 2 rhen set 2nd column
CLR P3.5 ;clear 3rd column
JNB P2.3, L9_1 ;check if 'enter' pressed
KEY9: JNB P2.4, L10_1 ;check if '3' pressed
KEY10: JNB P2.5, L11_1 ;check if '6' pressed
KEY11: JNB P2.7, L12_1 ;check if '9' pressed
KEY12: SETB P3.5 ;if no key is pressed in column 3 rhen set 3rd column
LJMP KEYPAD
OVER: RET
L1_1: ;subroutine to call l1 to show all coefficients entered
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.3, KEY1
LJMP L1
L2_1: ;subroutine to call l2 to display '1'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.4, KEY2
LJMP L2
L3_1: ;subroutine to call b3 to display '4'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.5, KEY3
LJMP L3
L4_1: ;subroutine to call b4 to display '7'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.7, KEY4
LJMP L4
L5_1: ;subroutine to call b5 to display '0'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.3, KEY5
LJMP L5
L6_1: ;subroutine to call b6 to display '2'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.4, KEY6
LJMP L6
L7_1: ;subroutine to call b7 to display '5'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.5, KEY7
LJMP L7
L8_1: ;subroutine to call b8 to display '8'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.7, KEY8
LJMP L8
L9_1: ;subroutine to call b9 to display 'f'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.3, KEY9
LJMP L9
L10_1: ;subroutine to call b10 to display '3'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.4, KEY10
LJMP L10
L11_1: ;subroutine to call b11 to display '6'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.5, KEY11
LJMP L11
L12_1: ;subroutine to call b12 to display '9'
LCALL DEBOUNCE_DELAY ;avoid repeatition of no. when key is presed for a long time
JNB P2.7, KEY12
LJMP L12
COMPUTE:
MOV R0, #70H
MOV A, @R0
ANL A, #0FH
MOV B, #100
MUL AB
MOV @R1, A
INC R0
MOV A, @R0
ANL A, #0FH
MOV B, #10
MUL AB
ADD A, @R1
MOV @R1, A
INC R0
MOV A, @R0
ANL A, #0FH
ADD A, @R1
MOV @R1, A
INC R1
RET
INITIALISE_LCD: ;initialise lcd
MOV A, #38H ;two lines 5x8 matrix
LCALL COMMAND ;call command subroutine
MOV A, #0CH ;display on, cursor off
LCALL COMMAND ;call command subroutine
MOV A, 06H ;increment cursor(shift cursor to right)
LCALL COMMAND ;call command subroutine
RET ;return to main program
INSTRUCTION:
MOV A, #'F' ;to display 'fc' means filter coefficients
LCALL LCD_DATA
MOV A, #'C'
LCALL LCD_DATA ;to display filter coefficient no.
MOV A, R7
LCALL LCD_DATA
MOV A, #':'
LCALL LCD_DATA
INC R7
RET
COMMAND: ;command subroutine to write command to lcd
CLR P3.0 ;register select bit cleared to choose command register
MOV OUT_D, A ;port 0 acts as input to lcd
SETB P3.2 ;enable pin high to low for write operation
CLR P3.2
LCALL DELAY
RET ;return to main program
LCD_DATA: ;data subroutine to write data to lcd
SETB P3.0 ;register select bit set high to choose data register
MOV OUT_D, A ;port 0 acts as input to lcd
SETB P3.2 ;enable pin high to low for write operation
CLR P3.2
LCALL DELAY
RET ;return to main program
DELAY_HALFSEC: ;to give delay of .5second using timer0 in mode 1
MOV TMOD, #01H
MOV R4, #7
AGAIN: MOV TH0, #00H
MOV TL0, #00H
SETB TR0
JNB TF0, $
CLR TF0
CLR TR0
DJNZ R4, AGAIN
RET
DEBOUNCE_DELAY: ;to give delay of .2844 second using timer1 in mode1
MOV TMOD, #10H
MOV R6, #4
BACK: MOV TH1, #00H
MOV TL1, #00H
SETB TR1
JNB TF1, $
CLR TF1
CLR TR1
DJNZ R6, BACK
RET
DELAY: ;to give lcd some time to write
MOV R5, #0A0H
S2: MOV R3, #0FFH
S1: DJNZ R3, S1
DJNZ R5, S2
RET
;initialize these registers for storing partial products
SAMPLING:
MOV R0, #00H
MOV R1, #00H
MOV R2, #00H
MOV R3, #00H
MOV R4, #00H
;temporary storage for msb and lsb of partial products
MOV R6, #00H
MOV R7, #00H
GET_ADC_DATA:
MOV MYDATA, #0FFH ;define mydata as input port
;mov out_d,#00h ;set port 0 as o/p port
;mov p3,#00h ;;set port 3 as o/p port
SETB ADC_EOC
CLR ADC_OE
CLR ADC_ALE
CLR ADC_SC
CLR ADC_A
CLR ADC_B
CLR ADC_C
SETB ADC_ALE
SETB ADC_SC
CLR ADC_ALE
CLR ADC_SC
WAIT1: JNB ADC_EOC, WAIT1 ;wait till conversion is complete
SETB ADC_OE ;enable the output port of adc
NOP
MOV A, P1 ;move converted data from adc to accumulator
MOV P3, A ;move the unfiltered signal to port 3
;nop
CLR ADC_OE
SETB ADC_EOC
FILTER:
MOV R0, A
MOV B, 60H
MUL AB
MOV R7, A
MOV R6, B
MOV A, R1
MOV B, 61H
MUL AB
ADD A, R7
MOV R7, A
MOV A, B
ADDC A, R6
MOV R6, A
MOV A, R2
MOV B, 62H
MUL AB
ADD A, R7
MOV R7, A
MOV A, B
ADDC A, R6
MOV R6, A
MOV A, R3
MOV B, 63H
MUL AB
ADD A, R7
MOV R7, A
MOV A, B
ADDC A, R6
MOV R6, A
MOV A, R4
MOV B, 64H
MUL AB
ADD A, R7
MOV A, B
ADDC A, R6
MOV OUT_D, A
;nop
SHIFT_ADC_DATAS:
MOV A, R3
MOV R4, A
MOV A, R2
MOV R3, A
MOV A, R1
MOV R2, A
MOV A, R0
MOV R1, A
AJMP GET_ADC_DATA
END ;end of main program