рефакторинг и вроде бы понял как надо управлять импульсами

надо доделать и проверить
This commit is contained in:
2025-12-04 15:01:55 +03:00
parent c0eea077d9
commit aa59f84fb7
16 changed files with 156 additions and 146 deletions

View File

@@ -0,0 +1,177 @@
%% КЛАСС ДЛЯ РАСЧЕТА КОЭФФИЦИЕНТОВ БИКВАДРАТНЫХ ФИЛЬТРОВ
classdef BiquadFilterDesigner
%BIQUADFILTERDESIGNER Класс для расчета коэффициентов биквадратных фильтров
% Поддерживает: ФНЧ, ФВЧ, полосовые, режекторные фильтры
methods (Static)
%% 1. ФНЧ (Low-Pass Filter)
function [b, a, coeffs_cmsis] = lpf(fc, Fs, Q)
% lpf - Расчет коэффициентов ФНЧ через MATLAB функции
% fc - частота среза [Гц]
% Fs - частота дискретизации [Гц]
if fc >= Fs/2
error('Частота среза должна быть меньше Fs/2');
end
% Используем встроенные функции MATLAB
if nargin < 3
% По умолчанию - Баттерворт
[b, a] = butter(2, fc/(Fs/2), 'low');
else
% С указанной добротностью
[b, a] = butter(2, fc/(Fs/2), 'low');
end
% Стабилизация коэффициентов
[b, a] = BiquadFilterDesigner.stabilize_filter(b, a);
% Формат для CMSIS-DSP [b0, b1, b2, a1, a2]
coeffs_cmsis = [b(1), b(2), b(3), a(2), a(3)];
end
%% 2. ФВЧ (High-Pass Filter)
function [b, a, coeffs_cmsis] = hpf(fc, Fs, Q)
% hpf - Расчет коэффициентов ФВЧ через MATLAB функции
% fc - частота среза [Гц]
% Fs - частота дискретизации [Гц]
if fc >= Fs/2
error('Частота среза должна быть меньше Fs/2');
end
% Используем встроенные функции MATLAB
[b, a] = butter(2, fc/(Fs/2), 'high');
% Стабилизация коэффициентов
[b, a] = BiquadFilterDesigner.stabilize_filter(b, a);
coeffs_cmsis = [b(1), b(2), b(3), a(2), a(3)];
end
%% 3. Полосовой фильтр (Band-Pass Filter) - ИСПРАВЛЕННЫЙ
function [b, a, coeffs_cmsis] = bpf(fc, bw, Fs)
% bpf - Расчет коэффициентов полосового фильтра через MATLAB функции
% fc - центральная частота [Гц]
% bw - ширина полосы [Гц]
% Fs - частота дискретизации [Гц]
f_low = fc - bw/2;
f_high = fc + bw/2;
if f_high >= Fs/2
error('Верхняя граница полосы должна быть меньше Fs/2');
end
% Используем встроенные функции MATLAB
[b, a] = butter(2, [f_low, f_high]/(Fs/2), 'bandpass');
% Стабилизация коэффициентов
[b, a] = BiquadFilterDesigner.stabilize_filter(b, a);
coeffs_cmsis = [b(1), b(2), b(3), a(2), a(3)];
end
%% 4. Режекторный фильтр (Band-Stop/Notch Filter)
function [b, a, coeffs_cmsis] = bsf(fc, bw, Fs)
% bsf - Расчет коэффициентов режекторного фильтра через MATLAB функции
% fc - центральная частота [Гц]
% bw - ширина полосы подавления [Гц]
% Fs - частота дискретизации [Гц]
f_low = fc - bw/2;
f_high = fc + bw/2;
if f_high >= Fs/2
error('Верхняя граница полосы должна быть меньше Fs/2');
end
% Используем встроенные функции MATLAB
[b, a] = butter(2, [f_low, f_high]/(Fs/2), 'stop');
% Стабилизация коэффициентов
a_stable = a;
if abs(a(3)) > 0.99
a_stable(3) = 0.99 * sign(a(3));
end
if abs(a(2)) > 1.98
a_stable(2) = 1.98 * sign(a(2));
end
b = b;
a = a_stable;
coeffs_cmsis = [b(1), b(2), b(3), a(2), a(3)];
end
%% 5. Показать характеристики фильтра
function show_response(b, a, Fs, filter_name)
% show_response - Визуализация характеристик фильтра
% b, a - коэффициенты фильтра
% Fs - частота дискретизации [Гц]
% filter_name - название фильтра для заголовка
figure('Position', [100, 100, 1000, 700]);
% АЧХ
subplot(2,2,1);
[h, f] = freqz(b, a, 1024, Fs);
plot(f, 20*log10(abs(h)), 'LineWidth', 2);
title([filter_name ' - АЧХ']);
xlabel('Частота [Гц]'); ylabel('Усиление [дБ]');
grid on;
% ФЧХ
subplot(2,2,2);
plot(f, angle(h)*180/pi, 'LineWidth', 2);
title([filter_name ' - ФЧХ']);
xlabel('Частота [Гц]'); ylabel('Фаза [градусы]');
grid on;
% Групповая задержка
subplot(2,2,3);
[gd, f_gd] = grpdelay(b, a, 1024, Fs);
plot(f_gd, gd/Fs*1000, 'LineWidth', 2);
title([filter_name ' - Групповая задержка']);
xlabel('Частота [Гц]'); ylabel('Задержка [мс]');
grid on;
% Импульсная характеристика
subplot(2,2,4);
imp_resp = filter(b, a, [1 zeros(1, 99)]);
stem(0:99, imp_resp, 'filled', 'MarkerSize', 4);
title([filter_name ' - Импульсная характеристика']);
xlabel('Отсчеты'); ylabel('Амплитуда');
grid on;
end
%% 6. Генерация C-кода для коэффициентов
function generate_c_code(coeffs, filter_name)
% generate_c_code - Генерация C-кода для коэффициентов
% coeffs - коэффициенты в формате CMSIS [b0, b1, b2, a1, a2]
% filter_name - имя фильтра для переменной
fprintf('// Коэффициенты фильтра: %s\n', filter_name);
fprintf('const float32_t %s_coeffs[5] = {\n', filter_name);
fprintf(' %.6ff, // b0\n', coeffs(1));
fprintf(' %.6ff, // b1\n', coeffs(2));
fprintf(' %.6ff, // b2\n', coeffs(3));
fprintf(' %.6ff, // a1\n', coeffs(4));
fprintf(' %.6ff // a2\n', coeffs(5));
fprintf('};\n\n');
end
function [b_stable, a_stable] = stabilize_filter(b, a)
a_stable = a;
% Ограничиваем коэффициенты a для устойчивости
if abs(a_stable(3)) > 0.95
a_stable(3) = 0.95 * sign(a_stable(3));
end
if abs(a_stable(2)) > 1.9
a_stable(2) = 1.9 * sign(a_stable(2));
end
b_stable = b;
end
end
end