Симуляция схем на ОУ в ngSpice
kayo — Втр, 22/03/2016 - 18:29
Симуляторы электронных схем незаменимы в разработке железа, поскольку позволяют верифицировать предварительные расчёты с использованием моделей электронных компонентов, которые ведут себя подобно железным экземплярам. Традиционно для симуляции применяют программы, подобные симулятору Spice. Мы уже коснулись работы с ним в одной из прошлых статей, теперь же попробуем сотворить более сложные вещи.
Мы будем решать довольно простую, но практически значимую задачу: задачу измерения тока с использованием АЦП. А конкретно, аппаратную часть этой задачи: снятие сигнала с шунта и приведение к требуемому диапазону. Будет парочка схемотехнических хитростей, немного Maxima, жестокая правда жизни и чуть больше ngSpice.
Что имеем
Предположим, у нас есть некий источник питания, гальванически развязанный от всего остального. Мы хотели бы подключить к нему шунт (допустим, 10 мОм), и мерить падение напряжения на нём для косвенного измерения тока. Для начала определимся с пределами изменений, пусть это будет 0...48A. То есть, если наш блок питания способен обеспечить 48V, то при подключении нагрузки 1 Ом, мы получим предельный измеряемый ток. По закону Георгия Семёновича Ома можно прикинуть, что падение напряжения на шунте при 48A составит 0.48V (0.01 Ом x 48A), а значит входной сигнал будет меняться в диапазоне 0...0.48V.
С другой стороны мы имеем аналого-цифровой преобразователь в кристалле микроконтроллера, который позволяет измерять сигнал в диапазоне 0...Vaa. В нашел микроконтроллере АЦП 12-битный, а Vaa = Vcc = 3.3V. Таким образом нам необходимо привести измеряемый сигнал к диапазону 0...3.3V, что в программе даст нам значения 0...2^12-1. На самом деле мы вряд ли сможем строго привести сигнал к этому диапазону, но это и не нужно, достаточно близко вписаться в него. Сразу можно прикинуть цену деления результирующего амперметра: 48 / (2^12-1) ~ 10mA.
Реализация
Шаг первый
Итак, начнём веселье. Немного почесав репу, можем накидать вот такую схему:
Источник питания V1 питает операционный усилитель (питание одно-полярное), а V2 питает некую нагрузку R5 через шунт R7, на котором мы будем мерить. Я использовал кусочно-линейный источник питания, значение напряжения которого линейно возрастает от 0 до 48 вольт в течении 20 мс. Это позволит нам посмотреть, как будет меняться сигнал на всём измеряемом диапазоне.
В подключении шунта есть хитрость, которая потребовалась, чтобы на выходе источника земля не парила в воздухе между шунтом и нагрузкой, как некоторые товарищи делают для простоты. Поскольку у нас источник гальванически не связан по земле со схемой, то нам ничто не мешает организовать землю на выходе по-нормальному. Таким образом, напряжение на шунте мы будем измерять в диапазоне 0...-0.48. Поэтому, для измерения применена инвертирующая схема включения операционного усилителя.
Я накидал в максиме формулы для расчёта усилительного каскада для идеального ОУ:
/* Pre-Amp: (maxima) */ EQ[1]: U[out] = -U[in] * R[1]/R[2]$ EQ[3]: EQ[1], U[in]=U[in(max)], U[out]=U[out(max)]$ /* будем искать R[2], задав R[1] */ EQ[4]: solve(EQ[3], R[1])[1]; /* неизменные параметры */ PR[1]: [U[in(min)]=0.0, U[in(max)]=-0.48, R[2]=10e3]$ /* считаем R[1] для максимального напряжения на выходе */ EQ[4], PR[1], U[out(max)]=3.3; /* берём ближайшее значение R[1] и считаем напряжение на выходе */ EQ[3], PR[1], R[1]=68e3;
Вот как посчиталось:
$${R}_{1}=−\frac{{R}_{2}\,{U}_{\mathrm{out}\left( max\right) }}{{U}_{\mathrm{in}\left( max\right) }}$$
$${R}_{1}=68750.0$$
$${U}_{\mathrm{out}\left( max\right) }=3.264$$
Для симуляции мы используем модель операционного усилителя LM358 от инженеров из Texas Instruments. Также я пробовал модель этого же ОУ от ON Semiconductor, но отличия между ними оказались пренебрежимо малы. Итак, казалось бы всё замечательно, но сперва попробуем симуляцию. Как обычно, экспортируем список цепей из редактора схем KiCAD и запускаем симуляцию. На выходе получатся такие графики:
Как видим, всё не так хорошо, как бы хотелось: в начале диапазона на выходе присутствует клюшка. Давайте приблизим и посмотрим это место:
Теперь видно, что на выходе имеется выраженная нелинейность и смещение где-то +0.06V. Быть может это не так уж и страшно? Прикинем: 0.06 / 3.3 = a / 48, a ~ 0.87A. Не мало, а ведь мы хотим достаточно точно мерить от нуля. Тут есть два пути решения проблемы:
1. Программный: использовать полиномиальную интерполяцию вместо линейной для этого начального куска характеристики.
2. Аппаратный: сделать что-нибудь с этим смещением путём нехитрых манипуляций с операционными усилителями.
Поскольку эта статья о железе, мы, разумеется, пойдём по второму пути.
Шаг второй
Итак, раз реальный операционник не может работать линейно со значениями, близкими к +V и -V, то нужно организовать смещение, то есть переместить реальную область работы куда-то за +0.1V. Поскольку у нас инвертирующий усилитель и не инвертирующий вход лежит на земле, то нет ничего проще, чем поднять его немного выше земли с помощью делителя напряжения как то так:
Вот расчёт этого каскада на максиме:
EQ[1]: U[p] = U[cc] * R[3] / (R[3] + R[4])$ EQ[2]: U[n] = (U[out] - U[in]) * R[2] / (R[2] + R[1]) + U[in]$ EQ[3]: EQ[2], U[n] = U[p], EQ[1]$ EQ[4]: EQ[3], U[in]=U[in(min)], U[out]=U[out(min)]$ EQ[5]: EQ[3], U[in]=U[in(max)], U[out]=U[out(max)]$ EQ[6]: solve(EQ[5], U[out(max)])[1]; EQ[7]: solve(EQ[5], R[1])[1]; EQ[8]: solve(EQ[1], R[4])[1]; EQ[9]: solve(EQ[4], U[out(min)])[1]$ /* задаём известные параметры */ PR[1]: [U[in(min)]=0.0, U[in(max)]=-0.48, U[cc]=5, R[2]=10e3, R[3]=1e3]$ /* прикидываем R[4] */ EQ[8], PR[1], U[p]=0.1; PR[2]: [R[4]=47e3]$ /* считаем смещение U[p] */ EQ[1], PR[1], PR[2]; /* считаем R[1] */ EQ[7], PR[1], PR[2], U[out(max)]=3.3; PR[3]: [R[1]=56e3]$ /* считаем V[out(max)] */ EQ[6], PR[1], PR[2], PR[3]; /* считаем V[out(min)] */ EQ[9], PR[1], PR[2], PR[3];
И посчитанный результат:
$${U}_{\mathrm{out}\left( max\right) }=−\frac{\left( {R}_{1}\,{R}_{4}+{R}_{1}\,{R}_{3}\right) \,{U}_{\mathrm{in}\left( max\right) }+\left( −{R}_{2}−{R}_{1}\right) \,{R}_{3}\,{U}_{cc}}{{R}_{2}\,{R}_{4}+{R}_{2}\,{R}_{3}}$$
$${R}_{1}=−\frac{\left( {R}_{2}\,{R}_{4}+{R}_{2}\,{R}_{3}\right) \,{U}_{\mathrm{out}\left( max\right) }−{R}_{2}\,{R}_{3}\,{U}_{cc}}{\left( {R}_{4}+{R}_{3}\right) \,{U}_{\mathrm{in}\left( max\right) }−{R}_{3}\,{U}_{cc}}$$
$${R}_{4}=−\frac{{R}_{3}\,{U}_{p}−{R}_{3}\,{U}_{cc}}{{U}_{p}}$$
$${R}_{4}=49000.0$$
$${U}_{p}=0.1041666666666666$$
$${R}_{1}=54707.56062767475$$
$${U}_{\mathrm{out}\left( max\right) }=3.3755$$
$${U}_{\mathrm{out}\left( min\right) }=0.6875$$
Запустим симуляцию и посмотрим графики:
Как видим, теперь всё линейно, однако появилась новая проблема: из-за усиления минимальное значение смещено относительно нуля более чем на 600mV. И здесь у нас снова есть два варианта, как поступить:
1. Пожертвовать разрешением. Мы можем просто измерять в диапазоне 0.6...3.3V, в этом случае никаких преобразований сигнала делать не требуется.
2. Сместить и отмасштабировать аналоговый сигнал к нужному диапазону.
Поскольку в корпусе LM358 имеются два операционных усилителя, а мы задействовали только один и второй нам для других целей не нужен, то пойдём вторым путём.
Шаг третий
Итак, теперь у нас будет задействовано два каскада: первый реализует инвертированное усиление, второй - масштабирование и сдвиг к требуемому диапазону. Вот как теперь выглядит наша схема:
Я несколько снизил усиление первого каскада, чтобы соотношения элементов второго каскада не были слишком уж экстремальны. Здесь можно показать анализ схемы второго каскада по методу Густава Робертовича Кирхгофа в максиме:
/* сигналы на прямом и инверсном входах равны */ EQ[1]: U[n] = U[p]; /* сигнал на инверсном через ток от земли по R[2] */ EQ[2]: U[n] = I[R[2]] * R[2]; /* далее ток распределяется по двум путям */ EQ[3]: I[R[2]] = I[R[1]] + I[R[3]]; /* первый путь через R[1] */ EQ[4]: I[R[1]] = (U[cc] - U[n]) / R[1]; /* второй путь через R[3] */ EQ[5]: I[R[3]] = (U[out] - U[n]) / R[3]; /* скидываем всё в кучу */ EQ[6]: EQ[2], EQ[3], EQ[4], EQ[5], EQ[1]; /* решаем относительно U[out] и упрощаем */ EQ[7]: expand(solve(EQ[6], U[out])[1]);
Вот полученное решение:
$${U}_{n}={U}_{p}$$
$${U}_{n}={R}_{2}\,{I}_{{R}_{2}}$$
$${I}_{{R}_{2}}={I}_{{R}_{3}}+{I}_{{R}_{1}}$$
$${I}_{{R}_{1}}=\frac{{U}_{cc}−{U}_{n}}{{R}_{1}}$$
$${I}_{{R}_{3}}=\frac{{U}_{out}−{U}_{n}}{{R}_{3}}$$
$${U}_{p}={R}_{2}\,\left( \frac{{U}_{out}−{U}_{p}}{{R}_{3}}+\frac{{U}_{cc}−{U}_{p}}{{R}_{1}}\right)$$
$${U}_{out}=\frac{{R}_{3}\,{U}_{p}}{{R}_{2}}+\frac{{R}_{3}\,{U}_{p}}{{R}_{1}}+{U}_{p}−\frac{{R}_{3}\,{U}_{cc}}{{R}_{1}}$$
Теперь вычислим параметры первого каскада:
/* Stage A: (maxima) */ EQ[1]: U[p] = U[cc] * R[3] / (R[3] + R[4])$ EQ[2]: U[n] = (U[out] - U[in]) * R[2] / (R[2] + R[1]) + U[in]$ EQ[3]: EQ[2], U[n] = U[p], EQ[1]$ EQ[4]: EQ[3], U[in]=U[in(min)], U[out]=U[out(min)]$ EQ[5]: EQ[3], U[in]=U[in(max)], U[out]=U[out(max)]$ EQ[6]: solve(EQ[5], U[out(max)])[1]; EQ[7]: solve(EQ[5], R[1])[1]; EQ[8]: solve(EQ[1], R[4])[1]; EQ[9]: solve(EQ[4], U[out(min)])[1]$ PR[1]: [U[in(min)]=0.0, U[in(max)]=-0.48, U[cc]=5, R[2]=10e3, R[3]=1e3]$ EQ[8], PR[1], U[p]=0.12; PR[2]: [R[4]=39e3]$ EQ[1], PR[1], PR[2]; EQ[7], PR[1], PR[2], U[out(max)]=2.0; PR[3]: [R[1]=33e3]$ EQ[6], PR[1], PR[2], PR[3]; EQ[9], PR[1], PR[2], PR[3];
Результат:
$${U}_{\mathrm{out}\left( max\right) }=−\frac{\left( {R}_{1}\,{R}_{4}+{R}_{1}\,{R}_{3}\right) \,{U}_{\mathrm{in}\left( max\right) }+\left( −{R}_{2}−{R}_{1}\right) \,{R}_{3}\,{U}_{cc}}{{R}_{2}\,{R}_{4}+{R}_{2}\,{R}_{3}}$$
$${R}_{1}=−\frac{\left( {R}_{2}\,{R}_{4}+{R}_{2}\,{R}_{3}\right) \,{U}_{\mathrm{out}\left( max\right) }−{R}_{2}\,{R}_{3}\,{U}_{cc}}{\left( {R}_{4}+{R}_{3}\right) \,{U}_{\mathrm{in}\left( max\right) }−{R}_{3}\,{U}_{cc}}$$
$${R}_{4}=−\frac{{R}_{3}\,{U}_{p}−{R}_{3}\,{U}_{cc}}{{U}_{p}}$$
$${R}_{4}=40666.66666666667$$
$${U}_{p}=0.125$$
$${R}_{1}=30991.73553719008$$
$${U}_{\mathrm{out}\left( max\right) }=2.1215$$
$${U}_{\mathrm{out}\left( min\right) }=0.5375$$
И наконец вычислим второй каскад:
/* Stage B (maxima) */ EQ[1]: U[out] = U[in] * (1 + R[3]/R[2] + R[3]/R[1]) - U[cc] * R[3]/R[1]$ EQ[2]: EQ[1], U[in]=U[in(min)], U[out]=U[out(min)]$ EQ[3]: EQ[1], U[in]=U[in(max)], U[out]=U[out(max)]$ EQ[4]: [EQ[2], EQ[3]]; EQ[5]: solve(EQ[4], [R[1], R[2]])[1]; PR[1]: [U[in(min)]=0.54, U[in(max)]=2.12, U[cc]=5.0]$ PR[2]: [U[out(min)]=0.1, U[out(max)]=3.3]$ PR[3]: [R[3]=4.7e3]$ EQ[5], PR[1], PR[2], PR[3]; PR[4]: [R[1]=22e3, R[2]=5.6e3]$ EQ[4], PR[1], PR[3], PR[4];
Результат вычисления:
$$[{U}_{\mathrm{out}\left( min\right) }=\left( \frac{{R}_{3}}{{R}_{2}}+\frac{{R}_{3}}{{R}_{1}}+1\right) \,{U}_{\mathrm{in}\left( min\right) }−\frac{{R}_{3}\,{U}_{cc}}{{R}_{1}},{U}_{\mathrm{out}\left( max\right) }=\left( \frac{{R}_{3}}{{R}_{2}}+\frac{{R}_{3}}{{R}_{1}}+1\right) \,{U}_{\mathrm{in}\left( max\right) }−\frac{{R}_{3}\,{U}_{cc}}{{R}_{1}}]$$
$$[{R}_{1}=\frac{{R}_{3}\,{U}_{cc}\,{U}_{\mathrm{in}\left( min\right) }−{R}_{3}\,{U}_{cc}\,{U}_{\mathrm{in}\left( max\right) }}{{U}_{\mathrm{in}\left( max\right) }\,{U}_{\mathrm{out}\left( min\right) }−{U}_{\mathrm{out}\left( max\right) }\,{U}_{\mathrm{in}\left( min\right) }},{R}_{2}=−\frac{{R}_{3}\,{U}_{cc}\,{U}_{\mathrm{in}\left( min\right) }−{R}_{3}\,{U}_{cc}\,{U}_{\mathrm{in}\left( max\right) }}{\left( {U}_{\mathrm{in}\left( max\right) }−{U}_{cc}\right) \,{U}_{\mathrm{out}\left( min\right) }+\left( {U}_{cc}−{U}_{\mathrm{out}\left( max\right) }\right) \,{U}_{\mathrm{in}\left( min\right) }+{U}_{cc}\,{U}_{\mathrm{out}\left( max\right) }−{U}_{cc}\,{U}_{\mathrm{in}\left( max\right) }}]$$
$$[{R}_{1}=23649.68152866242,{R}_{2}=5686.064318529864]$$
$$[{U}_{\mathrm{out}\left( min\right) }=0.04039610389610404,{U}_{\mathrm{out}\left( max\right) }=3.284012987012986]$$
Осталось запустить симуляцию и проверить работу схемы:
У нас получилась практически линейная характеристика в заданных пределах с небольшим заданным смещением от нуля. мы не пожертвовали разрешением и диапазоном, а также нам не потребуется усложнять программную обработку результатов оцифровки сигнала по причине нелинейности характеристики.
Выводы
На практике не всегда можно однозначно сделать выбор в пользу усложнения электронной схемы или программы. Всё зависит от соотношения требований и возможностей. Но предпочтение следует отдавать аппаратной обработке, ибо не всегда можно исправить программно то, что было плохо реализовано в железе.
На этом всё, товарищи. Прикладываю файлы KiCAD-а: схемы под номерами 1 и 2 содержат соответственно первый и второй вариант схемы, а схема без номера третий финальный вариант.
Вложение | Размер |
---|---|
sense.sim.tar.xz | 5.35 КБ |

Отправить комментарий