www.gusucode.com > 利用MATLAB GUI设计滤波器界面,可以设计IIR滤波器 > AFD/BuildCircuit_LastStage.m
function strCircuit = BuildCircuit_LastStage(strCircuit) % BuildCircuit_LastStage is a subfile of the AnalogFilter GUI collection % % James C. Squire, 2002 % Assistant Professor, Virginia Military Institute % ver 1.0 % BuildCircuit_LastStage takes a strFilterObject with precomputed biquads % and if necessary builds a final first OR zero order stage to meet the % specified poles, zeros, gain, and polarity % constants CLOSE_ENOUGH = 0.05; % if gain is within CLOSE_ENOUGH then omit final gain stage (e.g. .05 = 5%) DEBUG = 1; % print out helpful information to aid in debugging % setup nStages = strCircuit.nStages; nBiquads = strCircuit.nBiquads; bFirstOrderStage = strCircuit.bFirstOrderStage; bGainStage = strCircuit.bGainStage; sPolarity = strCircuit.sPolarity; % may be i, n, or d nRTol = strCircuit.nRTol; nCTol = strCircuit.nCTol; sPurpose = strCircuit.sPurpose; % may be LP, HP, or Notch vStage = strCircuit.vStage; % find kRequired, the amount of gain required in a last stage to fix undesired gain in the biquads kSoFar = 1; for i=1:nBiquads k1=strCircuit.vStage(i).k1; p1=strCircuit.vStage(i).p1; z1=strCircuit.vStage(i).z1; k=strCircuit.vStage(i).k; p=strCircuit.vStage(i).p; z=strCircuit.vStage(i).z; if prod(z)*prod(z1)==0 % if a HP kSoFar = kSoFar * k1; else kSoFar = kSoFar * k1 * prod(-z1) / prod(-p1) / prod(-z) * prod(-p); end end kRequired = strCircuit.k/kSoFar; switch sPolarity case 'd' % if we don't care about the polarity, make it so if close to +/-1 we don't use the last stage kRequired = abs(kRequired); case 'n' % if non-inverting do nothing case 'i' % if inverting passband, then invert kRequired kRequired = -kRequired; otherwise error('unknown sPolarity') end if kRequired > 1-CLOSE_ENOUGH && kRequired < 1+CLOSE_ENOUGH kRequired = 1; end % determine each stage's name if ~bFirstOrderStage % no first order stage if kRequired < 0 bGainStage = 1; nStages = nBiquads + bFirstOrderStage + bGainStage; vStage(nStages).k = kRequired; vStage(nStages).k1 = kRequired; vStage(nStages).schName = 'ZO_I'; vStage(nStages).schTitle = 'Inverting gain'; elseif kRequired>0 && kRequired < 1 bGainStage = 1; nStages = nBiquads + bFirstOrderStage + bGainStage; vStage(nStages).k = kRequired; vStage(nStages).k1 = kRequired; vStage(nStages).schName = 'ZO_N_KLE1'; vStage(nStages).schTitle = 'Non-inverting gain'; elseif kRequired==1 % no final stage needed bGainStage = 0; nStages = nBiquads + bFirstOrderStage + bGainStage; elseif kRequired>1 bGainStage = 1; nStages = nBiquads + bFirstOrderStage + bGainStage; vStage(nStages).k = kRequired; vStage(nStages).k1 = kRequired; vStage(nStages).schName = 'ZO_N_KGT1'; vStage(nStages).schTitle = 'Non-inverting gain'; end else % requires a first order stage vStage(nStages).k = kRequired; vStage(nStages).k1 = kRequired; if isempty(vStage(nStages).z) % LP vStage(nStages).schTitle = 'First order lowpass'; % kDC = k / abs(p) for 1st order LP or k otherwise - important because % LP_SK uses a different configuration for kDC <=1 and >1 kDC = kRequired/abs(vStage(nStages).p(1)); if kDC < 0 vStage(nStages).schName = 'SO_LP_I'; elseif kDC>0 && kDC <= 1 vStage(nStages).schName = 'SO_LP_N_KLE1'; elseif kDC>1 vStage(nStages).schName = 'SO_LP_N_KGT1'; end else % HP vStage(nStages).schTitle = 'First order highpass'; if kRequired < 0 vStage(nStages).schName = 'SO_HP_I'; elseif kRequired>0 && kRequired <= 1 vStage(nStages).schName = 'SO_HP_N_KLE1'; elseif kRequired>1 vStage(nStages).schName = 'SO_HP_N_KGT1'; end end end % make the recommended name/title the same as the current schematic name/title if a last stage if bFirstOrderStage || bGainStage vStage(nStages).recName = vStage(nStages).schName; vStage(nStages).recTitle = vStage(nStages).schTitle; end % fill up the output structure strCircuit.bGainStage = bGainStage; strCircuit.nStages = nStages; strCircuit.vStage = vStage; % select components for the last stage (if any) if bFirstOrderStage || bGainStage strCircuit.vStage(nStages) = ... BuildCircuit_UpdateComponents(strCircuit.vStage(nStages),nRTol,nCTol); end