- •Московский технический университет связи и информатики
- •Курсовая работа
- •Задание на курсовую работу
- •Теоретические сведения
- •3. Расчёт ких-фильтра
- •4. Реализации программы в SciLab
- •5. Разработка программы на языке ассемблера процессора adsp-2181
- •6. Проверка разработанного фильтра
- •7.Оценка влияния эффекта Гиббса.
- •8. Вывод
- •9.Список литературы.
5. Разработка программы на языке ассемблера процессора adsp-2181
Код подпрограммы fir_main.asm:
// инициализация фильтра .SECTION/PM program; .extern impr; .extern signal; .global fir_ini;
fir_ini: i4=impr; // указатель I4 → начало массива коэффициентов, I0–I7 — 16-битные указатели данных l4=length(impr); // Длина кольца = 80 m4=1; // При обращении I4 увеличивается на 1, M0–M7 — модификаторы адреса
i0=signal; // указатель на буфер входных данных l0=length(signal); // кольцевой буфер, L0–L7 — длины циклических буферов m0=0; m1=1; // проход по буферу
my0=pm(i4,m4); // чтение из Program Memory + приращение m4, MY0 — один из MAC-регистров DSP, //MX0, MX1, MY0, MY1 — входы умножителя //доступ к Program Memory (коэффициенты) rts; fir_ini.end: |
Код подпрограммы fir.asm:
.SECTION/PM program; .extern filtr;
interr: jump start; rti; rti; rti; // RESET rti; rti; rti; rti; // IRQ2 rti; rti; rti; rti; // IRQL1 rti; rti; rti; rti; // IRQL0 rti; rti; rti; rti; // SPORT0 Tx rti; rti; rti; rti; // SPORT0 Rx rti; rti; rti; rti; // IRQE rti; rti; rti; rti; // BDMA rti; rti; rti; rti; // SPORT1 Tx rti; rti; rti; rti; // SPORT1 Rx jump timer_proc; rti; rti; rti; // Timer rti; rti; rti; rti; // Power Down
start: // основная инициализация ar = 4;//AR — Arithmetic Register, типичный 16-битный регистр общего назначения dm(0x3ffb) = ar; //dm() — запись в Data Memory (сигналы)
ar = 999; dm(0x3ffc) = ar; dm(0x3ffd) = ar;
ifc = 0x00ff; ////IFC — Interrupt Flag Clear / I/O Flag Control Register очищает флаги, устанавливает конфигурацию внешних линий nop; ena timer; //включает системный таймер imask = B#00000000001; //маска прерываний, разрешён только Timer interrupt nop;
call fir_ini;
zacycl: jump zacycl; //DSP в простое — ждёт прерываний таймера
timer_proc: call filtr; rti; //Каждое прерывание вызывает filtr
interr.end:
|
Код подпрограммы fir_init.asm
// коэффициенты .global signal; .global impr; .SECTION/DM vars; .var/circ signal[80] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; //объявляет циклический буфер (circular buffer), Используется аппаратная адресация DSP
.SECTION/PM varsp; .var/circ impr[80] = 240, -890, 486, 239, -1068, -140, 989,-752,-753,1540, -371, -2332, 2325, 4676, -2471, -4418, 4208, 6504, -2248, -4346, 2855, 4058, -1308, -1566, 1413, 122, -1155, 552, 488, -1048, -189, 556, -512, -201, 741, -9, -588, 520, 391, -623, 77, 764, -535, -576, 845, -177, -861, 761, 389, -1179, 521, 830, -1238, 151, 1275, -971, -910, 2160, -1110, -1460, 2889, -1493, -1067, 2236, -1068, -866, 1293, 65, -1419, 989, 421, -1377, 466, 926, -897, -203, 1191, -588, -458, 844; // коэффициенты фильтра |
Код подпрограммы fir_int.dsp
.SECTION/PM program; .global filtr;
filtr: mx0=IO(0); // чтение из внешнего порта ввода dm(I0,m1)=mx0, mr=0; // Запись входа в циклический буфер //обнуление MAC-аккумулятора (40 бит) cntr=78; do filt until ce;
filt: mr=mr+mx0*my0(ss), mx0=dm(i0,m1), my0=pm(i4,m4); mr=mr+mx0*my0(ss), mx0=dm(i0,m0), my0=pm(i4,m4); mr=mr+mx0*my0(ss), my0=pm(i4,m4); //Тело цикла filt — 3 MAC за итерацию “3 MAC на итерацию” //означает, что за каждый шаг цикла FIR-фильтр вычисляет сразу три //произведения вида x[i] * h[i] и суммирует их в MR mr=mr(rnd); // Используется округление if mv sat mr; // Если было переполнение (MV-флаг) → выполнить saturation (ограничить значение до MAX/MIN) IO(1)=mr1; // Отправляем младшую часть результата (MR1) в выходной порт rts; // Возврат из функции
filtr.end:
|
