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

📄 diotemp.c

📁 另一款电路设计软件
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Thomas L. Quarles**********/    /* perform the temperature update to the diode */#include "spice.h"#include <stdio.h>#include "util.h"#include "cktdefs.h"#include "diodefs.h"#include "const.h"#include "sperror.h"#include "suffix.h"intDIOtemp(inModel,ckt)    GENmodel *inModel;    register CKTcircuit *ckt;{    register DIOmodel *model = (DIOmodel*)inModel;    double xfc;    double vte;    double cbv;    double xbv;    double xcbv;    double tol;    double vt;    double vtnom;    register DIOinstance *here;    register int iter;    char *emsg;    /*  loop through all the diode models */    for( ; model != NULL; model = model->DIOnextModel ) {        if(!model->DIOnomTempGiven) {            model->DIOnomTemp = ckt->CKTnomTemp;        }        vtnom = CONSTKoverQ * model->DIOnomTemp;        /* limit grading coeff to max of .9 */        if(model->DIOgradingCoeff>.9) {            (*(SPfrontEnd->IFerror))(ERR_WARNING,                    "%s: grading coefficient too large, limited to 0.9",                    &(model->DIOmodName));            model->DIOgradingCoeff=.9;        }        /* limit activation energy to min of .1 */        if(model->DIOactivationEnergy<.1) {            (*(SPfrontEnd->IFerror))(ERR_WARNING,                    "%s: activation energy too small, limited to 0.1",                    &(model->DIOmodName));            model->DIOactivationEnergy=.1;        }        /* limit depletion cap coeff to max of .95 */        if(model->DIOdepletionCapCoeff>.95) {            (*(SPfrontEnd->IFerror))(ERR_WARNING,                    "%s: coefficient Fc too large, limited to 0.95",                    &(model->DIOmodName));            model->DIOdepletionCapCoeff=.95;        }        if(!model->DIOresistGiven || model->DIOresist==0) {            model->DIOconductance = 0;        } else {            model->DIOconductance = 1/model->DIOresist;        }        xfc=log(1-model->DIOdepletionCapCoeff);        for(here=model->DIOinstances;here;here=here->DIOnextInstance) {            double egfet1,arg1,fact1,pbfact1,pbo,gmaold;            double fact2,pbfact,arg,egfet,gmanew;            /* loop through all the instances */            if(!here->DIOtempGiven) here->DIOtemp = ckt->CKTtemp;            vt = CONSTKoverQ * here->DIOtemp;            /* this part gets really ugly - I won't even try to             * explain these equations */            fact2 = here->DIOtemp/REFTEMP;            egfet = 1.16-(7.02e-4*here->DIOtemp*here->DIOtemp)/                    (here->DIOtemp+1108);            arg = -egfet/(2*CONSTboltz*here->DIOtemp) +                    1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));            pbfact = -2*vt*(1.5*log(fact2)+CHARGE*arg);            egfet1 = 1.16 - (7.02e-4*model->DIOnomTemp*model->DIOnomTemp)/                    (model->DIOnomTemp+1108);            arg1 = -egfet1/(CONSTboltz*2*model->DIOnomTemp) +                     1.1150877/(2*CONSTboltz*REFTEMP);            fact1 = model->DIOnomTemp/REFTEMP;            pbfact1 = -2 * vtnom*(1.5*log(fact1)+CHARGE*arg1);            pbo = (model->DIOjunctionPot-pbfact1)/fact1;            gmaold = (model->DIOjunctionPot -pbo)/pbo;            here->DIOtJctCap = model->DIOjunctionCap/                    (1+model->DIOgradingCoeff*                    (400e-6*(model->DIOnomTemp-REFTEMP)-gmaold) );            here->DIOtJctPot = pbfact+fact2*pbo;            gmanew = (here->DIOtJctPot-pbo)/pbo;            here->DIOtJctCap *= 1+model->DIOgradingCoeff*                    (400e-6*(here->DIOtemp-REFTEMP)-gmanew);            here->DIOtSatCur = model->DIOsatCur *  exp(                     ((here->DIOtemp/model->DIOnomTemp)-1) *                    model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) +                    model->DIOsaturationCurrentExp/model->DIOemissionCoeff*                    log(here->DIOtemp/model->DIOnomTemp) );            /* the defintion of f1, just recompute after temperature adjusting             * all the variables used in it */            here->DIOtF1=here->DIOtJctPot*                    (1-exp((1-model->DIOgradingCoeff)*xfc))/                    (1-model->DIOgradingCoeff);            /* same for Depletion Capacitance */            here->DIOtDepCap=model->DIOdepletionCapCoeff*                    here->DIOtJctPot;            /* and Vcrit */            vte=model->DIOemissionCoeff*vt;            here->DIOtVcrit=vte*log(vte/(CONSTroot2*here->DIOtSatCur));            /* and now to copute the breakdown voltage, again, using             * temperature adjusted basic parameters */            if (model->DIObreakdownVoltageGiven){                cbv=model->DIObreakdownCurrent;                if (cbv < here->DIOtSatCur*model->DIObreakdownVoltage/vt){                    cbv=here->DIOtSatCur*model->DIObreakdownVoltage/vt;                    emsg = MALLOC(100);                    if(emsg == (char *)NULL) return(E_NOMEM);                    (void)sprintf(emsg,            "%%s: breakdown current increased to %g to resolve incompatability",                            cbv);                    (*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname));                    FREE(emsg);                    (*(SPfrontEnd->IFerror))(ERR_WARNING,                            "with specified saturation current",(IFuid*)NULL);                    xbv=model->DIObreakdownVoltage;                } else {                    tol=ckt->CKTreltol*cbv;                    xbv=model->DIObreakdownVoltage-vt*log(1+cbv/                            here->DIOtSatCur);                    iter=0;                    for(iter=0 ; iter < 25 ; iter++) {                        xbv=model->DIObreakdownVoltage-vt*log(cbv/                                here->DIOtSatCur+1-xbv/vt);                        xcbv=here->DIOtSatCur*(exp((model->DIObreakdownVoltage                                -xbv)/vt)-1+xbv/vt);                        if (FABS(xcbv-cbv) <= tol) goto matched;                    }                    emsg = MALLOC(100);                    if(emsg == (char *)NULL) return(E_NOMEM);                    (void)sprintf(emsg,"%%s: unable to match forward and reverse diode regions: bv = %g, ibv = %g",                            xbv,xcbv);                    (*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&here->DIOname);                    FREE(emsg);                }                matched:                here->DIOtBrkdwnV = xbv;            }        }        model->DIOf2=exp((1+model->DIOgradingCoeff)*xfc);        model->DIOf3=1-model->DIOdepletionCapCoeff*                (1+model->DIOgradingCoeff);    }    return(OK);}

⌨️ 快捷键说明

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