You are on page 1of 33

LAB 12.

FIR 필터 프로그램
Practical DSP methods
for FIR Filtering (1)
 Input-output relationship for FIR Filtering
𝐾

𝑦 𝑛 = ෍ 𝑏𝑖 𝑥 𝑛 − 𝑖
𝑖=0
= 𝑏0 𝑥 𝑛 + 𝑏1 𝑥 𝑛 − 1 + ⋯ + 𝑏𝐾 𝑥 𝑛 − 𝐾
• 𝑏𝑖 : FIR filter coefficients
• 𝐾 + 1: FIR filter length (K: FIR filter degree)

 Block processing methods


– The data are collected and processed in blocks.
– FIR filtering of finite-duration signals by convolution or
DFT/FFT.

Lab12. FIR Filtering 2


Practical DSP methods
for FIR Filtering (2)
 Sample processing methods
– The data are processed one sample at a time
– Real-time filtering of long signals

Lab12. FIR Filtering 3


Sample Processing Methods
Direct Form I/O Convolutional Equation

 𝑦 𝑛 = ℎ0 𝑥 𝑛 + ℎ1 𝑥 𝑛 − 1 + ⋯ + ℎ𝑀 𝑥 𝑛 − 𝑀
 Impulse response, 𝒉 = ℎ0 , ℎ1 , ⋯ , ℎ𝑀
 Internal states
– 𝑤0 (𝑛) = 𝑥(𝑛)
– 𝑤1 𝑛 = 𝑥 𝑛 − 1 = 𝑤0 (𝑛 − 1)
– 𝑤𝑀 𝑛 = 𝑥 𝑛 − 𝑀 = 𝑤𝑀−1 (𝑛 − 1)

 Another expression for convolution


– 𝑤0 (𝑛) = 𝑥(𝑛)
– 𝑦(𝑛) = ℎ0 𝑤0 (𝑛) + ℎ1 𝑤1 (𝑛) +··· +ℎ𝑀 𝑤𝑀 (𝑛)
– 𝑤𝑖 (𝑛 + 1) = 𝑤𝑖−1 (𝑛), for 𝑖 = 𝑀, 𝑀 − 1, . . . , 1

Lab12. FIR Filtering 4


Sample Processing Methods
Direct Form I/O Realizations (1)

 Direct form realization of 3rd order filter


– 𝑦 𝑛 = ℎ0 𝑤0 𝑛 + ℎ1 𝑤1 𝑛 + ℎ2 𝑤2 𝑛 + ℎ3 𝑤3 (𝑛)

a) Direct form realization of b) Direct form with internal


third-order filter states

Lab12. FIR Filtering 5


Sample Processing Methods
Direct Form I/O Realizations (2)

 Direct form realization of Mth order filter

Lab12. FIR Filtering 6


Sample Processing Methods
Sample Processing Algorithm

𝑤0 = 𝑥
𝑦 = ℎ0 𝑤0 + ℎ1 𝑤1 + ⋯ + ℎ𝑀 𝑤𝑀
for 𝑖 = 𝑀, 𝑀 − 1, ⋯ , 1 do:
𝑤𝑖 = 𝑤𝑖−1

Lab12. FIR Filtering 7


Sample Processing Methods
fir.c

/* fir.c - FIR filter in direct form */


double fir(M,h,w,x) // Usage: y = fir(M,h,w,x);
double *h, *w, x; // h = filter, w = state, x = input sample
int M; // M = filter order
{
int i;
double y; // output sample
w[0] = x; // read current input sample x
for (y=0, i=0; i<=M; i++)
y += h[i]*w[i]; // compute current output sample y
for (i=M; i>=1; i--) // update states for next call
w[i] = w[i-1]; // done in reverse order
return y;
}
Lab12. FIR Filtering 8
실험 내용
 FIR(Finite Impulse Response) 필터 프로그램을 작성
하여 A/D Converter로부터 입력되는 신호를 filtering
하고 그 결과를 PC로 전송하여 FIR필터의 특성을 분석
한다.

Lab12. FIR Filtering 9


실험 방법 (1)
1. 소스 코드를 입력한다.
– example 폴더의 “fir.c”를 다른 이름(fir_kim.c)으로 copy한다.
2. 컴파일하고 다운로드를 하여 DSP LAB 2000이 동작함을
확인할 수 있다.
3. Waveform generator 출력을 AUX IN단자에 입력할 것.
4. 신호처리 → 데이터 모니터링 → 2채널(trig) 모니터창을
실행하고 샘플링 주파수는 10 kHz, 데이터 개수는 512
로 설정한다.
5. Waveform Generator의 주파수를 적당히 조절하면 다
음과 같은 파형을 확인할 수 있다.

Lab12. FIR Filtering 10


실험 방법 (2)

Lab12. FIR Filtering


