Программа 29.1. Программа КИХ-фильтрации на Ассемблере[1]
001
/************************************************************************
002 *************************** MAIN PROGRAM ********************************
003 ************************************************************************/
004 main:
005
006 /* ОРГАНИЗАЦИЯ ЦИКЛИЧЕСКИХ БУФЕРОВ */
007
008 b0 = dline; /* буфер dline[ ], содержащий последние
отсчёты входного сигнала */
009 l0 = @dline;
010 m0 = 1;
011 b8 = coef; /* буфер
коэффициентов фильтра coef[ ] */
012 l8 = @coef;
013 m8 = 1;
014
015 /* БЕСКОНЕЧНЫЙ ЦИКЛ. ОЖИДАНИЕ
ПРЕРЫВАНИЯ ГОТОВНОСТИ ВХОДНОГО ОТСЧЁТА */
016
017 wait:
018 idle;
019 jump wait;
020
021
022 /***********************************************************************
023 ********* ПОДПРОГРАММА ОБРАБОТКИ ОДНОГО ОТСЧЁТА ***********
024 ***********************************************************************/
025 sample_ready:
026
027 /* СЧИТЫВАНИЕ НОВОГО ОТСЧЁТА, ПЕРЕВОД ЕГО В ФОРМАТ С ПЛАВАЮЩЕЙ ТОЧКОЙ */
028
029 r0 = dm(rx_buf + 1); /* запись входного отсчёта в регистр r0 */
030 r0 = lshift r0 by 16;/* сдвиг влево на 16 бит с сохранением знака */
031 r1 = -31; /* установка масштаба преобразования */
032 f0 = float r0 by r1; /* выполняем преобразование в формат с плавающей точкой
*/
033 dm(i0,m0) = f0; /* запись нового отсчёта в буфер dline[ ] и обнуление f12
*/
034
035 /* ВЫЧИСЛЕНИЕ ВЫХОДНОГО ОТСЧЁТА КИХ-ФИЛЬТРА */
036
037 f12 = 0;
038 f2 = dm(i0,m0), f4 = pm(i8,m8); /* загрузка регистров */
039 f8 = f2*f4, f2 = dm(i0,m0), f4 = pm(i8,m8);
040 /* основной цикл */
041 lcntr = NR_COEF-2, do (pc,1) until lce;
042 f8 = f2*f4, f12 = f8+f12, f2 = dm(i0,m0), f4 = pm(i8,m8);
043
044 f8 = f2*f4, f12 = f8+f12; /* окончание последней итерации */
045 f12 = f8+f12;
046
047 /* ПРЕОБРАЗОВАНИЕ ВЫХОДНОГО ОТСЧЁТА В ФОРМАТ С ФИКСИРОВАННОЙ ТОЧКОЙ
/* И ВЫВОД РЕЗУЛЬТАТА */
048
049 r1 = 31; /* установка масштаба преобразования
*/
050 r8 = fix f12 by r1; /* переход от плавающей точки к
фиксированной */
051 rti(db); /*
возврат из прерывания с предварительным исполнением
/*следующих
двух строк*/
052 r8 = lshift r8 by -16; /* сдвиг вправо на 16 бит*/
053 dm(tx_buf + 1) = r8; /* вывод полученного отсчёта */
[1] Перед выполнением основной программы должны быть определены следующие объекты: NR_COEF — число коэффициентов ядра фильтра (в нашем примере 301); dline[NR_COEF] — циклический буфер, в который записываются последние входные отсчёты (память данных); coef[NR_COEF] — циклический буфер, содержащий коэффициенты фильтра (память программ).