Смекни!
smekni.com

Цифровой сглаживающий фильтр (стр. 3 из 4)

При перепаде на высокий уровень, если прерывание не замаскировано и разрешено, произойдет сохранение счетчика команд в стеке, и микропроцессор начнет работу с ячейки 003С(16). В эту ячейку следует записать инструкцию перехода на начальный адрес основной программы, которая будет считывать входной отсчет из порта А, обрабатывать его согласно алгоритму фильтрации и выводить в порт В. Основная программа должна отработать до прихода в порт А очередных данных, а до этого не прерываться. Первое обеспечивается эффективностью алгоритма и быстродействием программы. Второе – хранением высокого уровня на входе RST 7.5 триггером, поэтому ложная импульсная помеха, попавшая на этот вход во время выполнения программы, не прервет и не перезапустит ее. Но чтобы обеспечить возможность нового запуска программы при приходе очередных данных, необходимо сбросить триггер, что осуществляется переустановкой маски, описанной выше. Кроме того, необходимо записать исходное число 50FFв указатель стека, так как при каждом прерывании в стек записывается счетчик команд, а указатель стека дважды декрементируется, что в конечном итоге приведет к достижению им рабочей области и засорению ее неверной информацией. Завершается основная программа командой HLT, и процессор ожидает поступления на вход RST 7.5 очередного положительного перепада.

3. Разработка конкретных алгоритмов работы устройства

Как уже оговаривалось, при рестарте микропроцессор начинает исполнять инструкции, находящиеся в области векторов прерываний ПЗУ в зависимости от типа рестарта. При включении питания исполняется команда, записанная в ячейке с адресом 0000(16), а при аппаратном прерывании RST 7.5. - начальный адрес 003С(16). В эти ячейки следует поместить команды безусловного перехода на определенный адрес JMP. В первом случае ссылка осуществляется на программу инициализации, во втором – на основную программу обработки оцифрованного сигнала. Обе программы ориентировочно небольшие по сравнению с размером ПЗУ ( 2кбайт ), поэтому их можно рассредоточить в адресном пространстве. Например, программу инициализации поместить с адреса 0200(16), а основную программу – начиная с адреса 0500(16). Тогда ориентировочная карта памяти выглядит следующим образом:

0000 JMP 0200
0001
003C JMP 0500
003D
0200 Инициализация
0201
0500 Осн. программа
0501
5000 ОЗУ
5001
7001 Порт А
7002 Порт В
7003

ПЗУ, ОЗУ и порты ввода-вывода имеют одно адрестое пространство, поэтому обращение к ним можно производить с помощью одних и тех же инструкций: LDA (загрузка ) и STA (запоминание). При этом данные соответственно загружаются в аккумулятор и копируется из него.

Алгоритм программы инициализации имеет следующий вид:

Основная программа должна начинаться с загрузки в аккумулятор входного отсчета из порта А. Входные данные, получаемые от АЦП, представлены в беззначном коде (минимальное число 00000000(2), максимальное 11111111(2)). Чтобы перейти к рабочему коду процессора – дополнительному, достаточно прибавить к входному число 80(16) = 10000000(2), это эквивалентно отсечению постоянной составляющей. Далее предстоит умножение числа на коэффициенты и суммирование согласно выражению (1). Для этих целей необходимо хранить предыдущие отсчеты в памяти ОЗУ. Возможен следующий вариант организации оперативной (рабочей) памяти:


Отсчет*0.4
*коэффиц. Адрес(16)
Xi-4
0.1 5000
Xi-3
1 5001
0.65 5002
0.1 5003
Xi-2
1 5004
0.65 5005
0.1 5006
Xi-1 1 5007
0.65 5008
0.1 5009
Xi 1 500А
0.65 500В
0.1 500С

ОЗУ начинается с адреса 5000(16) , тут и можно разместить рабочую область. Преобразованный отсчет умножается на 0.4, помещается в ячейку с адресом 500А, далее умножается на 0.65 и помещается в ячейку 500В. Эти два умножения выполняются стандартно – сдвигом множителя и сложением.

Коэффициент 0.4 можно представить в 8-разрядной сетке приближенно: 0.0110011 = 0.25+0.125+0.015625+0.0078125 = 0.3984325. Алгоритм умножения на 0.4:

Аналогично производится умножение на коэффициент 0.65, который в двоичном виде можно представить как 0.1010011 = 0.5+0.125+0.015625+0.0078125=0.6484375.

