www.gusucode.com > 利用MATLAB GUI设计滤波器界面,可以设计IIR滤波器 > AFD/GuiPlotFrequencyResponse.m

    function varargout = GuiPlotFrequencyResponse(varargin)
% GUIPLOTFREQUENCYRESPONSE M-file for GuiPlotFrequencyResponse.fig
%      GUIPLOTFREQUENCYRESPONSE, by itself, creates a new GUIPLOTFREQUENCYRESPONSE or raises the existing
%      singleton*.
%
%      H = GUIPLOTFREQUENCYRESPONSE returns the handle to a new GUIPLOTFREQUENCYRESPONSE or the handle to
%      the existing singleton*.
%
%      GUIPLOTFREQUENCYRESPONSE('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUIPLOTFREQUENCYRESPONSE.M with the given input arguments.
%
%      GUIPLOTFREQUENCYRESPONSE('Property','Value',...) creates a new GUIPLOTFREQUENCYRESPONSE or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before GuiPlotFrequencyResponse_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to GuiPlotFrequencyResponse_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help GuiPlotFrequencyResponse

% Last Modified by GUIDE v2.5 27-Dec-2003 07:10:45

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @GuiPlotFrequencyResponse_OpeningFcn, ...
                   'gui_OutputFcn',  @GuiPlotFrequencyResponse_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin & isstr(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before GuiPlotFrequencyResponse is made visible.
function GuiPlotFrequencyResponse_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for GuiPlotFrequencyResponse
handles.output = hObject;

global strFilterObject

% Load data
if isempty(strFilterObject)
   temp=load('matlab');
   disp([mfilename ' called in debug mode using matlab.mat datafile'])
   strFilterObject = temp.strFilterObject;
else
    strFilterObject=Utility_zpk(strFilterObject); % find poles, zeros
end
set(handles.uiFigure,'Name',strFilterObject.sTitle)

% determine and save FMin, FMax
FMin = floor(log10(strFilterObject.fFc))-2;
FMax = ceil(log10(strFilterObject.fFc))+2;
handles.FMin = FMin;
handles.FMax = FMax;
% set the query frequency to the critical frequency
if strFilterObject.fFc >= 1e6
    set(handles.uipmFc,'Value',4)
    set(handles.uitxFc, 'String', num2str(strFilterObject.fFc/1e6))
elseif strFilterObject.fFc >= 1000
    set(handles.uipmFc,'Value',3)
    set(handles.uitxFc, 'String', num2str(strFilterObject.fFc/1e3))
elseif strFilterObject.fFc >= 1
    set(handles.uipmFc,'Value',2)
    set(handles.uitxFc, 'String', num2str(strFilterObject.fFc))
elseif strFilterObject > 0
    set(handles.uipmFc,'Value',1)
    set(handles.uitxFc, 'String', num2str(strFilterObject.fFc*1000))
else
    error('Fc in strFilterObject is negative')
end
% enable/disable the "plot using standard values" button
if isempty(strFilterObject.fK1)
    handles.DrawStandard = 0;
    set(handles.uitxStandard,'Enable','off')
    set(handles.uicbStandard,'Enable','off')
    set(handles.uifrBox,'BackgroundColor',[.9 .9 .9]);
else
    handles.DrawStandard = 1;
    set(handles.uitxStandard,'Enable','on')
    set(handles.uicbStandard,'Enable','on')
    set(handles.uifrBox,'BackgroundColor',[0 0 .75])
    set(handles.uicbStandard,'Value',1)
end
% initialize variables
set(handles.uitxStandard,'Value',0)
handles.IsdB = get(handles.uirbdB,'Value');
handles.IsDeg = get(handles.uirbDeg,'Value');
handles.IsFLog = get(handles.uirbFLog,'Value');
handles.fExact = strFilterObject.fFc;

% Calculate y and plot it
guidata(hObject, handles);
Recalculate(handles);
Replot(handles);

function varargout = GuiPlotFrequencyResponse_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output; % default output

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                     Limit Callbacks   
%                    uitxFMin, uitxFMax
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function uitxFMin_Callback(hObject, eventdata, handles)
global strFilterObject
sFMin = get(hObject,'String');
if findstr('default',lower(sFMin))
    FMin = floor(log10(strFilterObject.fFc))-2;
    handles.FMin = FMin;
    sFMin = num2str(FMin);
    set(hObject,'String','default ')
    % check to see if maximum frequency must be increased
    if FMin>=handles.FMax
        handles.FMax=FMin+1;
        set(handles.uitxFMax,'String',num2str(handles.FMax))
    end
end
FMin = str2num(sFMin);
if isempty(FMin)
    errordlg('Enter the power of 10 of the lowest frequency to plot (e.g. 3 for 1kHz), or "default"','Error')
    set(hObject,'String',num2str(handles.FMin))
elseif FMin >= handles.FMax
    errordlg('Minimum frequency to plot must be less than the maximum frequency to plot','Error')
    set(hObject,'String',num2str(handles.FMin));
else
    handles.FMin = FMin;
    guidata(hObject, handles);
    Replot(handles)
end

function uitxFMax_Callback(hObject, eventdata, handles)
global strFilterObject
sFMax = get(hObject,'String');
if findstr('default',lower(sFMax)) 
    FMax = ceil(log10(strFilterObject.fFc))+2;
    handles.FMax = FMax;
    sFMax = num2str(FMax);
    set(hObject,'String','default ')
    % check to see if minimum frequency must be decreased
    if FMax<=handles.FMin
        handles.FMin=FMax-1;
        set(handles.uitxFMin,'String',num2str(handles.FMin))
    end
end
FMax = str2num(sFMax);
if isempty(FMax)
    errordlg('Enter the power of 10 of the highest frequency to plot (e.g. 6 for 1MHz), or "default"','Error')
    set(hObject,'String',num2str(handles.FMax))
elseif FMax <= handles.FMin
    errordlg('Maximum frequency to plot must be greater the minimum frequency to plot','Error')
    set(hObject,'String',num2str(handles.FMax));
else
    handles.FMax = FMax;
    guidata(hObject, handles);
    Replot(handles)
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                      Options Callbacks   
%                      uirbLinear, uirbdB
%                      uirbRad, uirbDeg
%                     uirbFLin, uirbFLog
%                        uicbStandard
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function uirbLinear_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbdB, 'Value', 0);
    set(handles.uitxGainTitle,'String','Gain')
    handles.IsdB = 0;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uirbdB_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbLinear, 'Value', 0);
    set(handles.uitxGainTitle,'String','Gain (dB)')
    handles.IsdB = 1;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uirbRad_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbDeg, 'Value', 0);
    set(handles.uitxPhaseTitle,'String','Phase (rad)')
    handles.IsDeg = 0;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uirbDeg_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbRad, 'Value', 0);
    set(handles.uitxPhaseTitle,'String','Phase (deg)')
    handles.IsDeg =1;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uirbFLin_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbFLog, 'Value', 0);
    handles.IsFLog = 0;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uiFLog_Callback(hObject, eventdata, handles)
