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

Download the Model and Code here.