Bootstrap

DSP之汇编实现用FIR滤波器将方波变为正弦波

1、基本原理

FIR滤波器:

      FIR滤波器是一种数字滤波器,其名称代表了其特性——有限脉冲响应(Finite Impulse Response)。它的特点是其响应是有限长度的,不会无限延长。FIR滤波器通过一系列加权的输入信号来产生输出信号,其中每个输入信号都有一个对应的加权系数。这些加权系数决定了滤波器的频率响应。

     FIR滤波器的冲激响应h(n)只有N个点有值,这N个值称为滤波器的系数。滤波器的输出Y(n)只与当前的输入x(n)和有限个过去的输入x(n-1),X(n-2),…X(n-(N-1))有关,其表达式为:

Y(n)=h(O)X(n)+h(1)X(n-1)+h(2)X(n-2)+h(N-1)x(n-(N-1))

和此表达式对应的实现结构可用图2-1来表示。

2、MATLAB仿真

MATLAB仿真FIR:

% 生成方波信号
Fs = 1000; % 采样频率
T = 1/Fs; % 采样周期
t = 0:T:1-T; % 时间向量
f = 10; % 方波频率
x = square(2*pi*f*t); % 生成方波信号

% 设计FIR滤波器
N = 101; % 滤波器阶数
fc = 20; % 截止频率
b = fir1(N, fc/(Fs/2)); % 设计FIR滤波器

% 输出滤波器系数
disp('FIR滤波器系数:');
disp(b);

% 应用滤波器
y = filter(b, 1, x);

% 绘制结果
subplot(2,1,1);
plot(t, x);
title('Square Wave');
xlabel('Time (s)');
ylabel('Amplitude');
subplot(2,1,2);
plot(t, y);
title('Filtered Wave');
xlabel('Time (s)');
ylabel('Amplitude');

  MATLAB仿真IIR:

% 生成方波信号
Fs = 1000; % 采样率
t = 0:1/Fs:1; % 时间向量
f_square = 10; % 方波频率
square_wave = square(2*pi*f_square*t); % 生成方波信号

% 设计IIR滤波器
[b, a] = butter(4, 2*f_square/Fs, 'low'); 

% 对方波信号进行滤波
filtered_signal = filter(b, a, square_wave);

% 绘制结果
figure;
subplot(2,1,1);
plot(t, square_wave);
title('Square Wave Signal');
xlabel('Time (s)');
ylabel('Amplitude');

subplot(2,1,2);
plot(t, filtered_signal);
title('Filtered Signal (Sinusoidal)');
xlabel('Time (s)');
ylabel('Amplitude');

仿真结果:

求得滤波器系数 :

第二步设计一个FIR滤波器把方波变成正弦波。 

3、流程图

首先我们在 RAM区设置两组连续的存储区,一组存放采样数据,-组存放滤波器系数,如图2-2所示。在初始化时,存放采样数据的存储区先清零。系数存储区存放的滤波器的系数在matlab的仿真环境中求得,通过修改截止频率、阻带最小衰减以及窗函数来修正截止频率,以达到最好的滤波效果。

 其次,用汇编语言设计一个FIR滤波器把方波变成正弦波。具体流程图如下:

 4、汇编实现

fir.asm:

	.global _c_int00
			.bss x,1024  ;设置未初始化段
			.bss y,1024  ;设置未初始化段在flash里面
			.sect "coff_tab"
fir_tab:	.word -2,-8,-15,-20,-16,6,52,126,229,357,501,649,786,896,969,994,969,896,786,649,501,357,229,126 ,52,6,-16,-20,-15,-8,-2
fir1_tab	.usect "fir2_tab",512  ;设置已初始化段
fir1_dat	.usect "fir2_dat",512  ;设置已初始化段(滤波的数据)
			.text
