03_Периферийные_устройства_Информ_материал_СПО_ч3 (1268619), страница 3
Текст из файла (страница 3)
Один из путей использования этой особенности —организация пошагового режима.Например, можно запрограммировать одно из внешних прерываний, скажем INT0, наактивизацию по уровню:JNB P3.2,$; Ожидание, когда INT0 станет высокимJB; Ожидание, когда INT0 станет низкимp3.2,$RETIP3.23.3.5. Написание подпрограмм обработки прерыванийОбобщенная схема подпрограмм обработки прерываний:Такие подпрограммы называются ISR (interrupt service routine) — стандартнаяподпрограмма обслуживания прерываний или interrupt handler подпрограмма обработки(обработчик) прерываний.Vector: LJMP SubrVectorЗапоминание регистров в стекеТелоВосстановление регистров из стекаRETI; дополнительно восстанавливает; логику приоритетов прерыванийЗдесь Vector — адрес, соответствующий запросу прерывания, но непосредственно даннойметки в явном виде не существует; SubVector — подпрограмма обработчика прерыванияна новом адресе.Поскольку с каждым источником прерывания связан конкретный вектор (адрес)прерывания, то обработчик прерывания необходимо расположить, начиная с этого адреса.Как это сделать? Вариантов есть несколько.
Рассмотрим два основных.Во-первых, в главном модуле можно зафиксировать вектора обработчиков прерыванийследующим образом:extrn code (ISR_INT0, ISR_TC0)cseg at 0ljmp startup; переход к инициализацииorg 0003hljmp ISR_INT0orgljmp......; Сами обработчики находятся в другом; модуле000BhISR_TC0startup:Второй способ предполагает использование директивы задания абсолютного сегмента вкодовой памяти CSEG:?PR?INT0CSEGAT0003hLJMPISR_INT0segment coderseg ?PR?INT0using 1; необязательный элемент (переключает;ISR_INT0:...банки); начало обработчика прерывания......RETI; конец обработчика прерыванияПоследний вариант представляется предпочтительным, т.к. объявление как абсолютногосегмента, так и перемещаемого находятся в одном модуле-файле, предназначенным дляописания обработчика прерывания.
Там же могут размещаться все другие необходимыедекларации, имеющие отношение к выполняемой модулем функции. То есть, этосоответствует концепции модульного программирования.3.3.6. Взаимодействие программПодпрограммы обработки прерываний обычно не являются полностью независимыми отосновной программы, т.е. между ними имеет место взаимодействие. Примером такоговзаимодействия является обращение к общим ресурсам (памяти, периферийнымустройствам).
Пример другого типа взаимодействия — задержка на запрос прерывания изза временного запрета прерывания или выполнения прерывания такого же или болеевысокого уровня приоритета.Пример:Допустим, что реализованы «часы» с использованием прерывания таймера. В переменныхHi и Lo храниться текущее время в единицах переполнения таймера. Пусть основная(фоновая программа) считывает Hi = 0. Сразу после этогоHi Loсчитывания генерируется прерывание, которое добавляет 100 ffh до прерыванияк шестнадцатиразрядной переменной Hi-Lo. После01 00 после прерывания окончания прерывания основная программа продолжитсчитывание второго байта, в результате считает Lo = 00.
Общий результат считываниясоставит 00 00. Заметим, что проблема отсутствует, если выполняется одна командачтения, т.е. считываемая переменная однобайтовая.Для решения отмеченной проблемы следует до окончания обращения однойподпрограммы к общим переменным исключить возможность обращения к ним другойподпрограммы.
Этот подход называется принципом взаимного исключения. Областьпрограммы, в которой должен соблюдаться этот принцип, называется критическойобластью [Морисита].Наиболее простая реализация этого принципа — запрещение прерываний перед входом вкритическую область и разрешение его сразу после выхода из этой области.Отрицательное действие — увеличение времени реакции на прерывание.Второй способ реализации принципа взаимного исключения основан на примененииспециального флага (переменной), называемого «семафором».
Для каждого взаимногоисключения используется свой «семафор». Часто между выполняемыми действиямиподпрограмм (программ) требуется установить определенную связь. Этот процессназывается синхронизацией, которую можно реализовать с помощью «семафора».АНетДанныеготовы?НетДаДанныесчитаны?ДаЗапись в буферВзвестифлагСчитать данныеВзвести флаг «данныесчитаны»B.