В прошлой статье мы рассмотрели азы составления SPICE-моделей электронных схем на совсем тривиальном примере. В этой статье постараемся углубить наши знания, изучив более сложные приемы анализа схем в симуляторе Ngspice.

1. Анализ схем на постоянном токе. Параметризация схемы

Закрепляя материал предыдущей статьи, построим более сложную схему, например такую

Для расчета токов в такой схеме придется уже изрядно попотеть, например составив и решив систему уравнений, например с применением законов Кирхгофа. Система уравнений будет состоять из трех узловых уравнений и трех контурных

\begin{align} &I_1-I_2-I_3=0,\\ &I_2 - I_4- I_6 = 0,\\ &I_5 + I_6 - I_1 = 0, \\ &I_1(R_1+R8) + I_3R_3 + I_5R_5 = E, \\ &I_2R_2 + I_4 R_4 - I_3R_3 = 0, \\& I_6(R_6 + R_7)-I_4R_4 - I_5R_5 = 0 \end{align}

Решая которую, или в ручную, или применяя любой математический пакет, можно получить значения токов во всех ветвях

I_1=0,71 \, А, I_2=0,34 \, А, I_3=0,38 \, А, I_4=0,11 \, А, I_5=0,49 \, А, I_6=0,22 \, А.

Теперь отдадим эту схему на съедение Ngspice, благо она уже к этому подготовлена, введением дополнительных узлов, предусматривающих включение в ветви нулевых источников-измерителей. Составим netlist

.title Test DC scheme

V1 1 0 DC 100
Vmeas1 1 2 0
R1 2 3 10
Vmeas2 3 4 0
R2 4 5 20
R3 3 6 30
Vmeas3 6 7 0
R4 5 8 40
Vmeas4 8 7 0
Vmeas5 7 9 0
R5 9 10 50
R6 12 11 60
Vmeas6 11 10 0
R7 5 12 70
R8 10 0 80

.op

.end

Выполним проверку схемы (listing), её расчет (run), выведем значения токов ветвях, воспользовавшись заботливо расставленными пробниками

ngspice 2 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Using SPARSE 1.3 as Direct Linear Solver
 Reference value :  0.00000e+00
No. of Data Rows : 1
ngspice 3 -> print i(Vmeas1) i(Vmeas2) i(Vmeas3) i(Vmeas4) i(Vmeas5) i(Vmeas6)
i(vmeas1) = 7.134457e-01
i(vmeas2) = 3.371227e-01
i(vmeas3) = 3.763230e-01
i(vmeas4) = 1.136809e-01
i(vmeas5) = 4.900039e-01
i(vmeas6) = 2.234418e-01
ngspice 4 ->

Как видим, результат аналогичен тому, что получен путем расчета по уравнениям Кирхгофа.

Какую еще информацию мы можем получить. Например, мы можем вывести величину потенциалов в узлах схемы, воспользовавшись конструкцией v(имя узла), например так

ngspice 5 -> print v(3) v(5) v(7) v(10)
v(3) = 9.286554e+01
v(5) = 8.612309e+01
v(7) = 8.157585e+01
v(10) = 5.707566e+01
ngspice 6 ->

Это потенциалы узлов 3, 5, 7 и 10 относительно выбранного нами нулевого узла. А можем ли мы получить падения напряжения на резисторах схемы? Легко, помня о том, что напряжение есть разность потенциалов, например для резистора R3 это будет выглядеть так

ngspice 6 -> print v(3) - v(6)
v(3) - v(6) = 1.128969e+01
ngspice 7 ->

то есть для вывода результатов мы можем применять математические выражения, что немаловажно для нас в дальнейшем. Нетрудно проверить и закон Ома, например для резистора R4

ngspice 7 -> print (v(5) - v(8))/40
(v(5) - v(8))/40 = 1.136809e-01
ngspice 8 ->

получаем то же значение тока, что выводили ранее. Воспользовавшись возможностью применения арифметических операций, мы можем определить, например, эквивалентное сопротивление данной схемы

ngspice 8 -> print v(1) / i(Vmeas1)
v(1) / i(vmeas1) = 1.401648e+02
ngspice 9 ->

Важным аспектом организации SPICE-моделей является так называемая параметризация. Вместо использования конкретных числовых значений, мы можем ввести переменные, хранящие данные значения, и связать параметры между собой, используя арифметические операции. Ввод параметров выполняется с помощью директивы .param. Например так