if get(hObject,'Value') == 1
    set(handles.uirbFLin, 'Value', 0);
    handles.IsFLog = 1;
    guidata(hObject, handles);
    Replot(handles)
else
    set(hObject,'Value',1)
end

function uicbStandard_Callback(hObject, eventdata, handles)
handles.DrawStandard = get(hObject,'Value');
guidata(hObject, handles);
Replot(handles)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                     Analyze Callbacks   
%                      uitxFc, uipmFc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function uitxFc_Callback(hObject, eventdata, handles)
num=str2double(get(hObject,'String'));
if isnan(num)
    errordlg('Enter a numeric freqnency at which to examine the filter''s response','Error')
    set(hObject,'String',sprintf('%g',handles.fExact))
elseif num < 0
    errordlg('The frequency must be postive','Error')
    set(hObject,'String',sprintf('%g',handles.fExact))
else
    set(hObject,'String',sprintf('%g',num))
    handles.fExact = str2num(get(handles.uitxFc,'String'))*10^((get(handles.uipmFc,'Value')-2)*3);
end
guidata(hObject, handles);
Recalculate(handles)
Replot(handles)

function uipmFc_Callback(hObject, eventdata, handles)
handles.fExact = str2num(get(handles.uitxFc,'String'))*10^((get(handles.uipmFc,'Value')-2)*3);
guidata(hObject, handles);
Recalculate(handles)
Replot(handles)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Helper functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Recalculate(handles)
global strFilterObject
% setup
z = strFilterObject.vZeros; 
p = strFilterObject.vPoles; 
k = strFilterObject.fK; 
f = str2num(get(handles.uitxFc,'String'))*10^((get(handles.uipmFc,'Value')-2)*3);
% do the calculations
w=f*2*pi;
H = k*prod(j*w-z)/prod(j*w-p);
magH = abs(H);
dBH  = 20*log10(magH);
radH = angle(H);
degH = radH*180/pi;
% post the data
set(handles.uitxGain,'String',sprintf('%4.4g',magH))
set(handles.uitxGaindB,'String',sprintf('%4.4g',dBH))
set(handles.uitxPhaseDeg,'String',sprintf('%4.4g',degH))
set(handles.uitxPhaseRad,'String',sprintf('%4.4g',radH))


