Искусство схемотехники - практикум: Полосовой RC-фильтр
Полосовой RC-фильтр для выделения частотного диапазона
В этом примере рассчитывается и проверяется пассивный полосовой RC-фильтр для диапазона примерно от 0.75 кГц до 16 кГц. В скрипте показаны расчет номиналов, построение ожидаемой амплитудно-частотной характеристики, запуск готовых моделей Engee и сравнение сигнальной модели с физической электрической цепью.
Введение
Этот пример описывает ход решения задачи
2W1.2 - Полоса пропускания
из книги
Томас К. Хейс, Пол Хоровиц
Искусство схемотехники: Теория и практика
путем компьютерного моделирования в Engee.
По задаче требуется получить фильтр, который ослабляет слишком низкие частоты, пропускает рабочий диапазон и снова ослабляет высокочастотную составляющую.
Практически такой фильтр можно собрать из двух простых RC-звеньев. Низкочастотную границу задает звено верхних частот, а высокочастотную границу задает звено нижних частот. Важно выбирать сопротивления так, чтобы следующий каскад не перегружал предыдущий.
Теоретическая справка
Для звена нижних частот первого порядка используется передаточная функция
Для звена верхних частот первого порядка:
Если считать каскады слабо связанными по нагрузке, полосовой фильтр описывает произведение:
Граничные частоты каждого RC-звена оцениваются как
В физической модели выходной резистор верхнечастотного звена имеет сопротивление 1 МОм. Поэтому для нижней границы полезно учитывать эквивалентное сопротивление:
Расчет параметров
В этой ячейке задайте сопротивления каскадов, целевые частоты и стандартные емкости. Затем сравните расчетные частоты границ с требуемым диапазоном.
R_LP = 10_000.0
C_LP = 1e-9
R_HP = 100_000.0
C_HP = 2e-9
R_load = 1_000_000.0
f_low_target = 750.0
f_high_target = 16_000.0
parallel(R1, R2) = 1 / (1 / R1 + 1 / R2)
R_HP_loaded = parallel(R_HP, R_load)
f_lp = 1 / (2pi * R_LP * C_LP)
f_hp_ideal = 1 / (2pi * R_HP * C_HP)
f_hp_loaded = 1 / (2pi * R_HP_loaded * C_HP)
C_LP_exact = 1 / (2pi * f_high_target * R_LP)
C_HP_exact = 1 / (2pi * f_low_target * R_HP)
calculation_summary = (;
R_LP,
C_LP,
f_lp,
R_HP,
C_HP,
f_hp_ideal,
R_HP_loaded,
f_hp_loaded,
C_LP_exact,
C_HP_exact,
)
calculation_summary
Номинал 1 нФ для звена нижних частот дает верхнюю границу около 15.9 кГц. Номинал 2 нФ для звена верхних частот дает нижнюю границу около 796 Гц без нагрузки и около 875 Гц при нагрузке 1 МОм. Для учебного RC-фильтра это близко к требуемой полосе.
Описание моделей
Для проверки подготовлены две модели Engee.
RCBandPass_2W_1_2_signal.engee— сигнальная модель с блокамиTransfer Fcn. Она сравнивает идеальную каскадную передаточную функцию и приближение с нагрузкой 1 МОм.RCBandPass_2W_1_2_phys.engee— физическая acausal-модель. В ней источник напряжения питает RC-цепь: сначала стоит звено нижних частот 10 кОм + 1 нФ, затем звено верхних частот 2 нФ + 100 кОм, а на выход подключена нагрузка 1 МОм.
На вход подается сумма трех синусоид: низкая частота 200 Гц, частота в полосе 3 кГц и высокая частота 30 кГц. Такой сигнал помогает увидеть, какие составляющие фильтр подавляет, а какую пропускает.

