Глинченко А.С. Принципы организации и программирования сигнальных процессоров ADSP-21xx (2000) (1264223), страница 13
Текст из файла (страница 13)
Она используется в одной из следующих форм:.INIT buffer_name: constant, constant, … ;.INIT buffer_name: ^other_buffer or %other_buffer;.INIT buffer_name: <filename> ;Примеры инициализации буферов:.INIT seed_values: 1, 2, 3, 5, 7; {инициализация списком констант}.INIT buffer_ptr: ^input_buffer; {инициалицация указателем другого буфера}.INIT cos: <cosines. dat>{инициализация буфера из файла}Если файл инициализации находится в другой директории, то вдирективе должен указываться полный путь, например:.INIT cos: <С:\ 2181\ filter\ cosines.
dat>;Директива .INCLUDE <filename>; позволяет включить в программныймодуль любой исходный текст на языке ассемблера.С помощью директив .GLOBAL, .EXTERNAL и .ENTRY осуществляютсямежмодульные связи.Директива .GLOBAL internal_symbol, … ; делает переменнуюinternal_symbol и другие следующие за ней видимыми (доступными) издругих модулей программы.Директивой .ENTRY programm_label; объявляется метка входа вподпрограмму, вызываемую из другого модуля.В модуле, использующем глобальные переменные и метки, они должныбыть объявлены как внешние директивой .EXTERNAL external_symbol,external_programm_label; c тем же именем, что объявлено в директивах.GLOBAL и .ENTRY.Все помещаемые в ассемблерных модулях комментарии заключаются вфигурные скобки {…}.Таким образом, общая структура программного модуля включаетпоследовательность директив объявления модуля, описания констант,71описания переменных, их инициализации, объявления глобальных ивнешних переменных и меток, ассемблерных инструкций процессора(собственно программу или подпрограмму), комментарии и директивузакрытия модуля.
Последние инструкции подпрограмм RTS или RTIвозвращают управление основной программе. Модули подпрограммсодержат также обязательные комментарии − сообщения, такие как:Параметры вызова − значения регистров, которые должна установитьвызывающая программа перед вызовом подпрограммы.Возвращаемые значения − регистры, содержащие результаты работыподпрограммы.Изменяемые регистры − регистры, используемые подпрограммой.Вызывающая программа должна сохранить их содержимое перед вызовомподпрограммы и восстановить после возврата из нее, если их содержимоесущественно.Время исполнения − количество процессорных циклов, необходимое дляисполнения подпрограммы (при необходимости).Приводимые далее примеры ассемблерных программ иллюстрируютиспользование вышеописанных директив ассемблера.12.2.
ПРОГРАММНАЯ РЕАЛИЗАЦИЯ ЦИФРОВЫХ ФИЛЬТРОВСтруктура программ цифровой фильтрацииЦифровая фильтрация относится к одной из основных задач цифровойобработки сигналов и данных. Ниже приводятся примеры программнойреализации нерекурсивного и рекурсивного цифровых фильтров.Программы содержат главный модуль и модули подпрограмминициализации фильтра и обработки данных. Подпрограмма инициализациифильтра вызывается из главного модуля программно, а подпрограммаобработки данных – по прерыванию приема очередного отсчета данных.Главный модуль является общим для нерекурсивного и рекурсивногоцифровых фильтров.Главный модуль программы цифровой фильтрацииГлавный модуль обеспечивает управление синхронизированнымвводом/выводом данных и их алгоритмической обработкой.
Ввод/выводданных осуществляется через последовательный порт сигнальногопроцессора SPORT0. Порт работает в режиме внутренней тактовой икадровой синхронизаций с частотами, соответственно, 1,536 МГц и 8 кГц,которые получаются делением тактовой частоты процессора 12,2888 МГц.Источниками – приемниками данных могут быть любые внешниепоследовательные устройства, в том числе АЦП и ЦАП, непосредственносопрягаемые с последовательными портами процессора.
При этом импульсывнутренней кадровой синхронизации порта, выводимые наружу,используются также в качестве импульсов частоты дискретизации72преобразуемого в код сигнала. Возможен также вариант с внешней кадровойсинхронизацией порта с частотой выборок сигнала, т. е. с внешней частотойдискретизации. Ввод данных в процессор и их обработка выполняются попрерываниям приема данных, генерируемыv портом, также как и выводобработанных данных.В главном модуле программы flt_routine объявляются внешние стартовыеадреса вызываемых подпрограмм proc_start и init_start, осуществляетсянастройка подсистемы прерываний и системных регистров процессора,выполняется программирование последовательного порта SPORT0, вызовподпрограммы инициализации фильтра, организуется цикл ожиданияпрерывания приема данных.
По генерируемому портом прерываниювызывается подпрограмма обработки данных цифрового фильтра, привозврате из которой процессор снова переводится в цикл ожиданияочередного отсчета данных из последовательного порта.Ниже приводится исходный текст главного управляющего модуляпрограмм цифровой фильтрации flt_routine для процессора ADSP-2111 исовместимых с ним.{Главный модуль программ цифровой фильтрации}.MODULE/ RAM/ ABS = 0 flt_routine;.EXTERNAL init_start, proc_start;{загрузка векторов прерываний с нулевого адреса}JUMP restarter; NOP; NOP; NOP;RTI; NOP; NOP; NOP;RTI; NOP; NOP; NOP;RTI; NOP; NOP; NOP;RTI; NOP; NOP; NOP;JUMP proc_start; NOP; NOP; NOP;RTI; NOP; NOP; NOP;RTI; NOP; NOP; NOP;RTI; NOP; NOP; NOP;{прерывание перезапуска}{прерывание IRQ2}{прерывание записи ХИП}{прерывание чтения ХИП}{прерывание передачи SPORT0}{прерывание приема SPORT0}{прерывание записи SPORT1}{прерывание приема SPORT1}{прерывание таймера}{установка регистров последовательного порта и интерфейса памяти}AX0 = 191;DM(0x3FF4) = AX0;{установка частоты кадровой}{синхронизации RFS 8 кГц}AX0 =3;DM(0x3FF5) = AX0;{установка частоты тактовой}{синхронизации SCLC 1,536 МГц}AX0 =0x69B7;DM(0x3FF6) = AX0;{внутренние SCLC, RFS, TFS; нормальная}{кадровая синхронизация; требуются RFS,}{TFS; компандирование по η-закону;}{8-битовые слова, многоканальный режим}{запрещен; прерывание кадровой}73{синхронизации передачи запрещено;}{прерывание кадровой синхронизации}{приема разрешено}AX0 = 0x7000;{состояния ожидания DM: 0x3400 – 0x37FF}DM(0x3FFE) = AX0; {- 7 тактов, остальные 0 }AX0 =0x1000;DM(0x3FF5) = AX0;{SPORT0 блокирован, загрузка со страницы}{0, 0 тактов ожидания памяти начальной}{загрузки и памяти программ PM}ICNTL = 0x00;IMASK = 0x0018;{разрешены только прерывания SPORT0}mainloop: IDLE;{цикл ожидания прерывания SPORT0}JUMP mainloop;.ENDMOD;Подпрограммы инициализации и обработки нерекурсивногоцифрового фильтраНерекурсивный цифровой фильтр или фильтр с конечной импульснойхарактеристикой (КИХ или FIR фильтр) реализует алгоритм дискретнойвременной свертки.
Сигнал на его выходе y(n) определяется суммойтекущего x(n) и (N – 1)-го предыдущих отсчетов входного сигнала, взятых свесовыми коэффициентами, соответствующими значениям импульснойхарактеристики фильтра h(n) конечной длины N:y (n ) =N −1∑ h (m )⋅ x(n − m ).m =0Значения h(N – 1), h(N – 2), … h(1), h(0) в указанной последовательностиразмещаются по возрастающим адресам памяти программ, образуя массивили циклический буфер коэффициентов coef_buffer.
Они умножаются насоответствующие отсчеты входного сигнала x(n–N+1), x(n–N+2), … x(n–1),x(n), которые образуют сигнальную память фильтра или циклический буферотсчетов сигнала data_buffer в памяти данных процессора. Ему соответствуетструктура данных типа очередь постоянной длины. Очередной отсчетсигнала x(n) после его обработки замещает самое старое значение сигнала вочереди x(n–N).
Адрес этого отсчета определяет начало очереди, котороециклически перемещается в буфере в процессе обработки сигнала. Такомуспособу обработки соответствует алгоритм программной реализациинерекурсивного фильтра без сдвига сигнальной памяти. Исходный адресначала очереди соответствует обычно началу буфера data_buffer в памятиданных.Инициализация фильтра выполняется вне базового программного цикла.В приводимой ниже подпрограмме инициализации flt_init объявляетсяметка входа в подпрограмму init_start, объявляются буферы данных74data_buffer и коэффициентов coef_buffer, осуществляется инициализациябуфера коэффициентов из файла <coef.dat>, инициализируются регистрыгенераторов адресов данных, адресующие циклические буферы, загружаетсясчетчик циклов и производится очистка буфера данных в цикле DO UNTIL.В подключаемом файле <const.h> задаются фактические значения константldbuf = N, lcbuf = N и ldbuf_less_one = N – 1, например:.CONST ldbuf = 31, lcbuf = 31, ldbuf_less_one = 30;{Модуль подпрограммы инициализации нерекурсивного фильтра}.MODULE/ RAM flt_init;.INCLUDE <const.h>;.VAR/ DM/ RAM/ ABS=0x3800/ CIRC data_buffer[ldbuf];.VAR/ PM/ RAM/ CIRC coef_buffer[lcbuf];.GLOBAL data_buffer, coef_buffer;.INIT coef_buffer: <coef.dat>;.ENTRY init_start;{Параметры вызова - нетВозвращаемые значенияI0 = указывает на начало буфера данныхL0 = длина буфера данных NI4 = указывает на начало буфера коэффициентовL4 = длина буфера коэффициентов NM0, M4 = 1Изменяемые регистрыI0, I4, L0, L4, M0, M4, CNTR}Init_start: I0 = ^ data_buffer; {загрузка указателя буфера данных}L0 = % data_buffer; {задание длины циклического буфера данных}M0 = 1;{модифицирующее значение адреса данных}I4 = ^ coef_buffer; {загрузка указателя буфера коэффициентов}L4 = % coef_buffer; {задание длины циклического буфера коэфф-в}M4 = 1;{модифицирующее значение адреса коэффициентов}CNTR = % coef_buffer;DO clear UNTIL CE;{очистка буфера данных}clear: DM(I0, M0);.ENDMOD;В приводимом модуле подпрограммы обработки прерыванийнерекурсивного фильтра fir_proc, реализующем базовую операцию свертки,из подключаемого файла <const.h> передаются значения констант ldbuf == lcbuf = N длины фильтра и ldbuf_less_one = N – 1, объявляются метка входаproc_start, внешние переменные data_buffer и coef_buffer и осуществляетсяалгоритмическая обработка очередного отсчета сигнала, которыйсчитывается с приемного регистра порта RX0.75Выходной отсчет данных записывается в передающий регистрпоследовательного порта TX0.Все коэффициенты и значения данных для нерекурсивного фильтрапредставляются в формате 1.15.{Модуль подпрограммы обработки нерекурсивного фильтра}.M0DULE/ RAM fir_proc;.INCLUDE <const.h>;.EXTERNAL data_buffer, coef_buffer;.ENTRY proc_start;{Параметры вызоваI0 –начало очереди данныхL0, L4 = длина фильтра NI4 = начало буфера коэффициентовM0, M4 = 1Возвращаемые значенияTX0 = выходной отсчет (с округлением)I0 – указывает начало очереди данныхI4 – указывает начало таблицы коэффициентовL0, L4 = длина фильтра NM0, M4 = 1Изменяемые регистрыSI, MX0, MY0, MR, CNTRВремя выполнения N-1+5+2 цикловПредполагается, что все коэффициенты и значения данных представленыв формате 1.15}proc_start: CNTR = ldbuf_less_one;{CNTR = N – 1}SI = RX0;{чтение отсчета данных x(n) с порта SPORT0}DM(I0, M0)=SI;{пересылка x(n) в начало очереди данных}MR=0, MX0=DM(I0, M0), MY0=PM(I4, M4);{обнуление накопителя,}{считывание значений x(n-N+1) и h(N-1) из памяти}DO top UNTIL CE;{цикл умножения h(m)*x(n-m) с накоплением}top: MR=MR+MX0*MY0(SS), MX0=DM(I0,M0), MY0=PM(I4,M4);MR=MR+MX0*MY0(RND); {умножение h(0)*x(n-m), накопление}IF MV SAT MR;{и округление с насыщением}TX0 = MR1;{запись y(n) из MR1 в регистр передачи SPORT0}RTI;{возвращение в главную программу}.ENDMOD;Подпрограммы инициализации и обработки рекурсивногоцифрового фильтраРекурсивный фильтр или фильтр с бесконечной импульснойхарактеристикой (БИХ или IIR фильтр) реализован по каскадной структуре в76виде последовательно соединенных L базовых биквадратных звеньев(звеньев второго порядка) [7, 8].