数字低通巴特沃斯滤波器阶数计算及MATLAB buttord函数高阶获取问题
Great question! Let’s break this down clearly—first, let’s clarify what buttord() actually does: it’s specifically built to calculate the minimum filter order needed to meet your passband/stopband specs. This is the standard goal in filter design: use the lowest possible order to hit your requirements, since higher orders add unnecessary computation time, phase distortion, and latency. There’s no built-in way to make buttord() return a "maximum order" because, theoretically, you can make the order as high as you want (though that’s rarely practical for real-world use).
If You Want a Higher Order (Like Your Rounded-Up 2nd Order)
You don’t need to rely on buttord() for this—just manually specify the order you want, then design the filter with butter(). Here’s a step-by-step example tailored to your specs:
Normalize your frequencies
With a sampling rateFs = 8kHz, convert your cutoff and stopband frequencies to normalized values (between 0 and 1, where 1 representsFs/2):Fs = 8000; Wn = 1.5e3 / (Fs/2); % Normalized cutoff frequency: 0.375 Ws = 3e3 / (Fs/2); % Normalized stopband frequency: 0.75 Rs = 10; % Required stopband attenuation (dB)Manually set your desired order and design the filter
Let’s use the 2nd order you calculated (by rounding up your 1.57 result):desired_order = 2; [b, a] = butter(desired_order, Wn, 'low');Verify the filter meets your stopband requirement
You can check the attenuation at 3kHz usingfreqz()to confirm it exceeds your 10dB requirement:[h, f] = freqz(b, a, 1024, Fs); % Find the closest frequency point to 3kHz idx = find(f >= 3000, 1); stopband_attenuation = -20*log10(abs(h(idx))); fprintf('Attenuation at 3kHz: %.2f dB\n', stopband_attenuation);You’ll see this 2nd-order filter gives far more than 10dB of attenuation at 3kHz—easily meeting your spec.
Why Did buttord() Return 1st Order?
Chances are, you set the passband attenuation Rp to 0 when calling buttord(). That’s a problem because real-world filters can’t have zero passband attenuation, and buttord() doesn’t handle Rp=0 correctly. If you use a realistic small value for Rp (like 0.1dB, meaning your passband signal loses at most 0.1dB), buttord() will return the correct minimum order (2, matching your manual calculation):
Rp = 0.1; % Realistic passband attenuation value [n, Wn_adjusted] = buttord(Wn, Ws, Rp, Rs);
Now n will be 2, which is the lowest order that actually meets your 10dB stopband attenuation requirement. A 1st-order filter only gives ~7dB of attenuation at 3kHz—not enough to hit your spec.
Key Takeaways
buttord()is for minimum-order designs only; there’s no "maximum order" option (since higher orders are unlimited but rarely useful).- To use a higher order, just specify it directly in
butter(). Keep in mind: higher orders mean steeper rolloff but more computation and phase shift. - Always use a non-zero
Rpvalue withbuttord()to get accurate, usable results.
内容的提问来源于stack exchange,提问作者Ahmed Mohamed