Как видно, алгоритмы схожи. Деление на два может быть реализовано с помощью арифметического сдвига аккумулятора путем сочетания инструкций RLC, RAR, RAR. Такая последовательность команд исключает потерю знака из 7-го разряда, а значит, может применяться для положительных и отрицательных чисел. Округление представляет собой сложение с элементом, оказавшимся после деления вне разрядной сетки. При арифметическом сдвиге этот элемент переходит во флаг переноса С, следовательно, для округления может быть использована команда сложения с переносом ADCE, где Е – заранее обнуленный регистр, либо ADCB, когда непосредственно за округлением в алгоритме следует сложение с регистром В. Чтобы не потерять множитель-отсчет, перед сложением с регистром В его необходимо сохранить, например, в регистр С, после сложения восстановить в аккумулятор и продолжать операции арифметического сдвига.

Умножение на 0.1 можно выполнить более просто, если учесть, что С(b0+b1+b2+b3+b4)=С(2b0+2b1+b2)=1 – это легко проверить. Домножив обе части равенства на величину преобразованного в дополнительный код отсчета, получим:

Xi = 2Cb0Xi + 2Cb1Xi +Cb2Xi = 2*0.4*0.1Xi + 2*0.4*0.65Xi +0.4Xi

Значение 0.4*0.1*Xiявляется искомым и должно быть записано в ячейку 500С:


Алгоритм умножения на 0.1 должен реализовать данное выражение, причем исходные данные в числителе известны, если преобразованный отсчет Xi перед умножением на 0.4 сохранить в регистре, например, D. Значение 0.4*0.65*Xiна данном этапе находится в аккумуляторе. Умножение его на 2 можно выполнить последовательностью инструкций RAL, RAL, RRC, ANI11111110(2) , позволяющей сохранить знак числа и исключить нечетность из-за перехода единицы в нулевой разряд аккумулятора из флага переноса.

Теперь рабочая область ОЗУ подготовлена к суммированию в соответствии с выражением (1), как показано на рис. . Суммируется содержимое ячеек с адресами 500С, 5008, 5004, 5002, 5000. Для этого можно использовать инструкцию ADD M, а в качестве указателя на адреса – регистр HL. После суммирования данные готовы к выводу в порт.

Далее содержимое ячеек 5003 – 500С подлежит переносу на три ячейки вверх – таким образом текущий отсчет становится предыдущим, предыдущий – препредыдущим и т. д. Сдвиг удобно осуществлять парами, используя для этого инструкции LHLD и SHLD.

Последней операцией основной программы является сброс входного триггера входа микропроцессора RST 7.5., после чего вход будет воспринимать сигнал прерывания как команду рестарта микропроцессора. Для сброса триггера просто переустанавливается маска прерываний, описанная выше.

Алгоритм работы основной программы ( алгоритм фильтрации ) выглядит следующим образом:

4. Разработка и отладка программного обеспечения

Программа, реализующая приведенные выше алгоритмы, разработана для микропроцессора КР1821ВМ85. При создании программы использовался в качестве компилятора кросс-ассемблер ASM80, позволяющий с помощью директив и меток, располагаемых в тексте программы, уйти от прямых физических адресов. Для пошагового анализа работы программы, выявления и исправления ошибок в реализации алгоритмов использовался отладчик DEB80. Исходный текст программы, а также ее листинг с указанием физических адресов, приведены ниже. Основная часть программы, реализующая алгоритм фильтрации, занимает ячейки ПЗУ с адреса 0500(16) по 0598(16) включительно, то есть 152 байта памяти. На исполнение основной части программы с момента рестарта RST 7.5. уходит 727 машинных тактов при максимально допустимом числе их N=1000, то есть программа, работая, укладывается в интервал дискретизации с запасом по времени » 25 %, что означает выполнение одного из требований к устройству – обработка сигнала в реальном масштабе времени.

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

Исходя из того, что переходная характеристика не имеет выброса и стремится к единице, можно утверждать, что при условии корректной реализации алгоритма не будет происходить переполнения разрядной сетки, то есть переходной процесс не превышает постоянный входной уровень, а установившийся режим в точности повторяет его. Это относится и к максимально допустимым цифровым значениям входных отсчетов. Переполнение может иметь место при некоторых упущениях в реализованной программе, например, когда результаты всех умножений ( на 0.4, 0.65, 0.1 ) округлятся в большую сторону. Однако особый способ реализации умножения на 0.1 ( вычитанием из единицы ) исключает такую возможность.

С целью проверки на переполнение был осуществлен ручной и автоматический расчет работы программы. В качестве исходных принимались два критических случая – минимального и максимального постоянных уровней на входе.