В этом примере показано, как спроектировать КИХ-фильтры lowpass. Многие концепции, представленные здесь, могут быть расширены к другим ответам, таким как highpass, полоса пропускания, и т.д.
КИХ-фильтры широко используются из-за мощных алгоритмов проекта, которые существуют для них, их свойственная устойчивость, когда реализовано в нерекурсивной форме, простоте, с которой может достигнуть линейной фазы, их простой расширяемости к многоскоростным случаям и вполне достаточной аппаратной поддержки, которая существует для них среди других причин. Этот пример демонстрирует функциональность в DSP System Toolbox™ для проекта КИХ-фильтров lowpass со множеством характеристик.
Создание фильтра lowpass в MATLAB предоставляет обзор разработки фильтров lowpass с DSP System Toolbox. Подводя итоги, две функции представлены, которые возвращают вектор из КИХ-коэффициентов фильтра: firceqrip
и firgr
. firceqrip
используется, когда порядок фильтра (эквивалентно длина фильтра) известен и фиксируется.
N = 100; % FIR filter order Fp = 20e3; % 20 kHz passband-edge frequency Fs = 96e3; % 96 kHz sampling frequency Rp = 0.00057565; % Corresponds to 0.01 dB peak-to-peak ripple Rst = 1e-4; % Corresponds to 80 dB stopband attenuation eqnum = firceqrip(N,Fp/(Fs/2),[Rp Rst],'passedge'); % eqnum = vec of coeffs fvtool(eqnum,'Fs',Fs,'Color','White') % Visualize filter
Выбор порядка фильтра 100 был произволен. В общем случае больший порядок приводит к лучшему приближению к идеалу за счет более дорогостоящей реализации. Удвоение порядка примерно уменьшает ширину перехода фильтра в половине (принимающий, что все другие параметры остаются то же самое).
N2 = 200; % Change filter order from 100 to 200 eqNum200 = firceqrip(N2,Fp/(Fs/2),[Rp Rst],'passedge'); fvt = fvtool(eqnum,1,eqNum200,1,'Fs',Fs,'Color','White'); legend(fvt,'FIR filter; Order = 100','FIR filter. Order = 200')
Вместо того, чтобы задать порядка фильтра, firgr
может использоваться, чтобы определить минимальный порядок, требуемый выполнить техническим требованиям проекта. В порядке для этого необходимо задать ширину области перехода. Это сделано путем установки частоты ребра полосы задерживания.
Fst = 23e3; % Transition Width = Fst - Fp numMinOrder = firgr('minorder',[0,Fp/(Fs/2),Fst/(Fs/2),1],[1 1 0 0],... [Rp Rst]); fvt = fvtool(eqnum,1,eqNum200,1,numMinOrder,1,'Fs',Fs,'Color','White'); legend(fvt,'FIR filter; Order = 100','FIR filter. Order = 200',... 'FIR filter. Order = 133')
Также возможно спроектировать фильтры минимума, даже заказывают ('mineven') или минимальный нечетный порядок ('minodd') через firgr
функция.
Если коэффициенты фильтра были получены, фильтр может быть реализован с dsp.FIRFilter
. Это поддерживает двойную / одинарную точность данные с плавающей точкой, а также данные фиксированной точки. Это также поддерживает C и генерацию HDL-кода, а также генерацию оптимизированного кода для ARM® Cortex® M и Коры ARM A.
lowpassFIR = dsp.FIRFilter('Numerator',eqnum); %or eqNum200 or numMinOrder fvtool(lowpassFIR,'Fs',Fs,'Color','White')
Для того, чтобы выполнить фактическую фильтрацию, вызовите КИХ непосредственно как функция. Следующий код фильтрует Гауссов белый шум и показывает получившийся отфильтрованный сигнал в спектре анализатор в течение 10 секунд.
scope = dsp.SpectrumAnalyzer('SampleRate',Fs,'SpectralAverages',5); tic while toc < 10 x = randn(256,1); y = lowpassFIR(x); scope(y); end
Как удобство, проектируя и реализуя фильтр может быть сделан на одном шаге с помощью dsp.LowpassFilter
. Это также поддерживает фиксированную точку с плавающей точкой, генерацию кода C, и Кору ARM M и Кору ARM оптимизация.
lowpassFilt = dsp.LowpassFilter('DesignForMinimumOrder',false, ... 'FilterOrder',N,'PassbandFrequency',Fp,'SampleRate',Fs,... 'PassbandRipple',0.01, 'StopbandAttenuation',80); tic while toc < 10 x = randn(256,1); y = lowpassFilt(x); scope(y); end
Заметьте, что как удобство, технические требования вводятся непосредственно с помощью значений дБ. Неравномерность в полосе пропускания может быть исследована путем выбора меню "View" в FVTool и затем выбора "Passband". dsp.LowpassFilter
может также использоваться для БИХ (biquad) проекты.
fvtool(lowpassFilt,'Fs',Fs,'Color','White')
Коэффициенты фильтра могут быть извлечены из dsp.LowpassFilter
при помощи tf
функция.
eqnum = tf(lowpassFilt);
КИХ lowpass просачивается, который частота среза может быть настроена во времени выполнения, может быть реализован с помощью 'dsp.VariableBandwidthFIRFilter'. Эти фильтры не обеспечивают ту же гранулярность управления характеристикой ответа фильтра, но они действительно допускают динамическую частотную характеристику.
vbwFilter = dsp.VariableBandwidthFIRFilter('CutoffFrequency',1e3); tic told = 0; while toc < 10 t = toc; if floor(t) > told % Add 1 kHz every second vbwFilter.CutoffFrequency = vbwFilter.CutoffFrequency + 1e3; end x = randn(256,1); y = vbwFilter(x); scope(y); told = floor(t); end
До сих пор все используемые проекты были оптимальными проектами equiripple. Проекты Экюриппла достигают оптимальности путем распределения отклонения от идеального ответа однородно. Это имеет преимущество минимизации максимального отклонения (пульсация). Однако полное отклонение, измеренное в терминах его энергии, имеет тенденцию быть большим. Это не может всегда быть желательно. Когда lowpass, фильтрующий сигнал, это подразумевает, что энергия остатка сигнала в полосе задерживания может быть относительно большой. Когда это - беспокойство, методы наименьших квадратов предоставляют оптимальные проекты, которые минимизируют энергию в полосе задерживания. fdesign.lowpass
может использоваться, чтобы спроектировать наименьшие квадраты и другие виды фильтров lowpass. Следующий код сравнивает КИХ-проект наименьших квадратов с КИХ equiripple проект с тем же порядком фильтра и шириной перехода:
lowpassSpec = fdesign.lowpass('N,Fp,Fst',133,Fp,Fst,Fs); lsFIR = design(lowpassSpec,'firls','SystemObject',true); LP_MIN = dsp.FIRFilter('Numerator',numMinOrder); fvt = fvtool(LP_MIN,lsFIR,'Fs',Fs,'Color','White'); legend(fvt,'Equiripple design','Least-squares design')
Заметьте, как затухание в полосе задерживания увеличивается с частотой для проектов наименьших квадратов, в то время как это остается постоянным для проекта equiripple. Увеличенное затухание в случае наименьших квадратов минимизирует энергию в той полосе сигнала, который будет отфильтрован.
Часто нежелательный эффект проектов наименьших квадратов состоит в том, что пульсация в области полосы пропускания близко к ребру полосы пропускания имеет тенденцию быть большой. Поскольку lowpass фильтрует в целом, желательно, чтобы частоты полосы пропускания сигнала, который будет отфильтрован, были затронуты как можно меньше. До этой степени equiripple полоса пропускания обычно предпочтительна. Если все еще желательно иметь увеличивающееся затухание в полосе задерживания, equiripple проектные решения обеспечивают способ достигнуть этого.
FIR_eqrip_slope = design(lowpassSpec,'equiripple','StopbandShape','1/f',... 'StopbandDecay',4,'SystemObject',true); fvt = fvtool(lsFIR,FIR_eqrip_slope,'Fs',Fs,'Color','White'); legend(fvt,'Least-squares design',... 'Equiripple design with stopband decaying as (1/f)^4')
Заметьте, что полосы задерживания весьма схожи. Однако проект equiripple имеет значительно меньшую неравномерность в полосе пропускания около частоты ребра полосы пропускания, 20 кГц:
mls = measure(lsFIR); meq = measure(FIR_eqrip_slope); mls.Apass meq.Apass
ans = 0.0121 ans = 0.0046
Еще одна возможность состоит в том, чтобы использовать произвольную спецификацию величины и выбрать две полосы (один для полосы пропускания и один для полосы задерживания). Затем при помощи весов для второй полосы возможно увеличить затухание в полосе. Для получения дополнительной информации об этом и других произвольных проектах величины смотрите Произвольное Создание фильтра Величины.
B = 2; % Number of bands F = [0 Fp linspace(Fst,Fs/2,40)]; A = [1 1 zeros(1,length(F)-2)]; W = linspace(1,100,length(F)-2); lowpassArbSpec = fdesign.arbmag('N,B,F,A',N,B,F(1:2),A(1:2),F(3:end), ... A(3:end),Fs); lpfilter = design(lowpassArbSpec,'equiripple','B2Weights',W, ... 'SystemObject',true); fvtool(lpfilter,'Fs',Fs,'Color','White');
До сих пор мы только рассмотрели проекты линейной фазы. Линейная фаза желательна во многих приложениях. Тем не менее, если линейная фаза не является требованием, проекты минимальной фазы могут обеспечить существенные улучшения по линейным дубликатам фазы. Однако проекты минимальной фазы не всегда численно устойчивы. Всегда проверяйте проект с FVTool.
Когда пример преимуществ минимальной фазы проектирует, рассмотрите сравнение проекта линейной фазы с проектом минимальной фазы, который выполняет тем же техническим требованиям проекта:
Fp = 20e3; Fst = 22e3; Fs = 96e3; Ap = 0.06; Ast = 80; lowpassSpec = fdesign.lowpass('Fp,Fst,Ap,Ast',Fp,Fst,Ap,Ast,Fs); linphaseSpec = design(lowpassSpec,'equiripple','SystemObject',true); eqripSpec = design(lowpassSpec,'equiripple','minphase',true,... 'SystemObject',true); fvt = fvtool(linphaseSpec,eqripSpec,'Fs',Fs,... 'Color','White'); legend(fvt,... 'Linear-phase equiripple design',... 'Minimum-phase equiripple design')
Заметьте, что количество коэффициентов было сокращено от 173 до 141. График групповой задержки также показывает преимущества проекта минимальной фазы. Заметьте, как групповая задержка намного меньше (в частности в области полосы пропускания).
fvt = fvtool(linphaseSpec,eqripSpec,'Fs',Fs,... 'Analysis','grpdelay','Color','White'); legend(fvt,... 'Linear-phase equiripple design',... 'Minimum-phase equiripple design')
Другой подход к минимизации количества коэффициентов, которое не включает проекты минимальной фазы, должен использовать многоступенчатые методы. Здесь мы показываем интерполированного КИХ (IFIR) подход. Этот подход терпит неудачу, проблема проектирования в разработку два просачивается каскад. В данном примере проект требует 151 коэффициента, а не 173. Для получения дополнительной информации об этом смотрите Произвольное Создание фильтра Величины.
Fp = 20e3; Fst = 22e3; Fs = 96e3; Ap = 0.06; Ast = 80; lowpassSpec = fdesign.lowpass('Fp,Fst,Ap,Ast',Fp,Fst,Ap,Ast,Fs); interpFilter = design(lowpassSpec,'ifir','SystemObject',true); cost(interpFilter) fvt = fvtool(linphaseSpec,interpFilter,'Fs',Fs,'Color','White'); legend(fvt,... 'Linear-phase equiripple design',... 'Interpolated FIR equiripple design (two stages)')
ans = struct with fields: NumCoefficients: 151 NumStates: 238 MultiplicationsPerInputSample: 151 AdditionsPerInputSample: 149
В этом случае график групповой задержки показывает недостатки проекта IFIR. В то время как проекты IFIR действительно обеспечивают линейную фазу, групповая задержка в целом больше, чем сопоставимый одноступенчатый проект.
fvt = fvtool(linphaseSpec,interpFilter,'Fs',Fs,'Analysis','grpdelay',... 'Color','White'); legend(fvt,... 'Linear-phase equiripple design',... 'Interpolated FIR equiripple design (two stages)')
Фильтры lowpass экстенсивно используются в проекте decimators и интерполяторов. См. Проект Decimators и Interpolators для получения дополнительной информации об этом и Многоступенчатом Преобразовании Уровня для многоступенчатых методов тот результат в очень эффективных внедрениях.