function Replot(handles)
% ------------------------setup----------------------------
global strFilterObject
z = strFilterObject.vZeros; 
p = strFilterObject.vPoles; 
k = strFilterObject.fK; 
f = logspace(handles.FMin, handles.FMax, 500);
w = 2*pi*f;
Fc = strFilterObject.fFc;
if handles.DrawStandard
    z1 = strFilterObject.vZeros1; 
    p1 = strFilterObject.vPoles1; 
    k1 = strFilterObject.fK1;    
end
% -------------------do the calculations--------------------
H=f;
for ind=1:length(w)
    wcur=w(ind);
    H(ind)= k*prod(j*wcur-z)/prod(j*wcur-p);
end
gain = abs(H);
if handles.IsdB
    gain = 20*log10(gain);
end
phase = unwrap(angle(H));
if handles.IsDeg
    phase = 180/pi*phase;
end
if handles.DrawStandard
    H1=f;
    for ind=1:length(w)
        wcur=w(ind);
        H1(ind)= k1*prod(j*wcur-z1)/prod(j*wcur-p1);
    end
    gain1 = abs(H1);
    if handles.IsdB
        gain1 = 20*log10(gain1);
    end
    phase1 = unwrap(angle(H1));
    if handles.IsDeg
        phase1 = 180/pi*phase1;
    end
    % due to weird rounding errors sometimes a 2pi diff b/n phase and phase1 occurs.
    % Stop it here.
    if handles.IsDeg
        for ind=1:length(w) 
            if abs(phase1(ind)-(phase(ind)+360)) < 10
                phase1(ind:end) = phase1(ind:end)-360;
            end
            if abs(phase1(ind)-(phase(ind)-360)) < 10
                phase1(ind:end) = phase1(ind:end)+360;
            end
        end
    else
        for ind=1:length(w) 
            if abs(phase1(ind)-(phase(ind)+2*pi)) < .1
                phase1(ind:end) = phase1(ind:end)-2*pi;
            end
            if abs(phase1(ind)-(phase(ind)-2*pi)) < .1
                phase1(ind:end) = phase1(ind:end)+2*pi;
            end
        end
    end
end
    % ----------------------plot the gain-------------------------
axes(handles.uiaxGain)
if handles.IsFLog
    semilogx(f,gain,'k-')
else
    plot(f,gain,'k-')
end
hold on
% plot standardized RC values
if handles.DrawStandard
    if handles.IsFLog
        semilogx(f,gain1,'b-')
    else
        plot(f,gain1,'b-')
    end
end
% plot the vertical line
axlimits=axis;
ymin = axlimits(3);
ymax = axlimits(4);
if handles.fExact>10^handles.FMin && handles.fExact<10^handles.FMax
    vx = [handles.fExact handles.fExact]; 
    vy = [ymin ymax];
    if handles.IsFLog
        semilogx(vx,vy,'r-')
    else
        plot(vx,vy,'r-')
    end
end
axis(axlimits)
hold off
% ----------------------plot the phase-------------------------
% plot ideal phase
axes(handles.uiaxPhase)
if handles.IsFLog
    semilogx(f,phase,'k-')
else
    plot(f,phase,'k-')
end
hold on
% plot standardized RC values
if handles.DrawStandard
    if handles.IsFLog
        semilogx(f,phase1,'b-')
    else
        plot(f,phase,'k-')
    end 
end
% plot the vertical line
axlimits=axis;
ymin = axlimits(3);
ymax = axlimits(4);
if handles.fExact>10^handles.FMin && handles.fExact<10^handles.FMax
    vx = [handles.fExact handles.fExact]; 
    vy = [ymin ymax];
    if handles.IsFLog
        semilogx(vx,vy,'r-')
    else
        plot(f,phase,'k-')
    end
end
axis(axlimits)
hold off