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