МЕТОДИЧЕСКАЯ РАЗРАБОТКА
Г
Лекция № 20
Программирование простейших фильтров нижних частот
1. Рекурсивные фильтры. Алгоритм экспоненциального сглаживания.
Простейший фильтр нижних частот это RC-цепочка. Если на входе действует дельта-функция , то выход — импульсная характеристика фильтра — имеет вид:
.
Цифровой аналог RC цепи — алгоритм экспоненциального сглаживания.
0< a <1 — коэффициент.
Пусть очередной входной отсчет — положительное число с форматом 1 байт, помещается другой частью программы в ячейку с именем x. Коэффициент фильтра
находится в ячейке памяти с именем alpha. Очередной выходной отсчет
должен быть помещен в ячейку памяти с именем y. Взаимодействие с АЦП и ЦАП рассматривать не будем. Заметим только, что срочная задача с именем Main вызывается по прерыванию от АЦП.
x: DS 1 ;место для очередного отсчета входного сигнала
alpha: DS 1 ;место для коэффициента
y: DS 1 ;место для очередного отсчета выходного сигнала
Обозначим , тогда выражение для экспоненциального сглаживания примет вид:
.
Разность может быть как положительной, так и отрицательной.
Разность отрицательная:
1. Найти модуль разности.
2. Умножить модуль на значение в ячейке alpha. В результате умножения получится 2-х байтовое число. Отбрасывание младшего байта произведения означает деление на 256:
Если учесть, что , то число в ячейке alpha следует выбирать в диапазоне:
, например 100, что соответствует
. Т.е. проводится неявное масштабирование.
3. Вычесть старший байт произведение из значения .
В случае положительной разности нет необходимости находить модуль и значение произведения следует прибавлять к
.
Дополнение к блоку инициализации:
mov alpha, #100 ;задать коэффициент
mov y, #0 ;начальные условия нулевые
Дополнение к срочной задаче Main:
mov A, x ;взять вх. отсчет
clr С ;подготовить вычитание
subb A, y ;вычесть
mov F0, c ;запомнить знак D
jnc Dp ;переход по дельта плюс
cpl A ;обратный код разности
inc A ;модуль разности
Dp: mov B, alpha ;загружаем альфа
mul AB ;мл. байт произведения в А, ст. — в В
jnb Aсс.7, Nс ;перейти если в аккумуляторе
;маленькое число
inc B ;округляем произведение в В
Nс: mov A, y ;взять предыдущий выходной отсчет
jnb F0, Pos ;перейти, если нужно прибавлять
clr С ;подготовка вычитания
subb A, B ;вычесть приращение
sjmp Store ;перейти на запоминание
Pos: add A, B ;прибавить D, умноженное на a
Store: mov y, A ;запомнить текущий выходной отсчет
2. Нерекурсивный фильтр
Медленно меняющийся сигнал
— наблюдаемый сигнал,
— полезный сигнал,
— шум.
h – интервал дискретизации.
- текущее среднее значение,
. Очевидно, что пока
в фильтре будет наблюдаться переходной процесс. Если распределение шума нормальное, то текущее среднее значение является наилучшей оценкой для сигнала
. Пусть окно для усреднения содержит N=8 отсчетов, i=0,1,…,7.
Для вычисления текущего отсчета потребуется текущий входной отсчет
и 7 предыдущих входных отсчетов
.
Пусть x(k) имеет формат 12-ть бит и помещается в регистры R1и R0.
Для хранения 8-ми входных отсчетов по два байта в каждом организуем кольцевой буфер размером 16-ть байтов. Пометим начало буфера меткой Buf. Вновь пришедший отсчёт всегда будем записывать на место самого старого. Для этого выделим указатель смещения в буфере — байт памяти с именем Pbuf. Значение этого указателя будет меняться от 0 до 7.
Учитывая, что до полного заполнения буфера в фильтре идет переходной процесс, начальное значение указателя Pbuf никакого значения не имеет. Нужно только обнулить незначащие биты с номерами от 3 до 7.
Резервируем место для кольцевого буфера и указателя смещения в буфере:
Buf: DS 16 ;16 байтов кольцевого буфера
Pbuf: DS 1 ;1 байт указателя
Адрес входного отсчета в кольцевом буфере формируется как сумма начального адреса буфера Buf и содержимого указателя Pbuf, умноженного на 2 (учет 2-х байтового формата входного отсчета).
Вызов срочной задачи Main по прежнему осуществляется по прерыванию от АЦП. Результат фильтрации помещаем в пару регистров А — младший байт, В — старший байт.
Дополнение к задаче Main:
………………………………………..
Start: inc Pbuf ;приращение указателя
anl Pbuf, #07h ;ограничивает приращение,
;организация кольцевого буфера
mov A, Pbuf ;для формирования адреса
rl A ;сдвиг влево на 1 разряд,
;учёт 2х байтового формата
add A, #Buf ;формирование адреса в буфере
xch A, R0 ;загрузка в R0 адреса буфера,
;в А мл. байт входного отсчета
mov @R0, A ;поместить мл. байт в буфер
inc R0 ;скорректировать адрес
mov A, R1 ;старший байт в А
mov @R0, A ;запись старшего байта в буфер
;После обновления буфера можно просуммировать все хранящиеся в нем ;отсчёты входного сигнала.
clr A ;для накопления младших байтов
mov B, A ;для накопления старших байтов
mov R1, #8 ;для счёта количества циклов
mov R0, #Buf ;для чтения из буфера
Next: add A, @R0 ;накопление младших байтов
xch A, B ;
inc R0 ;
addc A, @R0 ;накопление старших байтов
xch A, B ;в А мл. байт суммы, в В — старший
inc R0 ;скорректировать адрес в буфере
djnz R1 ,Next ;декрементировать счетчик
;и если не все вернуться
;Получить среднее значение можно посредством 3х сдвигов вправо
clr C ;подготовка сдвига
xch A, B ;начнем сдвиг со старшего байта
rrc A ;поделим на 2
xch A, B ;теперь младший
add A, #4 ;округление перед делением
jnc Car
inc B
Car: anl A, #11111000b ;очистка лишних разрядов
clr C
rrc A ;сумму поделили на 2
xch A, B ;
rrc A ;
xch A, B ;
rrc A ;еще раз на 2 (уже на 4)
xch A, B ;
rrc A ;
xch A, B ;
rrc A ;сумму поделили на 8
лекции (семинара) по травматологии и ортопедии