.png)
Подготовка окружения
В этой ячейке задайте пути к готовым моделям и папку для файлов результатов. Если вы запускаете пример из другой директории, измените переменную dir.
using Plots
dir = @__DIR__
output_dir = dir
model_paths = Dict(
:signal => joinpath(dir, "RCBandPass_2W_1_2_signal.engee"),
:physical => joinpath(dir, "RCBandPass_2W_1_2_phys.engee"),
)
string("prepared; dir=", dir)
Окружение готово: модели лежат рядом со скриптом, а новые графики и таблицы будут сохраняться в ту же папку.
Аналитическая проверка
Перед запуском моделей постройте расчетную амплитудно-частотную характеристику. Она показывает ожидаемую полосу пропускания и влияние нагрузки на нижнюю границу.
freqs = exp10.(range(log10(10.0), log10(100_000.0), length = 800))
gain_bp(f, R_hp) = begin
tau_lp = R_LP * C_LP
tau_hp = R_hp * C_HP
omega = 2pi * f
(omega * tau_hp) / sqrt((1 + (omega * tau_hp)^2) * (1 + (omega * tau_lp)^2))
end
p_response = plot(
freqs,
20 .* log10.(gain_bp.(freqs, R_HP));
xscale = :log10,
label = "без нагрузки",
xlabel = "Частота, Гц",
ylabel = "Амплитуда, дБ",
title = "Расчетная АЧХ полосового RC-фильтра",
)
plot!(p_response, freqs, 20 .* log10.(gain_bp.(freqs, R_HP_loaded)); label = "Rн = 1 МОм")
vline!(p_response, [750.0, 16_000.0]; label = "границы задания", linestyle = :dash)
hline!(p_response, [-3.0]; label = "-3 дБ", linestyle = :dot)
response_path = joinpath(output_dir, "rc_bandpass_response.png")
savefig(p_response, response_path)
p_response
График показывает подъем характеристики после нижней границы и спад после верхней. Нагрузка 1 МОм немного смещает нижнюю границу вверх, потому что она параллельно уменьшает сопротивление выходного плеча верхнечастотного каскада.
Симуляция модели
Теперь загрузите сигнальную модель и запустите симуляцию. Код использует программное управление Engee: engee.load, engee.open, engee.run и engee.close.
missing_models = [path for path in values(model_paths) if !isfile(path)]
if isempty(missing_models)
signal_payload = Core.eval(Main, quote
model = engee.load($(model_paths[:signal]); force = true)
engee.open(model)
results = engee.run(model)
engee.close(model; force = true)
(; results, result_text = repr(results))
end)
signal_results = signal_payload.results
string("signal model simulated; results=", signal_payload.result_text)
else
string("missing_models=", join(missing_models, ";"))
end
Сигнальная модель возвращает входной сигнал, выход идеального полосового фильтра и выход приближения с нагрузкой 1 МОм.
Проверка физической модели
Запустите физическую модель. Она проверяет ту же идею как электрическую цепь с источником напряжения, резисторами, конденсаторами, электрической землей, датчиком напряжения и блоком Solver Configuration.
physical_payload = Core.eval(Main, quote
model = engee.load($(model_paths[:physical]); force = true)
engee.open(model)
results = engee.run(model)
engee.close(model; force = true)
(; results, result_text = repr(results))
end)
physical_results = physical_payload.results
string("physical model simulated; results=", physical_payload.result_text)
Физическая модель выполнена успешно: выходное напряжение записывается датчиком.
Анализ результатов симуляции
Постройте временные графики сигнальной модели. Они показывают, как из суммы трех гармоник сигнала остается преимущественно составляющая в полосе пропускания.
function series_from_result(results, key)
df = results[key]
return df.time, df.value
end
time, input_signal = series_from_result(signal_results, "input_sum.1")
_, y_ideal = series_from_result(signal_results, "bp_ideal.1")
_, y_load = series_from_result(signal_results, "bp_load_1M.1")
p_time = plot(
time .* 1000,
input_signal;
label = "вход",
xlabel = "Время, мс",
ylabel = "Напряжение, отн. ед.",
title = "Фильтрация суммы трех тонов",
)
plot!(p_time, time .* 1000, y_ideal; label = "идеальная каскадная модель")
plot!(p_time, time .* 1000, y_load; label = "с нагрузкой 1 МОм")
time_plot_path = joinpath(output_dir, "rc_bandpass_time_signals.png")
savefig(p_time, time_plot_path)
p_time
На выходе меньше влияние медленной составляющей 200 Гц и высокочастотной составляющей 30 кГц. Сигнал в области 3 кГц проходит лучше остальных, поэтому форма становится ближе к среднечастотному гармонике.
Сравнение с физической цепью
Постройте вход и выход физической модели. Этот график нужен, чтобы убедиться, что физическая цепь ведет себя как рассчитанный полосовой фильтр.
time_phys, input_phys = series_from_result(physical_results, "input_sum.1")
_, vout_phys = series_from_result(physical_results, "vout_sensor.V")
p_phys = plot(
time_phys .* 1000,
input_phys;
label = "вход физической модели",
xlabel = "Время, мс",
ylabel = "Напряжение, В",
title = "Проверка физической RC-цепи",
)
plot!(p_phys, time_phys .* 1000, vout_phys; label = "выход физической модели")
physical_plot_path = joinpath(output_dir, "rc_bandpass_physical_time.png")
savefig(p_phys, physical_plot_path)
p_phys
Физическая цепь также подавляет низкую и высокую составляющие. Небольшое отличие от идеальной передаточной функции ожидаемо: реальные каскады взаимодействуют через импедансы, а выход дополнительно нагружен сопротивлением 1 МОм.
Сводная таблица
Соберите расчетные показатели в таблицу. Она фиксирует границы полосы и коэффициенты передачи на проверочных частотах.
case_rows = [
(case = "ideal", R_hp = R_HP),
(case = "load_1M", R_hp = R_HP_loaded),
]
summary_rows = [
(;
case = row.case,
f_hp_Hz = 1 / (2pi * row.R_hp * C_HP),
f_lp_Hz = f_lp,
gain_200Hz = gain_bp(200.0, row.R_hp),
gain_750Hz = gain_bp(750.0, row.R_hp),
gain_3kHz = gain_bp(3_000.0, row.R_hp),
gain_16kHz = gain_bp(16_000.0, row.R_hp),
gain_30kHz = gain_bp(30_000.0, row.R_hp),
)
for row in case_rows
]
summary_csv = joinpath(output_dir, "rc_bandpass_summary.csv")
open(summary_csv, "w") do io
println(io, "case,f_hp_Hz,f_lp_Hz,gain_200Hz,gain_750Hz,gain_3kHz,gain_16kHz,gain_30kHz")
for row in summary_rows
println(io, join((row.case, row.f_hp_Hz, row.f_lp_Hz, row.gain_200Hz, row.gain_750Hz, row.gain_3kHz, row.gain_16kHz, row.gain_30kHz), ","))
end
end
summary_rows
Таблица подтверждает инженерную цель: коэффициент передачи около 3 кГц максимален среди выбранных проверочных частот, а частоты 200 Гц и 30 кГц заметно ослаблены.
Заключение
Мы рассчитали и проверили полосовой RC-фильтр для диапазона примерно от 0.75 кГц до 16 кГц. Номиналы 10 кОм + 1 нФ и 2 нФ + 100 кОм дают близкие границы полосы, а нагрузка 1 МОм умеренно смещает нижнюю границу. Сигнальная и физическая модели Engee согласованно показывают подавление низкой и высокой составляющих при прохождении среднечастотного сигнала.
Список литературы
- Хейс Т.К., Хоровиц П. Искусство схемотехники. Теория и практика. БХВ-Петербург, 2022. с.130-132
- Хоровиц П., Хилл У. Искусство схемотехники. Том 1. Мир, 1993.
- Бессонов Л. А. Теоретические основы электротехники. Электрические цепи. Гардарики, 2002.
- Седра А., Смит К. Микроэлектронные схемы. Вильямс.
- Engee Help Center. Документация блоков
Transfer Fcn,Sine Wave,Add,Resistor,Capacitor,Electrical Reference,Controlled Voltage Source,Voltage Sensor,Solver Configuration. - Engee Help Center. Программное управление моделями:
engee.load,engee.open,engee.run,engee.close.