.title Test DC scheme

.param R1=10 R2=20 R3=30 R4=40 R5=50 R6=60 R7=70 R8=80

V1 1 0 DC 100
Vmeas1 1 2 0
R1 2 3 {R1}
Vmeas2 3 4 0
R2 4 5 {R2}
R3 3 6 {R3}
Vmeas3 6 7 0
R4 5 8 {R4}
Vmeas4 8 7 0
Vmeas5 7 9 0
R5 9 10 {R5}
R6 12 11 {R6}
Vmeas6 11 10 0
R7 5 12 {R7}
R8 10 0 {R8}

.op

.end

Значения параметров подставляются в описание элементов схемы в фигурных скобках. Мы получим тот же результат

ngspice 3 -> print i(Vmeas1) i(Vmeas2) i(Vmeas3) i(Vmeas4) i(Vmeas5) i(Vmeas6)
i(vmeas1) = 7.134457e-01
i(vmeas2) = 3.371227e-01
i(vmeas3) = 3.763230e-01
i(vmeas4) = 1.136809e-01
i(vmeas5) = 4.900039e-01
i(vmeas6) = 2.234418e-01
ngspice 4 ->

Теперь мы можем использовать параметр вместо повторяющегося значения, задав его однажды, а так же связать параметры между собой, например сделать так чтобы сопротивление R2 всегда было в 2 раза больше сопротивления R1

.param R1=10 R2=2*R1 R3=30 R4=40 R5=50 R6=60 R7=70 R8=80

записав значение R2 в форме выражения. Выражения можно использовать и внутри фигурных скобок в описании элементов

R3 3 6 {3*R1}

Параметризация схемы открывает широкие возможности, и создание сложных SPICE-моделей без параметризации невозможно.

Побаловавшись с постоянным током и твердо освоив .op-анализ, перейдем к другим аспектам SPICE-моделирования.

2. Анализ переходных процессов в цепях постоянного тока

Рассмотрим такую схему

Попробуем смоделировать переходный процесс в этой цепи, полагая что в начальный момент времени ток в ней не тек. Результат, конечно же, очевиден - ток будет нарастать экспоненциально, с постоянной времени T = L / R = 10 мс, и ассимптотически приближаться к значению E / R = 5 А. Заставим Ngspice показать нам данный переходный процесс на графике.

Построим модель следующим образом

*
* Переходный процесс в LR-цепи
*

.title LR-circuit demo

*
* Параметры модели
*
.param E=100 L=200m R=20

*
* Структурное описание схемы
*
V1 in 0 DC {E}
L1 in out {L}
Vmeas out 1 0
R1 1 0 {R}

*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 50m uic

.end

Кстати, обратим внимание на то, что некоторые узлы схемы заданы не номерами, а символическими именами. Это допускается синтаксисом, и может служить удобным способом обозначать важные узлы схемы. Узел 1 добавлен для врезки в цепь измерителя тока Vmeas.

Новой здесь является директива .tran, задающая анализ переходного процесса (Transient Analysis). Полный её синтаксис выглядит так

.tran tstep tstop <tstart <tmax>> <uic>

где

  • tstep - шаг интегрирования

  • tstop - конечное время интегрирования

  • tstart - начальное время интегрирования

  • tmax - максимальный шаг интегрирования. Если он не задан, симулятор принимает его равным (tstop - tstart) / 50

  • uic - признак того, что выполняется анализ переходного процесса, с начальными условиями, по умолчанию - нулевыми

Параметры, указанные в треугольных скобках могут быть опущены.

Данная директива предписывает симулятору составить и решить систему дифференциальных уравнений относительно потенциалов в узлах схемы. Испробуем это, однако теперь нам потребуется построить график, поэтому запускаем графический вариант Ngspice

D:\work\Projects\ngspice>ngspice LR-scheme.cir

и мы увидим вот такое окно

внизу которого есть поле для ввода команд. Запускаем симуляцию

Circuit: LR-circuit demo

ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Using SPARSE 1.3 as Direct Linear Solver
Operating point simulation skipped by 'uic',
  now using transient initial conditions.

No. of Data Rows : 5011
ngspice 2 ->