Source Codes (1)
#include "dsplab.h”
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include "LibDSP3x.h”
#include "LibPerip.h”
#include "LibEPP.h"

#define Data_siz Data_num*512


#define MUXCS MUX4
#define Data_num 1

Lab12. FIR Filtering 12


Source Codes (2)

#define Da_Sel 5
#define Timer 1250
#define Order 40

float X[Order]; // Order: filter length


float Y;
float BCOEF[] = {
0.00003914842612,
-0.00071038903780,
-0.00192936054457,
-0.00246973598032,
-0.00056474350858,
0.00427544146656,
Lab12. FIR Filtering 13
Source Codes (3)
0.00926301361605,
0.00966506680194,
0.00406011600643,
-0.00168815773163,
0.00158904137510,
0.01510410283974,
0.02453157404196,
0.00797627727317,
-0.04219388780326,
-0.10235191543514,
-0.12593923521624,
-0.07754279821035,
0.03283116693649,

Lab12. FIR Filtering 14


Source Codes (4)
0.14697378811015,
0.19531250000001,
0.14697378811015,
0.03283116693649,
-0.07754279821035,
-0.12593923521624,
-0.10235191543514,
-0.04219388780326,
0.00797627727318,
0.02453157404197,
0.01510410283975,
0.00158904137511,
-0.00168815773163,

Lab12. FIR Filtering 15


Source Codes (5)
0.00406011600642,
0.00966506680193,
0.00926301361604,
0.00427544146655,
-0.00056474350858,
-0.00246973598032,
-0.00192936054457,
-0.00071038903780
};

Lab12. FIR Filtering 16


Source Codes (6)
/* set timer 0/1 for frequency */
void Set_Timer(int timer0, int timer1)
{
*Timer0_GCR = 0x02c0;
*Timer0_PR = timer0;
*Timer1_GCR = 0x02c0;
*Timer1_PR = timer1;
}

void c_int09() /* timer 0 interrupt service routine */


{
asm(" xor 01000100b, IOF "); /* If LED blink, DSP is
working */
}

Lab12. FIR Filtering 17


Source Codes (7)
int Idata[Data_siz], Odata[Data_siz];
int IOcount=0;
int *DA_MUX;

void c_int10() /* timer 1 interrupt service routine */


{
int ADdata,i;
float temp_cal;
if(IOcount != Data_siz){
ADdata = *ADC_CS;
ADdata += 0x0800;
ADdata &= 0x0fff;
ADdata -= 0x0800;

Lab12. FIR Filtering 18


Source Codes (8)
X[0] = (float)ADdata;
ADdata = 0;
temp_cal =0.0;
for(i=0;i<Order;i++)
temp_cal += (BCOEF[i]*X[i]);

Y = temp_cal;
ADdata=(int)temp_cal;
for(i=0;i<Order-1;i++)
X[Order-(i+1)] = X[Order-(i+2)];

Lab12. FIR Filtering 19


Source Codes (9)
if (Da_Sel==5) {
data[IOcount] = ((int)X[1]+0x800) ;
Odata[IOcount] = ((int)Y+0x800);
IOcount++;
}
else {
ADdata+=0x800;
if (ADdata>0xfff) ADdata = 0x0fff;
*DA_MUX=ADdata;
IOcount = IOcount;
}
*ADC_RC = 0;

Lab12. FIR Filtering 20


Source Codes (10)
}
}

asm(" .sect \".vector\" ");


asm(" .space 8 ");
asm(" BR _c_int09 ");
asm(" BR _c_int10 ");

Lab12. FIR Filtering 21


Source Codes (11)
void main()
{
int i, Timer0=1250000, Timer1;

Init_DSP(); /* Initialize DSP Processor */


Init_8255(); /* Initialize 8255PPI */
Delay_ms(10);
Init_LCD(); /* Initialize LCD */
LCD_string(LCD_Line1," DSP LAB 2000 ");
LCD_string(LCD_Line2," FIR Filter ");

for(i=0;i<Order;i++)
X[i] = 0;

Lab12. FIR Filtering 22


Source Codes (11)
*MUX_CS = MUXCS; /* Select Input Source */
DA_MUX=DAC0 + Da_Sel;
Timer1=Timer;
Set_Timer(Timer0,Timer1); /* Initialize Timer */

asm(" OR 2000H,ST ");


asm(" LDI 0300H,IE ");
asm(" LDI 01100110b, IOF ");

while(1){
if(Da_Sel==5) {
if(IOcount == Data_siz){
asm(" LDI 0000h, IE "); //Disable Interrupt

Lab12. FIR Filtering 23


Source Codes (12)
/* Reinitialize Primary Bus control Register for EPP
communication */
asm(" LDI @_Pbus_control,AR0 ");
asm(" LDI 00B8H,R0 ");
asm(" STI R0,*AR0 ");
asm(" NOP ");
asm(" NOP ");
asm(" NOP ");

for(i=0;i<Data_siz;i++) //Send Input data


Send16(Idata[i] | 0xE000);
for(i=0;i<Data_siz;i++) //Send Output data
Send16(Odata[i] | 0x1000);

Lab12. FIR Filtering 24


Source Codes (13)
asm(" LDI 0300h, IE ");
// Reinitialize Primary Bus Control Register for Data Process
asm(" LDI @_Pbus_control,AR0 ");
asm(" LDI 00B0H,R0 ");
asm(" STI R0,*AR0 ");
asm(" NOP ");
asm(" NOP ");
asm(" NOP ");

IOcount = 0; // Initialize sampling data counter


}
}

Lab12. FIR Filtering 25


Source Codes (14)
else
{
Delay_ms(100);
}
}
}

