EE 451 - LAB 8

DTMF Detector

Part 1: Implementation of the Other Frequency Detectors

To detect DTMF signals it will be necessary to design bandpass filters and detectors for all eight frequencies which can be present in a DTMF signal. In Labs 6 and 7, you designed a bandpass filter and detector to detect on of the eight frequencies. Building bandpass filters for the other frequencies should be a simple matter of changing the bandpass filter coefficients. The detector you built for Lab 7 should work for all eight frequencies.

Implement the other bandpass filters and frequency detectors to complete your DTMF detection system. Here is a possible method to make the programming easier. Rather than repeating the code from Part 1 seven more times, the eight filters and detectors could be implemented with one code block executed eight times with a do loop. With proper ordering of the coefficients and states, it should be straightforward to do the programming. For example consider the implementation of a system to detect two frequencies. For simplicity, we will illustrate the concept with second-order filters, rather than the fourth-order filters used in the labs. Let's see how we might detect the frequencies 697 Hz and 770 Hz.

We begin by placing coefficients in the order they will be used. For the 697 Hz filter, we multiply x(n) by the gain of the 697 Hz bandpass filter, then pass it through the second-order IIR filter, then take its absolute value. Next we multiply by the gain of the low-pass filter, and finally pass the signal through the low-pass filter:

\epsfig{file=lab08_1.eps,width=6in}

This will be followed by the same procedure for the 770 Hz detector. You need to define the coefficients in the Y data space, and set aside storage for the states of each filter in the X data space.

Before starting the do loop, pointer r4 points to the gain of the 697 Hz bandpass filter, and pointer r0 points to the states (delayed values) for the 697 Hz bandpass filter. You will multiply the input sample by the gain of the 697 Hz filter, and increment r4 so it points at the first coefficient of the 697 Hz bandpass filter. After the iir7 macro has been executed, pointer r4 will point one location past the gain of the low-pass filter for the 697 Hz detector, and pointer r0 will point one location past the states of the low-pass filter for the 697 Hz detector. Decrementing the r0 and r4 pointers after the iir7 macro will set them up for the low-pass filter of the 697 Hz detector. After finishing with the low-pass filter for the 697 Hz detector, and decrementing the r0 and r4 pointers, r4 will point at the gain of the 770 Hz bandpass filter, and r0 will point at the states of the 770 Hz bandpass filter - the pointers will be ready for the next loop through the DO loop.

You should also set aside storage space to save the result of each detector, and use a pointer (such as r1) to point to the result for the current frequency.

The following will set up the storage for the coefficients and states:

       org     y:0
coef   equ     *
; Gain and coefficients for 697 Hz bandpass filter
       dc      xxxxxxxxxx     ; Gain for 697 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; a2/2 for 697 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; a1/2 for 697 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; b2/2 for 697 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; b1/2 for 697 Hz bandpass filter
; Gain and coefficients for lowpass filter for 697 Hz detector
       dc      xxxxxxxxxx     ; Gain for lowpass filter for 697 Hz detector
       dc      xxxxxxxxxx/2.0 ; a2/2 for lowpass filter for 697 Hz detector
       dc      xxxxxxxxxx/2.0 ; a1/2 for lowpass filter for 697 Hz detector
       dc      xxxxxxxxxx/2.0 ; b2/2 for lowpass filter for 697 Hz detector
       dc      xxxxxxxxxx/2.0 ; b1/2 for lowpass filter for 697 Hz detector

; Gain and coefficients for 770 Hz bandpass filter
       dc      xxxxxxxxxx     ; Gain for 770 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; a2/2 for 770 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; a1/2 for 770 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; b2/2 for 770 Hz bandpass filter
       dc      xxxxxxxxxx/2.0 ; b1/2 for 770 Hz bandpass filter
; Gain and coefficients for lowpass filter for 770 Hz detector
       dc      xxxxxxxxxx     ; Gain for lowpass filter for 770 Hz detector
       dc      xxxxxxxxxx/2.0 ; a2/2 for lowpass filter for 770 Hz detector
       dc      xxxxxxxxxx/2.0 ; a1/2 for lowpass filter for 770 Hz detector
       dc      xxxxxxxxxx/2.0 ; b2/2 for lowpass filter for 770 Hz detector
       dc      xxxxxxxxxx/2.0 ; b1/2 for lowpass filter for 770 Hz detector

       org     x:$100
; States for Filter A, 697 Hz bandpass
input  ds    1
states equ     *
       ds    2*nsec_bp   ; States for 697 Hz bandpass filter
       ds    2*nsec_lp   ; States for lowpass filter for 697 Hz detector
       ds    2*nsec_bp   ; States for 770 Hz bandpass filter
       ds    2*nsec_lp   ; States for lowpass filter for 770 Hz detector

results ds   2 ; storage for results of detectors

The following is in the program just after reading in a new sample;

;  Filter loop



; Set up pointers
; At start of first loop, they point to coefs and states of 1st filter
       move    #states,r0
       move    #coef,r4
       move    #results,r1  ; r1 -> outputs of detectors
       move    a,x:input    ; save input value -- will be used for all freqs

       do      #2,end_filter

       move    x:input,x0   ; x(n) into x0
       move    y:(r4)+,y0   ; gain of BP into y0 - r4 now points to coefs of BP
       mpy     x0,y0,a      ; g * x(n) -> a

       iir7    nsec_bp      ; output of BP -- when done, r4 -> gain of LP
                            ;                          r0 -> states of LP

       move    (r0)-        ; update r0 pointer for next filter
       move    (r4)-        ; update r4 pointer for next filter

       abs     a            ; ABS to make signal all positive

       move    a,x0         ; input to LP into x0
       move    y:(r4)+,y0   ; gain of LP into y0 - r4 now points to coefs of LP
       mpy     x0,y0,a      ; g * x(n) -> a

       iir7    nsec_lp      ; output of LP -- 
                            ; when done, r4 -> gain of BP of next freq
                            ;            r0 -> states of LP

       move    (r0)-        ; update r0 pointer for next filter
       move    (r4)-        ; update r4 pointer for next filter

       move    a,x:(r1)+    ; save output of detector; point to result for 
                            ;       next frequency
end_filter:

In Part 2 of the DTMF lab (Lab 9), you will determine what frequencies are present. After implementing all the stages, the program should check the outputs of the eight detectors. If a DTMF signal is present at the input, one of the detectors for the lower four frequencies should be asserted, and one of the detectors for the upper four frequencies should be asserted. If this is the case put out a four-bit number on bits 3-0 of Port B indicating which of the 16 keys was pressed, and put out a one on bit 4 of Port B to indicate a DTMF signal is present. If a signal other than a DTMF tone is present (at least one detector output asserted, but the detection outputs do not match any DTMF pattern) put out a one on bit 5 of Port B. If none of the detectors are asserted all bits of Port B should be low.



Bill Rison
2000-10-24