Нам сообщают, что проведен анализ при температуре 27 градусов Цельсия, тип использованного решателя ОДУ, указывается на то, что расчет рабочей точки по постоянному току пропущен, благодаря указанию параметра uic и используются начальные условия. Так как начальных условий мы не задали, они полагаются нулевыми. Далее выводится число точек (во времени) для которых произведен расчет по всем узлам схемы - 5011. Как получить график? Даем команду

ngspice 2 -> plot i(Vmeas)
ngspice 3 ->

и возникает графическое окно с графиком зависимости тока в цепи от времени.

Мы задали время моделирования 50 мс, равное пяти постоянным времени данной цепи и выполнили интегрирование с шагом 10 мкс, это заложено в настройки анализа

.tran 10u 50m uic

Обратим внимание на то, что допускается применение десятичных приставок: m означает "мили", u - "микро". Подробный список десятичных приставок можно увидеть в документации в Ngspice, не будем подробно останавливаться на этом.

Если требуется получить таблицу данных, даем команду

ngspice 3 -> print i(Vmeas) > results.txt
ngspice 4 ->

Получая файл results.txt следующего содержания (фрагмент)

                                LR-circuit demo
                                Transient Analysis  Mon Sep 22 16:04:01  2025
--------------------------------------------------------------------------------
Index   time            i(Vmeas)        
--------------------------------------------------------------------------------
0	1.000000e-07	2.000030e+00	
1	2.000000e-07	2.000060e+00	
2	4.000000e-07	2.000120e+00	
3	8.000000e-07	2.000240e+00	
4	1.600000e-06	2.000480e+00	
5	3.200000e-06	2.000960e+00	
6	6.400000e-06	2.001919e+00	
7	1.000000e-05	2.002999e+00	
8	1.064000e-05	2.003190e+00	
9	1.192000e-05	2.003574e+00	
10	1.448000e-05	2.004341e+00	
11	1.960000e-05	2.005874e+00	
12	2.960000e-05	2.008867e+00	
13	3.960000e-05	2.011857e+00	
14	4.960000e-05	2.014843e+00	
15	5.960000e-05	2.017827e+00	
16	6.960000e-05	2.020808e+00	
17	7.960000e-05	2.023785e+00	
18	8.960000e-05	2.026760e+00	
19	9.960000e-05	2.029732e+00	
20	1.096000e-04	2.032700e+00	
21	1.196000e-04	2.035666e+00	
22	1.296000e-04	2.038629e+00	
23	1.396000e-04	2.041589e+00	
24	1.496000e-04	2.044546e+00	
25	1.596000e-04	2.047500e+00	
26	1.696000e-04	2.050451e+00	
27	1.796000e-04	2.053399e+00	
28	1.896000e-04	2.056344e+00	
29	1.996000e-04	2.059286e+00

который затем можно использовать для обработки результатов расчета сторонними средствами.

А что если нам нужны ненулевые начальные условия? Их можно задать для всех реактивных элементов схемы, написав например следующее

L1 in out {L} ic=2.0

В описании индуктивности это означает начальную величину тока, протекающего в ней. Получаем следующий результат

Как видим, нарастание тока в цепи начинается с 2 ампер. Аналогично можно проиллюстрировать затухание тока. Для этого зададим его начальное значение, а источник либо уберем из схемы, либо обнулим его напряжение

*
* Переходный процесс в LR-цепи
*

.title LR-circuit demo

*
* Параметры модели
*
.param E=0 L=200m R=20

*
* Структурное описание схемы
*
V1 in 0 DC {E}
L1 in out {L} ic=10.0
Vmeas out 1 0
R1 1 0 {R}

*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 50m uic

.print v(out)

.end

Как видно, описание индуктивности начинается с литеры "L" и похоже на описание резистора. Конечно, как и у резистора, параметров намного больше, но нет смысла останавливаться на этом, я позволю себя отослать читателя к документации.

Аналогично можно выполнить анализ переходных процессов с емкостью. Следующая модель иллюстрирует процесс заряда конденсатора

*
* Переходный процесс в LR-цепи
*

.title RC-circuit demo

*
* Параметры модели
*
.param E=100 C=1000u R=20

*
* Структурное описание схемы
*
V1 in 0 DC {E}
R1 in out {R} 
Vmeas out 1 0
C1 1 0 {C}

*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 100m uic

.end
Circuit: RC-circuit demo

ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Using SPARSE 1.3 as Direct Linear Solver
Operating point simulation skipped by 'uic',
  now using transient initial conditions.

No. of Data Rows : 10011
ngspice 2 -> plot v(out) i(Vmeas)
ngspice 3 -> 

или его разряд, при задании напряжения источника равным нулю, а начально напряжения конденсатора через начальные условия симуляции

C1 1 0 {C} ic=200

Как видим, не смотря на очевидную низкоуровневость, в данном случае всё довольно просто, и легко распространяется на более сложные цепи.

3. Анализ цепей на переменном токе. Построение частотных характеристик

Не составит труда подать синусоидальное переменное напряжение на ту же цепь с катушкой и резистором.

Для этого предусмотрен специальный тип источника напряжения

*
* Переходный процесс в LR-цепи
* при синосоидальном входном напряжении
*

.title LR-circuit demo

*
* Параметры модели
*
.param Um=100 L=200m R=20 f=50

*
* Структурное описание схемы
*
V1 in 0 sin(0 {Um} {f})
L1 in out {L}
Vmeas out 1 0
R1 1 0 {R}

*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 100m

.end

Инструкцией в строке 15 мы задаем источник синусоидального напряжения с постоянной составляющей равной 0, амплитудой E=100 В и частотой f = 50 Гц. И получить графики напряжения на входе и выходе схемы

Однако, рассмотрение этого процесса во временной области малоинтересно. Гораздо больший интерес представляет собой реакция схемы на подачу напряжения произвольной частоты. Такую информацию дают нам амплитудные (АЧХ) и фазовые (ФЧХ) частотные характеристики. Ngspice предоставляет инструменты для их построения. Для этого составим такую модель

*
* Построение АЧХ и ФЧХ для LR-цепи
*

.title LR AC-analysis

*
* Параметры модели
*
.param L=200m R=20

*
* Структурное описание схемы
*
V1 in 0 dc 0 ac 1
L1 in out {L} 
Vmeas out 1 0
R1 1 0 {R}

*
* Вид моделирования - анализ на переменном токе
*
.ac lin 1000 0.01 1k

.end

Обратите внимание на описание источника

V1 in 0 dc 0 ac 1

Указывается имя источника, узлы его подключения, уточняется что отсутствует постоянная составляющая (dc 0) и указывается амплитуда переменной составляющей (ac 1) равная 1 В. При этом полагается что напряжение является синусоидальным переменной частоты, которая задается в режиме моделирования

.ac lin 1000 0.01 1k

Здесь указывается что следует выполнить малосигнальный анализ схемы на переменном токе (.ac) с линейным отображением амплитуды (lin). Далее указывается количество точек на графике (1000) и диапазон частот, данном случае от 0.01 до 1000 Гц. Загрузив модель и выполнив симуляцию, мы можем построить АЧХ и ФЧХ, за что отвечает команда в 7 строке

ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Using SPARSE 1.3 as Direct Linear Solver

No. of Data Rows : 1000
ngspice 2 -> plot v(out) phase(v(out))
ngspice 3 -> 

Такой график выглядит не сильно презентабельно, так как АЧХ и ФЧХ лучше изображать в логарифмическом масштабе по оси частот. Это легко сделать, указав это требование в команде построения графиков параметром xlog (логарифмический масштаб по оси абсцисс)

ngspice 3 -> plot v(out) phase(v(out)) xlog
ngspice 4 ->

получая вполне узнаваемые кривые.

Заключение и выводы

Мы довольно бегло пробежались по основным возможностям симулятора Ngspice. Использовать его напрямую можно, но всё же не совсем удобно. Лучше, всё же применять его в качестве бэкэнда в составе более дружественных к пользователю симуляторов, например Qucs-S. Целью всего этого повествования является освоение базового синтаксиса Ngspice. Я умышленно упустил описание анализа схем на постоянном токе с построением разверток (DC Transfer Function), задаваемый директивой .dc. Более наглядно его применение выглядит при исследовании характеристик полупроводниковых приборов. А к полупроводниковым прибором мы закономерно придем уже в следующей статье. Так что благодарю читателей за внимание и до новых встреч!

Комментарии (0)


  1. engine9
    23.09.2025 07:47

    Спасибо за методический материал, тема очень интересная.