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

📄 acan.c

📁 支持数字元件仿真的SPICE插件
💻 C
字号:
/* * Copyright (c) 1985 Thomas L. Quarles */#include "prefix.h"#include <stdio.h>#include <math.h>#include "CKTdefs.h"#include "ACdefs.h"#include "util.h"#include "SPerror.h"/* gtri - add - wbk - 12/19/90 - Add headers */#include "MIF.h"#include "EVTproto.h"#include "IPCtiein.h"/* gtri - end - wbk */#include "suffix.h"RCSID("ACan.c $Revision: 1.6 $ on $Date: 92/06/15 18:43:40 $")intACan(ckt,restart) CKTcircuit *ckt;int restart;{    double freq;    double freqTol; /* tolerence parameter for finding final frequency */    int error;    long save;    int save1;    int numNames;    IFuid *nameList;    IFuid freqUid;    GENERIC *acPlot;/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */    /* Tell the beginPlot routine what mode we're in */    g_ipc.anal_type = IPC_ANAL_AC;    /* Tell the code models what mode we're in */    g_mif_info.circuit.anal_type = MIF_DC;    g_mif_info.circuit.anal_init = MIF_TRUE;/* gtri - end - wbk */    if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) {         /* start at beginning */        switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {        case DECADE:            ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =                    exp(log(10.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);            break;        case OCTAVE:            ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =                    exp(log(2.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);            break;        case LINEAR:            ((ACAN*)ckt->CKTcurJob)->ACfreqDelta =                    (((ACAN*)ckt->CKTcurJob)->ACstopFreq -                    ((ACAN*)ckt->CKTcurJob)->ACstartFreq)/                    (((ACAN*)ckt->CKTcurJob)->ACnumberSteps+1);            break;        default:            return(E_BADPARM);        }/* gtri - begin - wbk - Call EVTop if event-driven instances exist */        if(ckt->evt->counts.num_insts == 0) {            /* If no event-driven instances, do what SPICE normally does */            error = CKTop(ckt,                (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,                (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,                ckt->CKTdcMaxIter);            if(error) return(error);        }        else {            /* Else, use new DCOP algorithm */            error = EVTop(ckt,                        (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,                        (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,                        ckt->CKTdcMaxIter,                        MIF_TRUE);            EVTdump(ckt, IPC_ANAL_DCOP, 0.0);            EVTop_save(ckt, MIF_TRUE, 0.0);            if(error)                return(error);        }/* gtri - end - wbk - Call EVTop if event-driven instances exist *//* gtri - add - wbk - 12/19/90 - Add IPC stuff */        /* Send the operating point results for Mspice compatibility */        if(g_ipc.enabled) {            /* Call CKTnames to get names of nodes/branches used by BeginPlot */            /* Probably should free nameList after this block since called again... */            error = CKTnames(ckt,&numNames,&nameList);            if(error) return(error);            /* We have to do a beginPlot here since the data to return is */            /* different for the DCOP than it is for the AC analysis.  Moreover */            /* the begin plot has not even been done yet at this point... */            (*(SPfrontEnd->OUTpBeginPlot))((GENERIC *)ckt,(GENERIC*)ckt->CKTcurJob,                ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList,                IF_REAL,&acPlot);            ipc_send_dcop_prefix();            CKTdump(ckt,(double)0,acPlot);            ipc_send_dcop_suffix();            (*(SPfrontEnd->OUTendPlot))(acPlot);        }/* gtri - end - wbk */        ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;        error = CKTload(ckt);        if(error) return(error);        error = CKTnames(ckt,&numNames,&nameList);        if(error) return(error);        (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,                "frequency", UID_OTHER,(GENERIC **)NULL);        (*(SPfrontEnd->OUTpBeginPlot))((GENERIC *)ckt,(GENERIC*)ckt->CKTcurJob,                ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,                IF_COMPLEX,&acPlot);        freq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;    } else {    /* continue previous analysis */        freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq;        ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */    }    switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {    case DECADE:    case OCTAVE:        freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta *                 ((ACAN*)ckt->CKTcurJob)->ACstopFreq * ckt->CKTreltol;        break;    case LINEAR:        freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * ckt->CKTreltol;        break;    default:        return(E_BADPARM);    }/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */    g_mif_info.circuit.anal_init = MIF_TRUE;    /* Tell the code models what mode we're in */    g_mif_info.circuit.anal_type = MIF_AC;/* gtri - end - wbk */    while(freq <= ((ACAN*)ckt->CKTcurJob)->ACstopFreq+freqTol) {        if( (*(SPfrontEnd->IFpauseTest))() ) {             /* user asked us to pause via an interrupt */            ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = freq;            return(E_PAUSE);        }        ckt->CKTomega = 2 * PI *freq;        ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;        error = NIacIter(ckt);        if(error) return(error);        if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){            save = ckt->CKTmode;            ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG;            save1 = ckt->CKTsenInfo->SENmode;            ckt->CKTsenInfo->SENmode = ACSEN;            if(freq == ((ACAN*)ckt->CKTcurJob)->ACstartFreq){                ckt->CKTsenInfo->SENacpertflag = 1;            }            else{                ckt->CKTsenInfo->SENacpertflag = 0;            }            if(error = CKTsenAC(ckt)) return (error);            ckt->CKTmode = save;            ckt->CKTsenInfo->SENmode = save1;        }/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */        if(g_ipc.enabled)            ipc_send_data_prefix(freq);        error = CKTacDump(ckt,freq,acPlot);        if(g_ipc.enabled)            ipc_send_data_suffix();        if(error) return(error);/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */        /*  increment frequency */        switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {        case DECADE:        case OCTAVE:            freq *= ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;            if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==1) goto endsweep;            break;        case LINEAR:            freq += ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;            if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==0) goto endsweep;            break;        default:            return(E_INTERN);        }    }endsweep:    (*(SPfrontEnd->OUTendPlot))(acPlot);    return(0);}

⌨️ 快捷键说明

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