⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfunc.mod

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 MOD
字号:
/* $Id: cfunc.mod,v 1.3 2004/07/09 18:38:04 pnenzi Exp $ *//*.......1.........2.........3.........4.........5.........6.........7.........8================================================================================FILE zener/cfunc.modCopyright 1991Georgia Tech Research Corporation, Atlanta, Ga. 30332All Rights ReservedPROJECT A-8503-405               AUTHORS                           2 May 1991     Jeffrey P. MurrayMODIFICATIONS       18 Sep 1991    Jeffrey P. Murray     2 Oct 1991    Jeffrey P. Murray                                   SUMMARY    This file contains the model-specific routines used to    functionally describe the zener code model.INTERFACES           FILE                 ROUTINE CALLED         CM.c                 void cm_analog_not_converged()REFERENCED FILES    Inputs from and outputs to ARGS structure.                     NON-STANDARD FEATURES    NONE===============================================================================*//*=== INCLUDE FILES ====================*/#include <math.h>                                      /*=== CONSTANTS ========================*//*=== MACROS ===========================*/  /*=== LOCAL VARIABLES & TYPEDEFS =======*/                                        /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/                   /*==============================================================================FUNCTION void cm_zener()AUTHORS                           2 May 1991     Jeffrey P. MurrayMODIFICATIONS       18 Sep 1991    Jeffrey P. Murray     2 Oct 1991    Jeffrey P. MurraySUMMARY    This function implements the zener code model.INTERFACES           FILE                 ROUTINE CALLED         CM.c                 void cm_analog_not_converged()RETURNED VALUE        Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE==============================================================================*/#include <stdlib.h>/*=== CM_ZENER ROUTINE ===*/void cm_zener(ARGS)  /* structure holding parms,                                           inputs, outputs, etc.     */{    double v_breakdown, /* breakdown voltage parameter  */           i_breakdown, /* breakdown current parameter  */           r_breakdown, /* breakdown resistance parameter   */                 i_rev, /* reverse current parameter    */                 i_sat, /* saturation current parameter...                           a.k.a. Io in the forward diode                           characteristic equation...see below. */             n_forward, /* forward emission coefficient parameter...                           a.k.a. "n" in the forward diode                           characteristic equation...see below. */                    vt, /* volt-equivalent of temperature, Vt,                           used in conjunction with n = n_forward                            value to describe the forward-voltage                           diode behavior described as:                            I = Io * (e^(V/n*Vt) - 1.0)  */                  v_1_2, /* Boundary value voltage between region                           1 (forward diode characteristic) and                            region 2 (linear region) */                     k, /* intermediate value used to find v_2_3 */                  v_2_3, /* Boundary value voltage between region                           2 (linear region) and region 3                            (reverse breakdown region) */                slope1, /* Slope of endpoint for a two segment model */                 slope2, /* Slope of endpoint for a two segment model */                  temp, /* temporary variable used to calulate the						   derivatives */               v_zener, /* input voltage across zener   */               i_zener, /* current which is allowed to                              flow through zener, for a given voltage  */                    i0,                    v0,                     a, /* coefficient used to calculate "c" */                     b, /* coefficient used to calculate "c" */                     c, /* A constant to match ordinates at                            region 2/3 boundary */                 deriv, /* partial derivative of the output                           current w.r.t. the input voltage */                  diff, /* difference between slope1 and slope2 */               ord_1_2, /* Compute ordinate at boundary of regions 1 & 2 */     *previous_voltage, /* Previous voltage value (used for limiting) */             increment, /* Increment value calculated from the                           previous_input for v_zener input limiting */                     g; /* conductance value equal to                            i_rev / v_breakdown. This value is                           used to simulate a reverse-leakage                           conductance in parallel with the                           zener characteristic.    */    Mif_Complex_t ac_gain;  /* AC gain  */                       if (INIT==1) {  /* First pass...allocate storage for previous value... */        /* Allocate storage for frequencies */        STATIC_VAR(previous_voltage) = (double *) malloc(sizeof(double));        previous_voltage = STATIC_VAR(previous_voltage);        /* Set previous_voltage value to zero... */        *previous_voltage = 0.0;    }      else {        previous_voltage = STATIC_VAR(previous_voltage);    }                           /* Retrieve frequently used parameters & inputs... */    v_breakdown = PARAM(v_breakdown);    i_breakdown = PARAM(i_breakdown);    r_breakdown = PARAM(r_breakdown);    i_rev = PARAM(i_rev);    i_sat = PARAM(i_sat);    n_forward = PARAM(n_forward);                                  v_zener = INPUT(z);          /** If the limit_switch parameter is set, test the   **/                          /** current input against previous value for limiting **/    if ( MIF_TRUE == PARAM(limit_switch) ) {        /* Check magnitude of v_zener */        if ( fabs(*previous_voltage) >= 1.0 ) {            increment = 0.1 * *previous_voltage;        }        else {            if (v_zener < 0.0) {                increment = -0.1;            }            else {                increment = 0.1;            }        }                                                /* Test v_zener for reasonable change in value since last call.. */        if ( fabs(v_zener) > ( fabs(*previous_voltage + increment) ) ) {                /* Apply limiting... */            *previous_voltage = v_zener = *previous_voltage + increment;                cm_analog_not_converged();                    }        else {                *previous_voltage = v_zener;            }    }      /* Compute voltage at boundary of regions 1 & 2 */    vt = 0.026;    v_1_2 = n_forward * vt * log(n_forward * vt / 10.0);    /* Compute voltage at boundary of regions 2 & 3 */    k = 1.0 / i_breakdown / r_breakdown;    v_2_3 = -v_breakdown + log(10.0/i_sat/r_breakdown)/k;    /* Compare v_1_2 and v_2_3 to determine if a 3 segment model is possible */     if (v_2_3 < v_1_2) {           /* Use a 3 segment model */        /* Compute v0 for region 3... */            i0 = 1.e-6;        v0 = -v_breakdown + 1.0/k*log(i_breakdown/i0);        /* Compute ordinate at boundary of regions 1 & 2 */        ord_1_2 = i_sat * (exp(v_1_2/n_forward/vt) - 1.0);        /* Compute a & b coefficients for linear section in region 2 */        a = i_sat / 10.0;        b = ord_1_2 - a * v_1_2;        /* Compute constant to match ordinates at region 2/3 boundary */        c = a*v_2_3 + b + i0*exp(-k * (v_2_3 - v0));        /* Compute zener current */        if (v_zener >= v_1_2) {            temp = exp(v_zener / n_forward / vt);            i_zener = i_sat * (temp - 1.0);            deriv = i_sat / n_forward / vt * temp;        }        else {            if (v_zener >= v_2_3) {                i_zener = a * v_zener + b;                deriv = i_sat / 10.0;            }            else {                temp = exp(-k * (v_zener - v0));                i_zener = -i0 * temp + c;                deriv = k * i0 * temp;            }        }    }    else {                        /* Must use a 2 segment model */        /* Determine i0 for reverse region */        i0 = i_breakdown / (exp(k * v_breakdown) - 1.0);        /* Determine the slopes at the region endpoints */        slope1 = i_sat / n_forward / vt;        slope2 = i0 * k;                              /* Determine zener current & first partial...           */        /* Use a linear conductance in one region to match      */        /* slopes at the boundary.                              */                                                                          if (v_zener >= 0.0) {            temp = exp(v_zener / n_forward / vt);            i_zener = i_sat * (temp - 1.0);            deriv = i_sat / n_forward / vt * temp;            diff = slope2 - slope1;            if (diff > 0.0) {                i_zener = i_zener + diff * v_zener;                deriv = deriv + diff;            }        }        else {            temp = exp(-k * v_zener);            i_zener = -i0 * (temp - 1.0);            deriv = k * i0 * temp;            diff = slope1 - slope2;            if (diff > 0.0) {                i_zener = i_zener + diff * v_zener;                deriv = deriv + diff;            }        }    }    /* Add resistor in parallel to simulate reverse leakage */    g = i_rev / v_breakdown;    i_zener = i_zener + g * v_zener;    deriv = deriv + g;    if(ANALYSIS != MIF_AC) {        /* Output DC & Transient Values */        OUTPUT(z) = i_zener;        PARTIAL(z,z) = deriv;    }    else {                      /* Output AC Gain */        ac_gain.real = deriv;        ac_gain.imag= 0.0;        AC_GAIN(z,z) = ac_gain;    }} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -