МП
.pdfпринципе по завершении перезаписи содержимого из rx_buf в vhod
информация (сигнал) готова к обработке, однако ее немедленная обработка в прерывающей подпрограмме не всегда возможна. Обработка обычно занимает достаточно много времени (в рассматриваемом примере на нее может быть отведено почти все время за исключением длительности одного канального интервала), а приоритет прерывания SPORT0 ПМ весьма высок,
поэтому в течение всего времени обработки сигнала такие прерывания, как
IRQE, BDMA, SPORT1 ПД, SPORT1 ПМ и таймерное не смогут быть обслуженными. Таким образом может быть , например, потерян сигнал порта
SPORT1, а таймерная подпрограмма может оказаться выполненной не в свое время. Между тем никакой срочности в выполнении программы обработки сигнала благодаря использованию двойного буферирования нет; главное,
чтобы она была завершена к концу цикла. Такое положение вещей определяет целесообразность снижения приоритета исполнения программы обработки сигнала, например, ее переноса основную программу в соответствии с блок-схемой алгоритма рис. 34.
Управление обращением к программе обработке сигнала, размещенной
восновной программе, осуществляется флагом готовности got_fl,
объявляемым как переменная в памяти данных.
В начале основной программы значение флага устанавливается равным
0, что препятствует направлению хода выполнения программы к программе обработки сигнала.
Значение флага got_fl устанавливается в отличное от нуля значение в прерывающей подпрограмме обслуживания SPORT0 ПМ после записи содержимого входного буфера rx_buf в буфер обработки vhod.
81
Рис. 34
82
По возвращении из прерывающей подпрограммы в основную на оператор условного перехода ход выполнения программы изменяется вследствие неравенства нулю значения переменной got_fl, в результате чего процессор приступает к исполнению программы обработки сигнала. После завершения выполнения этой программы значение got_fl должно быть установлено равным нулю во избежание повторного ее выполнения при необновленных сигналах.
Текст программы на языке ассемблера процессора ADSP-2181,
реализующей алгоритм рис. 34, представлен с необходимыми комментариями на рис. 35.
//объявление переменных
.section/dm vars;
//флаг готовности к обработке
.var |
got_fl = 0; |
//буфер приема
.var/circ rx_buf[32] =
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;
//буфер передачи
.var/circ tx_buf[32] =
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;
//буфер входного сигнала
.var/circ vhod[31] =
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;
Рис.35 начало
83
//буфер выходного сигнала
.var/circ vihod[31] =
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;
//ячейка для сохранения I2
.var |
i2_soh; |
|
|
|
// ячейка для сохранения I3 |
|
|
|
|
.var |
i3_soh; |
|
|
|
// ячейка для сохранения L2 |
|
|
|
|
.var |
l2_soh; |
|
|
|
// ячейка для сохранения L3 |
|
|
|
|
.var |
l3_soh; |
|
|
|
// ячейка для сохранения AR |
|
|
|
|
.var |
ar_soh; |
|
|
|
|
//---------------------------------------------- |
|
|
|
|
// с нулевого адреса начинается |
|
|
|
|
// заполнение таблицы векторов прерываний |
|||
|
//---------------------------------------------- |
|
|
|
.SECTION/PM program; |
|
|
|
|
// |
программа |
|
|
|
|
jump start; rti; rti; rti; // |
RESET |
||
|
rti; rti; rti; rti; // |
IRQ2 |
|
|
|
rti; rti; rti; rti; // |
IRQL1 |
|
|
|
rti; rti; rti; rti; // |
IRQL0 |
|
|
|
jump peredacha; rti; rti; rti; |
// |
SPORT0 ПД |
|
|
jump priem; rti; rti; rti; |
// |
SPORT0 ПМ |
|
|
rti; rti; rti; rti; // |
IRQE |
|
|
|
rti; rti; rti; rti; // |
BDMA |
|
|
|
rti; rti; rti; rti; // |
SPORT1 ПД |
|
|
|
rti; rti; rti; rti; // |
SPORT1 ПМ |
|
|
|
rti; rti; rti; rti; // |
Timer |
|
|
|
rti; rti; rti; rti; // |
Power Down |
|
|
|
//---------------------------------------------- |
|
|
|
|
//---------------------------------------------- |
|
|
|
// конец таблицы векторов прерываний
//----------------------------------------------
//----------------------------------------------
Рис.35 продолжение
84
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// начало основной программы
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//программирование последовательного
//порта SPORT0 и прерываний
//
//останов порта, см. рис. 27
start: |
ar = dm(0x3fff); |
|
ar = clrbit 0xc of ar; |
|
dm(0x3fff) = ar; |
//автобуферирование, см. рис.28
//привязка I0 к приему, а I1 к передаче
//шаг приема - M1 (все регистры - из ГАД1) ar = B#001010000111;
//|||||||||||+--- автобуферирование ПМ вкл.
//||||||||||+---- автобуферирование ПД вкл.
//||||||||++----- шаг приема - M1
//|||||+++------- I0 -> к приему
//|||++---------- шаг передачи - M1
//+++------------ I1 -> к передаче dm(0x3ff3) = ar;
//привязка rx_buf -> I0 -> к приему, a
// |
tx_buf -> I1 -> к передаче |
// |
шаг = М1 = 1 |
i0 |
= rx_buf; |
l0 |
= length(rx_buf); |
i1 |
= tx_buf; |
l1 |
= length(tx_buf); |
m1 |
= 1; |
Рис.35 продолжение
85
// |
настройка порта, см. рис.29 - 30 |
|
ar = B#1000001000000111; |
|
|
// |
||||||||||||++++---- |
длина слова = 8 бит |
// |
||||||||||++-------- |
слева нули |
// |
||||||||++------ |
RFS0, TFS0 - активный уровень - высокий |
// |
|||||||+------------ |
RFS0 - внешний сигнал |
// |
||||||+------------- |
поток Е1 |
// |
||++++-------------- |
цикловой синхросигнал - по биту Si |
// |
|+------------------ |
SCLK0 - внешний сигнал |
// |
+------------------- |
многоканальная функция включена |
dm(0x3ff6) = ar;
//активизация доступа к канальным интервалам, см. рис. 30
//все канальные интервалы потока принимаются и передаются ar = 0xffff;
dm(0x3ff7) = ar; dm(0x3ff8) = ar; dm(0x3ff9) = ar;
//включение порта ar = dm(0x3fff);
ar = setbit 0xc of ar; dm(0x3fff) = ar;
//сброс прерываний, стоящих в очереди ifc = 0x00ff;
//холостая операция nop;
//запуск работы порта ar = dm(i1, m1); tx0 = ar;
//маскирование прерываний imask = B#0001100000;
// |
|+---------- |
SPORT0 |
ПМ |
разрешено |
// |
+----------- |
SPORT0 |
ПД |
разрешено |
//холостая операция nop;
Рис.35 продолжение
86
//частичное зацикливание основной программы
//с внесением в нее операций обработки
//сигнала с тем, чтобы выполнение обработки
//не мешало вводу / выводу и другим
//прерываниям
//сигнал готов к обработке ?
zacycl: |
ar = dm(got_fl); |
|
|
|
ar = pass ar; |
|
|
|
if eq jump zacycl; |
|
|
// |
готов |
|
|
|
//**************************************** |
||
|
//* |
здесь должна быть размещена |
* |
|
//* |
программа обработки сигнала |
* |
//****************************************
//снятие флага готовности ar = 0;
dm(got_fl) = ar; jump zacycl;
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// конец основной программы
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$} //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// подпрограмма прерывания SPORT0 ПД
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
// |
сохранение значений используемых регистров |
|
peredacha: |
dm(i2_soh) = i2; |
|
|
dm(i3_soh) = i3; |
|
|
dm(l2_soh) = l2; |
|
|
dm(l3_soh) = l3; |
|
|
dm(ar_soh) = ar; |
|
// |
vihod -> tx_buf на передачу |
|
|
i2 |
= tx_buf + 1; |
|
l2 |
= length(tx_buf); |
|
i3 |
= vihod; |
|
l3 |
= length(vihod); |
Рис.35 продолжение
87
|
cntr = 31; |
|
|
do vic1 until ce; |
|
|
ar = dm(i3, m1); |
|
vic1: |
|
dm(i2, m1) = ar; |
// |
восстановление значений используемых регистров |
|
|
ar = dm(ar_soh); |
|
|
i2 |
= dm(i2_soh); |
|
i3 |
= dm(i3_soh); |
|
l2 |
= dm(l2_soh); |
|
l3 |
= dm(l3_soh); |
// |
возврат из подпрограммы |
|
|
rti; |
|
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// конец подпрограммы //прерывания SPORT0 ПД
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// подпрограмма прерывания SPORT0 ПМ
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
//сохранение значений используемых регистров priem: dm(i2_soh) = i2;
dm(i3_soh) = i3; dm(l2_soh) = l2; dm(l3_soh) = l3; dm(ar_soh) = ar;
//прием rx_buf -> vhod i2 = rx_buf + 1;
l2 = length(rx_buf);
i3 = vhod;
l3 = length(vhod); cntr = 31;
|
do vic2 until ce; |
|
ar = dm(i2, m1); |
vic2: |
dm(i3, m1) = ar; |
Рис.35 продолжение
88
//восстановление значений используемых регистров ar = dm(ar_soh);
i2 = dm(i2_soh);
i3 = dm(i3_soh);
l2 = dm(l2_soh);
l3 = dm(l3_soh);
//установка флага готовности ar = 0x55;
dm(got_fl) = ar;
//возврат из подпрограммы rti;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//конец подпрограммы
//прерывания SPORT0 ПM
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Рис.35 окончание
14.Флаги
В соответствии с представленной на рис. 1 архитектурой процессора
ADSP-2181, в понятие флагов входят:
-четыре вывода F0, FL0, FL1 и FL2 процессора, являющиеся выходами, значение логического уровня которых может программно меняться командами из группы «прочие» рис. 16;
-один вывод, являющейся входом, по значению логического уровня на котором могут быть выполнены условные переходы и условные вызовы подпрограмм в соответствии с рис. 3;
-восьмиразрядная двунаправленная шина PF.
Каждый вывод (разряд) шины PF PF7…PF0 может быть
индивидуально запрограммирован как выход или как вход; в последнем случае вывод переводится процессором в высокоомное состояние.
Управление режимом использования выводов осуществляется записью комбинации в регистр РF&CS_Control в соответствии с рис. 36.
Обмен информацией с внешними устройствами по шине РF 89
осуществляется через регистр РF_Data в соответствии с рис. 36.
При записи информации в регистр РF_Data соответствующие логические уровни установятся только на тех разрядах шины, которые запрограммированы как выходы (единичными значениями) в регистре РF&CS_Control. Остальные разряды останутся в высокоомном состоянии.
При чтении из регистра РF_Data значения разрядов,
запрограммированных как входы (нулевыми значениями) в регистре
RF&CS_Control будут определяться значениями логических уровней на выходах шины РF.
Подобно регистрам таймера и управляющим регистрам последовательных портов, регистры РF&CS_Control и РF_Data организованы на базе ячеек памяти данных, адреса ячеек указаны на рис. 36.
Рис. 36
90
