% This script runs an example of a load line analysis for a MOSFET amp % to: % 1. find the operating point for Vgs through iteration % 2. then compute a table of input (Vgs) and output (Vds)amplitude values % to get the transfer characteristic (TC) curve for the amp. % 3. then apply the resulting TC curve to an input sinusoid with % increasing amplitude to illustrate distorion. The sine wave % will be plotted and played in the demonstration. % The functions nmos.m and ampdist.m are needed to run this script % % Written by Kevin D. Donohue (donohue@engr.uky.edu) 10/2003 % Set Parameters: Operating point will be set to half VDD K=.5; vto = 1.8; % Nmos parameters W=1; L=1; KP=2*K; % Nmos parameters VDD=15; RS=400; RD=1e3; % Load line parameters idsmax = VDD/(RD+RS); % Maximum Load line value on Drain current axis % Operation point will be the max drain current divided by 2. vds = [0:.05:VDD]; % Create X-Axis idsll = -vds/(RD+RS) + VDD/(RD+RS); % Generate Load Line err = .2e-3; %Set initial error for quiesent point to get while loop started toler = .05e-3; % Set tolerance value for stopping rule on while loop incgs = .01; % Set increment for vgs to find intersection with load line. vgs = vto; % Initialize vgs to threshold voltage so initial guess will below desired operating point % Set flag to denote when guess goes above the the operating point in % order to reduce interation interval. passflag = 0; % If zero implies the last step is below the desired value, 1 implies last step was above % Set while loop to run until error is below tolerance while err >= toler ids = nmos(vds,vgs,KP,W,L,vto); % Compute characteristic curve [edum, inderr] = min(abs(idsll - ids)); % Find intersection with loadline err =abs(idsmax/2 - idsll(inderr(1))); % Find error between desired current and actual % Check to see if we are above or below the target and make adjustments to move closer to desired operating point if idsmax/2>ids(inderr) % If below target value .... vgs = vgs + incgs % Still below threshold so increase if passflag == 1 incgs = incgs/2; % If we just came from above the threshod cut increment in half for more resolution passflag = 0; % reset flag end else % If above target value vgs = vgs - incgs % Still above threshold so decrease if passflag == 0 incgs = incgs/2; % If we just came from below the threshold cut increment in half for more resolution passflag = 1; % reset flag end end % Comment out the next 4 lines to stop the while loop from being interupted by plots and pauses figure(1) plot(vds, idsmax*ones(size(vds))/2, 'c--', vds,idsll,'k:',vds,ids,'r') % Check plot along the way disp(['Iteration in progress']) pause(.1) end vgsq = vgs; % Set quiesent Vgs to last result of interation disp([' The operating point for Vgs is ' num2str(vgsq)]) % Compute corresponding output quiesent voltage amplitude at output ids = nmos(vds,vgsq,KP,W,L,vto); % Compute transfer characteristic (TC) curve at quiesent [err, inderr] = min(abs(ids - idsll)); % Find intersection with load line and TC vdsq = vds(inderr(1)); % Output voltage quiesent disp([' The operating point for Vds is ' num2str(vdsq)]) idsq = ids(inderr(1)); disp([' The operating point for Ids is ' num2str(idsq)]) disp([' Now compute transfer charactersitic between amp input and output ']) % Now compute array for maping the input to the output of the amplifier inarray = [0:.001:2*vgsq]; % AC input array amplitude sweep % range should include quiesent Vgs % Loop to compute each point on intersection of load line for input % vortage amplitude sweep for output VDS outarray = zeros(1,length(inarray)); % Initalize output array for karry = 1:length(inarray) vgsdcac= inarray(karry); % Vgs level with AC and DC energy ids = nmos(vds,vgsdcac,KP,W,L,vto); % Compute characteristic curve for that vgs [err, inderr] = min(abs(ids - idsll)); % Find closest point between load line and TC outarray(karry) = vds(inderr(1)); % Assign VDS as output array correspond to that Vgs value end % Subtract quiesent Vgs offset from input array to result in AC input only component insigac = inarray - vgsq; % Subtract quiesent Vds offset from input array to result in AC output only component outsigac = outarray - vdsq; % Plot transfer characteristics for AC voltage gain figure(2) plot(insigac,outsigac) xlabel('Input AC voltage Amplitude') ylabel('Output AC voltage Amplitude') title('AC transfer characteristic of amplifier') disp(['Hit any key to continue to hear examples of sounds played through amplifier']) pause % Now test the input and output relationship of the amplifier: % Creat a unit 300 Hz sine wave sampled at 8000 Hz and pass it through the amp fs = 8000; % Sampling frequency t= [0:3*fs-1]/fs; % Create a time axis for signal for 3 seconds sigin = sin(2*pi*t*300); % Create unit sine wave a = [.01, .05, .15]; %Set up amplitude scales for input voltage % Loop to distort and play sound for k=1:3 sigout = ampdist(sigin*a(k),insigac,outsigac); % Distort sound by mapping amplitudes through TC % Plot original and amplified signal on same scale to observe distortion figure(2+k); plot(t(1:100),sigin(1:100)/max(abs(sigin)),'r',t(1:100),-sigout(1:100)/max(abs(sigout)),'b') title([' Compare Scaled Input (red) at amplitude ' num2str(a(k)), ' output (blue) for Distortion']) % Play both sounds consecutively % Concatenate scale input and output signals in one vector wavsig = [sigin/(max(abs(sigin))+eps), sigout/(max(abs(sigout))+eps)]; soundsc(wavsig,fs); % Pause for user key press to go on to next sound if not at the end if k~=3 disp(['Hit any key to continue to next sound']) pause end end