Lab12. FIR Filtering 26


소스코드설명
선언문 (1)

#define Data_siz Data_num*512


#define MUXCS MUX4
#define Data_num 1
#define Da_Sel 5 ---------------------------------------------- ①
#define Timer 1250
#define Order 40 ---------------------------------------------- ②
float X[Order];
float Y;
float BCOEF[] = { --------------------------------------------- ③
0.00003914842612,
-0.00071038903780,
-0.00192936054457,
-0.00246973598032,

Lab12. FIR Filtering 27


소스코드설명
선언문 (2)

-0.00056474350858,
.
.
}

① Da_Sel은 출력을 결정한다.


– DAC0, DAC1, DAC2, DAC3 각각은 SPEAKER OUT, OPTION 1,
OPTION 2, AUX OUT이며 Da_Sel은 이런 D/A 컨버터의 각 채널
의 주소 편차로 지정된다.
– DA_MUX 선언시에 DAC0+Da_Sel을 입력함으로써 각각의 채널
을 선택할 수 있도록 했다.
• Da_Sel이 0일 때 DAC0, 1과 2일 때 각각 OPTION 1, OPTION 2, 3일
때 AUX OUT을 나타내며 5일 때는 PC입력으로 설정하였다.

Lab12. FIR Filtering 28


소스코드설명
선언문 (3)

– A/D Converter 출력데이터는 필터 루틴을 거친 후 Data_siz 만큼


을 PC에 전송하게 된다.
② Order는 FIR 필터의 차수가 아닌, 필터길이를 나타낸다.
③ BCOEF[] 배열은 FIR 필터계수이다.

Lab12. FIR Filtering 29


소스코드설명
Sampling (1)

void c_int10() /* timer 1 interrupt service routine */


{
int ADdata,i;
float temp_cal;
if(IOcount != Data_siz){
ADdata=*ADC_CS; // ADC 출력, 2’s complement
ADdata+=0x0800;
ADdata&=0x0fff;
ADdata-=0x0800;
X[0]=(float)ADdata; // 새로 읽은 ADC 출력 표본
ADdata=0;
temp_cal=0.0;

Lab12. FIR Filtering 30


소스코드설명
Sampling (2)

/* ADC를 통해 입력된 입력 sequence를 digital filtering 함. */


for(i=0;i<Order;i++)
temp_cal+=(BCOEF[i]*X[i]);

Y=temp_cal;
ADdata=(int)temp_cal; // digital filter 출력
/* 다음 입력표본을 위해 입력 시퀀스를 한 sample delay 시킴 */
for(i=0;i<Order-1;i++)
X[Order-(i+1)]=X[Order-(i+2)];
/* 필터입력 시퀀스와 필터출력 시퀀스를 PC로 전송, Da_Sel=5 */
if (Da_Sel==5) {
Idata[IOcount]=((int)X[1]+0x800) ;
Odata[IOcount]=((int)Y+0x800);

Lab12. FIR Filtering 31


소스코드설명
Sampling (3)

IOcount++;
}
/* PC 전송이 아닌 경우의 처리 루틴 */
else {
ADdata+=0x800;
if (ADdata>0xfff) ADdata=0x0fff;
*DA_MUX=ADdata;//DA_MUX에서 지정한 DAC로 출력
IOcount=IOcount;
}
*ADC_RC=0;
}
}

Lab12. FIR Filtering 32


소스코드설명
main()

for(i=0;i<Data_siz;i++) //Send Input data


Send16(Idata[i] | 0xE000); ------------------- ①
for(i=0;i<Data_siz;i++) //Send Output data
Send16(Odata[i] | 0x1000); ------------------ ②

①, ② PC에 데이터 전송, 16비트로 전송하며 채널1은 0XE000, 채


널2는 0X1000, 채널3은 0X2000, 채널4는 0X3000, 채널5는 0X4000
으로 구성되어있다.

Lab12. FIR Filtering 33

You might also like