% lcfilter.mの前半。後半と併せてUTF-8でテキストファイルとして拡張子.mで保存してください。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LC filter design for Butterworth, Chebyshev, Bessel and Elliptic
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear all

% 電力伝達多項式をプロットするか
PLOT1 = 1;         % 1 にした場合にプロットし、0だとプロットしない
% 反射電力多項式をプロットするか
PLOT2 = 0;        % 1 にした場合にプロットし、0だとプロットしない
% 反射係数多項式をプロットするか(正しく動作しているかの確認のため)
PLOT3 = 0;        % 1 にした場合にプロットし、0だとプロットしない


fprintf(char(10))
fprintf('LC filter design for Butterworth, Chebyshev, Bessel and Elliptic')
fprintf(char(10))
fprintf('Butterworth = 1')
fprintf(char(10))
fprintf('Chebyshev = 2')
fprintf(char(10))
fprintf('Bessel = 3')
fprintf(char(10))
fprintf('Elliptic = 4')
fprintf(char(10))
fprintf(char(10))

type = 0;
st = "Enter filter type number: ";
while !(type == 1 || type == 2 || type == 3 || type == 4)
    type = input(st);
end

% フィルタの次数を設定
order = 0;
switch(type)
    case 2
        st = "Enter filter order (Odd number) 3 to  9: ";
    case 4
        st = "Enter filter order (Odd number) 3 to  9: ";
    otherwise
    st = "Enter filter order 2 to  9: ";
end

while !(order > 1 && order < 10)
    order = input(st);
    if ((type == 2 || type == 4) && mod(order, 2) == 0)
        fprintf(char(10))
        fprintf('Error!')
        fprintf(char(10))
        fprintf('Even order Chebyshev or Elliptic filter can not be generated.')
        fprintf(char(10))
        fprintf('Because even order should have assigned ripple level attenuation at DC.')
        fprintf(char(10))
        fprintf('Enter odd order number please.')
        fprintf(char(10))
        fprintf(char(10))
        order = 0;
    end
end


% Chebyshev, EllipticフィルタのリプルをdBで設定
ripple = 0;
switch(type)
    case 2
        st = "Enter Chebyshev ripple in dB (0.01 to 3): ";
        while !(ripple >= 0.01 && ripple <= 3)
            ripple = input(st);
        end
    case 4
        st = "Enter Elliptic ripple in dB (0.01 to 3): ";
        while !(ripple >= 0.01 && ripple <= 3)
            ripple = input(st);
        end
        
        stopatt = 0;
        st = "Enter Elliptic stopband minimul attenuation in +dB (10 to 80): ";
        while !(stopatt >= 10 && ripple <= 80)
            stopatt = input(st);
        end
end


% 信号源インピーダンスを1で正規化
Rs = 1;
fprintf('Source impedance is set to 1 ohm to normalize')
fprintf(char(10)')


% 1で正規化した負荷インピーダンスを入力
Rl = 0;
st = "Enter Normalized Load Impedance in Ohm 0.1 to 10: ";
while !(Rl >= 0.1 && Rl <= 10)
    Rl = input(st);
end


if !(Rs == Rl)
    fprintf(char(10)')
    fprintf('!!! Note !!!')
    fprintf(char(10)')
    fprintf('In a case whare Source and Load impedance are not equal,')
    fprintf(char(10)')
    fprintf('inverse of Load impedance you set (1/RL) will also be calculated,')
end

fprintf(char(10)')
fprintf(char(10)')



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 信号伝達レベルの設定(信号源インピーダンスと
% 式は多項式になっているが、s = 0 つまり、DCでの条件で考えると簡単になる
% 反射係数 = Γ = (Rl - Rs)/(Rl + Rs)、これを自乗すれば反射電力となるため、これを用いて負荷に伝達する電力を計算する
% 負荷に伝達する電力(マッチング状態を1とした)= 1 - (gamma)^2(伝達電力率)

Power_Transfer_Ratio = 1 - (abs((Rl - Rs)/(Rl + Rs)))^2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


switch(type)
    case 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Butterworth filter カーブ
        % Butterworth特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        i = sqrt(-1);
        powerpoly = [1 zeros(1, (2 * order - 1)) 1];
        ripple = 1;   % PLOT 1でプロットするための一時的な設定

    case 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Chebyshev filter カーブ
        % Chebyshev特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        i = sqrt(-1);

        % dBで入力したChebyshev リプルを実電力リプル率にする
        e = 10^(ripple/10);
        e = e - 1;
        e = sqrt(e);

        % Chebyshev多項式を漸化式として得る
        % 漸化式の関係は
        % T_n+1(x) = 2x T_n(x) - T_n-1(x)

        tminus1 = [zeros(1, order) 1];
        tminus0 = [tminus1 0];
        tminus0 = tminus0(2:order+2);

        for n = 2:order
            tn = 2 * [tminus0 0];
            tn = tn(2:order+2);
            tn = tn - tminus1;
            tminus1 = tminus0;
            tminus0 = tn;
        end

        % Tn^2 (電力)を得る
        tn2 = conv(tn, tn);
        powerpoly = e^2 * tn2;
        powerpoly = powerpoly + [zeros(1, order*2) 1];

    case 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Bessel filter カーブ
        % Bessel 特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        i = sqrt(-1);

        % ベッセルフィルタはいきなりs平面での多項式で以下のようにあらわされる
        powerpolyP = [];
        for n = 0:order
            powerpolyP = [powerpolyP (factorial(order + n)/(factorial(order - n)*factorial(n)))*(1/2)^n*i^(order - n)];
        end

        % 0次の次数で正規化
        powerpolyP = powerpolyP/powerpolyP(1, order + 1);

        % s平面での多項式の共役を得る
        powerpolyN = [];
        for n = 0:order
            powerpolyN = [powerpolyN (factorial(order + n)/(factorial(order - n)*factorial(n)))*(1/2)^n*(-i)^(order - n)];
        end

        % 0次の次数で正規化
        powerpolyN = powerpolyN/powerpolyN(1, order + 1);

        % 自乗して電力伝達多項式を得る
        powerpoly = conv(powerpolyP, powerpolyN);
        powerpoly = real(powerpoly);

        ripple = 1;   % PLOT 1でプロットするための一時的な設定

        % ω = 1 rad/secにおける減衰量を計算する
        mpx = [];
        for n = 2*order:-1:0
            mpx = [(-1)^n mpx];
        end

        att = powerpoly * mpx';
        att = -10 * log10(att);
        fprintf('Attenuation at omega = 1 is %2.3d dB', att)
        fprintf(char(10))

    case 4
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Elliptic filter カーブ
        % Elliptic特性を自乗し、それを逆数とした電力伝達多項式を得る
        % 分母分子があるので注意
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        pkg load signal;

        i = sqrt(-1);

        % ellipap関数を用いて多項式のゼロと極を得る

        [elpnum elpden] = ellipap(order, ripple, stopatt);

        powerpoly = 1; %これはダミーでElliptic filterの設計では使用しない
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 電力伝達率で伝達多項式を割ることで、Rs ≠ Rl のときの電力伝達多項式を得る
powerpoly = powerpoly / Power_Transfer_Ratio;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ここまでで伝達多項式powerpolyを得た。ただしEllipticでは使わない
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 

 

 

24. LCフィルタ設計MATLAB/GNU Octave mファイルに戻る

 

LCフィルタ設計のTOPに戻る