IIR 低通滤波器设计:使用 C 语言和汇编语言实现
利用 C 语言和汇编语言设计实现 IIR 低通滤波器
本文将介绍如何使用 C 语言和汇编语言设计并实现一个 IIR 低通滤波器,以滤除高频噪声,保留信息信号。
设计要求:
- 信息信号:'signal = sin(2pislnT)'
- 高频噪声:'noise = 0.5sin(2pins1n*T)'
- 混合信号:'x = (signal + noise)'
其中:
- sl = 1000Hz
- ns1 = 4500Hz
- 采样频率为 10000Hz
- T = 1/10000
混合信号波形作为滤波器输入信号波形,信息信号波形作为输出信号波形。
设计流程:
-
确定滤波器的截止频率。 由于信息信号的频率为 1000Hz,而高频噪声的频率为 4500Hz,因此选择截止频率为 2000Hz,以确保能够滤除高频噪声。
-
选择合适的滤波器类型。 由于要设计低通滤波器,因此选择 Butterworth 滤波器,因为它具有平坦的通带和陡峭的阻带,能够有效滤除高频噪声。
-
确定滤波器的阶数。 选择二阶滤波器,因为它具有良好的性能和较少的计算量。
-
计算滤波器的系数。 利用 Matlab 等工具计算滤波器的系数,得到如下二阶 IIR 低通滤波器的系数:
- b0 = 0.001950231683839
- b1 = 0.003900463367678
- b2 = 0.001950231683839
- a1 = -1.911937747195649
- a2 = 0.914975880767064
-
编写 C 语言和汇编程序。 将滤波器的系数写入程序中,读入混合信号 x,利用二阶 IIR 滤波器进行滤波,得到输出信号 y,输出 y 即为信息信号的波形。
C 语言程序:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.141592653589793
float b[3] = {0.001950231683839, 0.003900463367678, 0.001950231683839};
float a[3] = {1.000000000000000, -1.911937747195649, 0.914975880767064};
float x[3] = {0.0, 0.0, 0.0};
float y[3] = {0.0, 0.0, 0.0};
float signal(float n)
{
float sl = 1000.0;
float T = 1.0 / 10000.0;
return sin(2.0 * PI * sl * n * T);
}
float noise(float n)
{
float ns1 = 4500.0;
float T = 1.0 / 10000.0;
return 0.5 * sin(2.0 * PI * ns1 * n * T);
}
float filter(float xin)
{
float yout = b[0] * xin + b[1] * x[1] + b[2] * x[0] - a[1] * y[1] - a[2] * y[0];
x[0] = x[1];
x[1] = xin;
y[0] = y[1];
y[1] = yout;
return yout;
}
int main()
{
float T = 1.0 / 10000.0;
int nsamples = 10000;
float n = 0.0;
for (int i = 0; i < nsamples; i++)
{
float s = signal(n);
float n = noise(n);
float xin = s + n;
float yout = filter(xin);
printf("%f\n", yout);
n += T;
}
return 0;
}
汇编程序:
.model small
.stack 100h
.data
b0 dw 0.001950231683839 * 32768
b1 dw 0.003900463367678 * 32768
b2 dw 0.001950231683839 * 32768
a1 dw -1.911937747195649 * 32768
a2 dw 0.914975880767064 * 32768
x dw 0, 0, 0
y dw 0, 0, 0
.code
start:
mov ax, @data
mov ds, ax
mov es, ax
mov cx, 10000
mov dx, 0
mov si, 0
mov bx, 0
loop1:
call signal
mov bx, ax
call noise
add ax, bx
call filter
mov bx, ax
mov ah, 4ch
int 21h
signal:
push ax
push bx
push cx
push dx
push si
push di
mov si, dx
mov ax, si
mov bx, 1000
mul bx
mov bx, ax
mov ax, 0
mov cx, 0
mov dx, 0
mov si, 0
mov di, 0
mov ax, bx
mov bx, 0
mov cx, 10000
div cx
mov cx, ax
mov ax, bx
mov dx, 0
fld PI
fmul ax
fmul 2.0
fsin
fstp ax
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
noise:
push ax
push bx
push cx
push dx
push si
push di
mov si, dx
mov ax, si
mov bx, 4500
mul bx
mov bx, ax
mov ax, 0
mov cx, 0
mov dx, 0
mov si, 0
mov di, 0
mov ax, bx
mov bx, 0
mov cx, 10000
div cx
mov cx, ax
mov ax, bx
mov dx, 0
fld PI
fmul ax
fmul 2.0
fsin
fmul 0.5
fmul 32768.0
fistp ax
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
filter:
push ax
push bx
push cx
push dx
push si
push di
mov si, dx
mov ax, si
mov bx, [x + 2]
mov [x], bx
mov bx, [x + 2]
mov [x + 1], bx
mov bx, ax
mov [x + 2], bx
mov bx, [y + 2]
mov [y], bx
mov bx, [y + 2]
mov [y + 1], bx
mov bx, ax
mov dx, [b0]
imul dx
mov bx, [x + 2]
imul bx
mov cx, [b1]
imul cx
add dx, cx
mov bx, [x]
imul bx
mov cx, [b2]
imul cx
add dx, cx
mov bx, [y + 2]
imul bx
mov cx, [a1]
imul cx
sub dx, cx
mov bx, [y]
imul bx
mov cx, [a2]
imul cx
sub dx, cx
sar dx, 15
mov ax, dx
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
end start
通过以上步骤,即可设计并实现一个 IIR 低通滤波器,有效滤除高频噪声,保留信息信号。
原文地址: https://www.cveoy.top/t/topic/oPKj 著作权归作者所有。请勿转载和采集!