_c_int00:
			MVK .S1 x,A0
			MVK .S1 1,A1
			MVK .S1 -1,A2
			MVK .S2 8,B0
			MVKL .S2 0X00000000,B1 ;清零AMR
			MVKH .S2 0X00000000,B1
			MVC .S2 B1,AMR
			NOP 5
LOOP1:
			MVK .S2 16,B1    ;取B1作为计数的寄存器
			NOP 5
LOOP2:
			STW .D1 A1,*A0++
			NOP 5
			SUB .L2 B1,1,B1
			NOP 5
		[B1]B LOOP2
			NOP 5
			MVK .S2 16,B1
			NOP 5
LOOP3:
			STW .D1 A2,*A0++
			NOP 5
			SUB .L2 B1,1,B1
			NOP 5
		[B1]B LOOP3
			NOP 5
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP1  ;32个点一个周期(16个点变化一次),共8个周期。
			NOP 5
			MVK .S1 fir_tab,A3 ;将未初始化段送至内存
			MVK .S1 fir1_tab,A4
			MVK .S1 fir1_dat,A5
			MVK .S2 128,B0
			NOP 5
LOOP4:           ;填充
			LDW .D1 *A3++,A6
			NOP 5
			STW .D1 A6,*A4++
			NOP 5
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP4
			NOP 5
			MVK .S2 51,B0
			NOP 5
LOOP5:
			LDW .D1 *A3--,A6
			NOP 5
			STW .D1 A6,*A4++
			NOP 5
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP5
			NOP 5
			ZERO A0
			MVK .S2 27,B0
			NOP 5
LOOP6:
			STW .D1 A2,*A5++
			NOP 5
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP6
			NOP 5
			MVK .S2 50,B0
			NOP 5
LOOP7:
			STW .D1 A2,*A4++
			NOP 5
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP7
			NOP 5
			MVK .S1 x,A0           ;填充结束
			MVK .S1 y,A1
			MVK .S1 fir1_tab,A4
			MVK .S1 fir1_dat,A5
			MVKL .S2 0X00080005,B1
			MVKH .S2 0X00080005,B1 ;循环寻址取A4和A5
			MVC .S2 B1,AMR
			MVK .S2 256,B0
			NOP 5
LOOP8:
			LDW .D1 *A0++,A2
			NOP 5
			STW .D1 A2,*--A5
			NOP 5
			MVK .S2 128,B1
			NOP 5
LOOP:   ;循环进行乘累加
			LDW .D1 *A4++,A9
			NOP 5
			LDW .D1 *A5++,A10
			NOP 5
			MPY .M A9,A10,A11
			NOP 5
			ADD .L1 A3,A11,A3  ;A3中存放卷积结果(疑问:A3先前是否清零)
			NOP 5
			SUB .L2 B1,1,B1
			NOP 5
		[B1]B LOOP  ;LOOP1
			NOP 5
			STW .D1 A3,*A1++ ;将乘累加的值放在y里面取
			SUB .L2 B0,1,B0
			NOP 5
		[B0]B LOOP8
			NOP 5
			.end

fir.cmd

fir.obj
-o fir.out
MEMORY//给存储器分成两部分
{
 		PAGE 0: ROM: ORIGIN=00000010H, LENGTH=1000H
         		ROM1: ORIGIN=00002300H, LENGTH=500H
 		PAGE 1: DARAM:  ORIGIN=00003000H, LENGTH=2000H
    	 		RAM1:   ORIGIN=00006000H, LENGTH=200H
    	 		RAM2:   ORIGIN=00007000H, LENGTH=1000H
}
SECTIONS//将不同的区分配到不同的段里
{
.text  :>ROM   PAGE 0
.bss   :>DARAM     PAGE 1
coff_tab  :>ROM1   PAGE 0
fir2_tab   :>RAM2   PAGE 1
fir2_dat   :>RAM2   PAGE 1
}

5、运行结果

寄存器中x的值:

寄存器中y的值:

方波仿真图:

正弦波仿真图

;