文章目录
- 1. matlab 的 buttord函数 的作用
- 2. matlab 的 buttord函数 的使用方法
- 3. C++ 实现代码
- 4. 测试代码和结果
- 4.1 定义滤波器的设计指标的结构体
- 4.2 C++ 测试文件
- 4.3 测试结果
1. matlab 的 buttord函数 的作用
根据给定的巴特沃斯滤波器的指标计算滤波器的最低阶数和截止频率
2. matlab 的 buttord函数 的使用方法
clear,clc,close;
%1.数字滤波器的技术指标要求
ap = 1;%通带最大衰减
as = 30;%阻带最小衰减
fp = 200;%通带截止频率
fs = 400;%阻带截止频率
Fs = 1000;%抽样间隔
T = 1/Fs;
%2.将数字指标转化成模拟滤波器指标
wp=(2*pi*fp)/Fs;
ws=(2*pi*fs)/Fs;
disp("wp="+wp);
disp("ws="+ws);
% 数字指标转模拟指标 预畸变,前面要× (2/T)
wap=2*Fs*tan(wp/2);
was=2*Fs*tan(ws/2);
disp(wap);
disp(was);
%3.设计模拟滤波器
[N,wac]=buttord(wap,was,ap,as,'s');% N为阶数,wac为3dB截止频率, 's'表示设计的是模拟滤波器
disp("N="+N);
disp("wac="+wac);
3. C++ 实现代码
#pragma once
#include <math.h>
//输入参数 wap 为模拟低通滤波器通带截止频率 Hz
//输入参数 was 为模拟低通滤波器阻带截止频率 Hz
//输入参数 ap 为模拟低通滤波器通带最大衰减 db
//输入参数 as 为模拟低通滤波器阻带最小衰减 db
//输出参数 N 为需要计算的模拟巴特沃斯低通滤波器的阶数
//输出参数 wc 为需要计算的模拟巴特沃斯低通滤波器的3db截止频率
bool buttord(double wap, double was, int ap, int as, int* N, double* wc)
{
// wap was ap as 都不能 <= 0
if (wap <= 0.0001 || was <= 0.0001 || ap <= 0.0001 || as <= 0.0001 || N == NULL || wc == NULL)
{
return false;
}
double ksp = sqrt((pow(10, 0.1 * as) - 1) / (pow(10, 0.1 * ap) - 1));
// 计算归一化频率
double lambdasp = was / wap;
*N = (int)ceil(log10(ksp) / log10(lambdasp));
// 使用双线性变换法,应用阻带指标 was
*wc = was * pow(pow(10, 0.1 * as) - 1, -1.0 / (2 * *N));
return true;
}
4. 测试代码和结果
4.1 定义滤波器的设计指标的结构体
#pragma once
struct DESIGN_SPECIFICATION
{
// 数字通带截止频率 Hz
double digital_passband_cutoff_frequency;
// 数字阻带截止频率 Hz
double digital_stopband_cutoff_frequency;
// 通带最大衰减 db
int passband_max_attenuation;
// 阻带最小衰减 db
int stopband_min_attenuation;
// 采样频率 Hz
int fs;
};
4.2 C++ 测试文件
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "design_specification.h"
#include "buttord.h"
#define pi ((double)3.141592653589793)
int main()
{
struct DESIGN_SPECIFICATION IIR_Filter;
//1.数字滤波器的技术指标
IIR_Filter.digital_passband_cutoff_frequency = 200; // Hz
IIR_Filter.digital_stopband_cutoff_frequency = 400;// Hz
IIR_Filter.passband_max_attenuation = 1; // db
IIR_Filter.stopband_min_attenuation = 30;// db
IIR_Filter.fs = 1000;// Hz
//2.将数字指标转化成模拟滤波器技术指标
double analog_passband_cutoff_frequency = (2 * pi * IIR_Filter.digital_passband_cutoff_frequency) / IIR_Filter.fs;
double analog_stopband_cutoff_frequency = (2 * pi * IIR_Filter.digital_stopband_cutoff_frequency) / IIR_Filter.fs;
//printf("wp = %lf, ws = %lf\n", analog_passband_cutoff_frequency, analog_stopband_cutoff_frequency);
//3.数字指标转模拟指标 预畸变,前面要× (2/T)
double wap = 2.0 * IIR_Filter.fs * tan(analog_passband_cutoff_frequency / 2);
double was = 2.0 * IIR_Filter.fs * tan(analog_stopband_cutoff_frequency / 2);
//printf("wap = %lf, was = %lf\n", wap, was);
//4.计算巴特沃斯滤波器阶数 和 3db截止频率
int* N = (int*)malloc(sizeof(int));
double* wc = (double*)malloc(sizeof(double));
bool ret = buttord(wap,
was,
IIR_Filter.passband_max_attenuation,
IIR_Filter.stopband_min_attenuation,
N,
wc);
printf("滤波器阶数:%d ,\n滤波器截止频率:%lf\n", *N, *wc);
return 0;
}
4.3 测试结果
可以看出和 matlab 得到的结果相同
下面再给一组设计指标进行测试:
数字通带截止频率 10 Hz
数字阻带截止频率 50 Hz
通带最大衰减 2 db
阻带最小衰减 40 db
采样频率 200 Hz
下面是 Matlab 的测试结果
下面是我的 C++ 版本的测试结果
可以看出 matlab 和 C++ 两个版本的结果一样