成型滤波器定义:
频谱模板:
设计实现:
设计重要的几个指标:带内波纹<0.4dB,带外抑制>40dB,奈奎斯特频率波纹<0.4dB。
在matlab中,有面向对象设计、直接函数设计和工具箱设计的方法。这里采用filterDesigner(fdatool)进行设计。在“Response Type”选择“Raised-cosine”,“Design Method”默认选择“Window”,“Options/Window”选择“Kaiser”,“Options/Beta”填入“3.4”,“Frequency Specifications/Units”选择“Normalized(0 to 1)”,“wc”填入“0.5”,“Frequency Specifications/Rolloff”填入“0.35”,随后调整“Filter Order”直到满足频谱模板即可。
后记:
成型滤波器的设计方法有很多,Matlab也有现成的函数和工具箱如rcosfir,fdesign,filterDesigner等,只需要合理的调整设计参数就可以。
同时,在很多应用中,后面常常接内插滤波器,如半带滤波器、CIC滤波器、分数倍内插滤波器等等,也可以做多倍的内插成型滤波器。
在内插成型滤波中,采用多相结构能够有效的降低实现的资源消耗。
附:FPGA实现思路
滤波器的输出:
同时,系数满足:
因此,
在输入时,将并行的I-Q数据转换为2倍速率的串行格式,输入滤波器的示意图如下。
系数 | ... | ... | ||||||||
n | ||||||||||
n+1 | ||||||||||
n+2 |
在输出端重构,并行的I-Q数据格式。
以上,仅仅是自己写代码实现的思路。当然像Xilinx等也有相应的FIR滤波器IP核,能大大降低实现复杂度。
% 这里以16-QAM为例子,产生随机的I-Q信号,并将功率归一化。
sig = randi([0 15],1e4,1);
IQ = qammod(sig,16,'UnitAveragePower',true);
% 加载滤波器系数。
load Num.mat
Num = Num(:);
% 直接实现滤波。
IQ_out = filter(Num,1,upsample(IQ,2));
% 以多相结构实现滤波。
I_out = zeros(length(IQ),2);
Q_out = zeros(length(IQ),2);
% 模拟移位寄存器
buffer = zeros(length(Num),1);
for i=2:length(IQ)
% 输入I
buffer = [real(IQ(i));buffer(1:end-1)];
mult = buffer.*Num;
I_out(i,1) = sum(mult(1:2:end));%将奇数项求和
Q_out(i-1,2) = sum(mult(2:2:end));%将偶数项求和
% 输入Q
buffer = [imag(IQ(i));buffer(1:end-1)];
mult = buffer.*Num;
I_out(i,2) = sum(mult(2:2:end));%将偶数项求和
Q_out(i,1) = sum(mult(1:2:end));%将奇数项求和
end
% 展开为2倍内插结果
I_out = reshape(I_out',[],1);
Q_out = reshape(Q_out',[],1);
% 重新合成I-Q数据
IQ_filter_out = complex(I_out,Q_out);
% 绘制功率谱图
[p,f]=pwelch(IQ_out,hanning(1e3),20,1000,2e6,'centered','power');
plot(f,10*log10(p),'r');
hold on;
[p,f]=pwelch(IQ_filter_out,hanning(1e3),20,1000,2e6,'centered','power');
plot(f,10*log10(p),'g');
hold off;