Команды и директивы компилятора PROTON
On Interrupt
Синтаксис:
On Interrupt {Goto} Label
Команда On Interrupt инициализирует так называемую программную обработку прерываний, в отличие от команды On_Interrupt, которое инициализирует аппаратную обработку прерываний.
Встроенный в Proton+IDE редактор отличает эти две команды следующим образом - директиву аппаратного прерывания On_Interrupt он подсвечивает красным полужирным шрифтом, а директиву программного прерывания On Interrupt черным полужирным шрифтом. Это делается для облегчения отладки.
Когда используется команда On Interrupt, компилятор просто помечает то, что прерывание произошло и немедленно возвращается к тому, чем до этого он занимался. То есть в отличие от аппаратного прерывания, программа немедленно не переходит к подпрограмме обработки прерывания. Поэтому в случае использования команд довольно большой продолжительности переход на подпрограмму обработки прерывания может привести к значительным задержкам.
Например, если основная программа только что перешла к выполнению команды DelayMS 2000 и в это время произошло прерывание, то в этом случае компилятор просто отметит, что произошло прерывание и продолжит выполнение команды DelayMS 2000. А так как эта пауза будет продолжаться целых 2 секунды, то переход к подпрограмме обработки прерывания может затянуться.
В случае если основная программа очень критична к времени исполнения команд, то она будет выполняться неправильно, например при мультиплексировании семи сегментного светодиодного индикатора.
Для того, чтобы минимизировать такие случаи, следует использовать только такие команды и их конструкции, которые не занимают много времени на свое выполнение. Например, вместо команды DelayMS 2000, можно использовать команду DelayMS 1 в циклах For…Next или Repeat…Until повторяя эти циклы 2000 раз. Такие конструкции позволят компилятору заканчивать каждую команду более быстро, а значит, при возникновении прерывания программа сможет гораздо быстрее перейти к его обработке.
Пример 1
' Организация задержки равной 200 мс в цикле при помощи оператора For…Next
For VAR1 = 0 To 199 | |
DelayMS 1 | |
Next |
Пример 2
' Организация задержки равной 200 мс в цикле при помощи оператора Repeat…Until
VAR1 = 1 | |
Repeat | |
DelayMS 1 | |
Inc VAR1 | |
Until VAR1 > 200 |
Если необходимо обрабатывать прерывания довольно часто, то лучше использовать аппаратное прерывание при помощи оператора On_Interrupt.
Необходимо отметить, что работа оператора On_Interrupt довольно замысловата, в отличии от неё команда On Interrupt более проста для понимания. Поэтому если Вы решили воспользоваться программной обработкой прерываний при помощи оператора On Interrupt, то необходимо разместить перед меткой подпрограммы обработки прерывания или сразу после неё команду Disable (см. пример 3). Причем наличие команды Disable совершенно необязательно говорит о том, что прежде должна была присутствовать команда Enable. Это мое замечание идет несколько в разрез с руководством по компилятору. Но так показали эксперименты проведенные с этой командой.
Далее для того, чтобы Ваша программа после обработки прерывания вернулась в то место, откуда она ушла на обработку прерывания, разместите в конце подпрограммы обработки прерывания команду Resume. Команда Resume вернет программу в то место, откуда она ушла на обработку прерывания, и установит бит GIE регистра INTCON в 1. Это будет означать, что программа вновь готова к обработке прерываний.
Примечание 1.
Перед тем, как выполнить команду Resume, необходимо сбросить флаг того прерывания, которое вызвало программу обработки прерывания. Понятно, что это нужно для того, чтобы, как только вновь будет разрешена обработка прерываний ваша программа тут же не отреагировала на несброшенный флаг, вновь перейдя на обработку прерывания, хотя фактически никакого прерывания не было.
Пример 3
Листинг программы on interrupt3.bas
Device 16F877A | ' Произвести программный код для микроконтроллера 16F877A |
Xtal = 4 | ' Установить частоту генаратора равной 4 МГц |
OPTION_REG = %00000111 | ' Установить в регистре OPTION_REG коэффициент деления равный 1:256 |
INTCON = %00100000 | ' Разрешить прерывания по переполнению таймера TMR0 |
Symbol LED = PORTD.0 | ' Присвоить RD0 псевдоним LED |
On Interrupt GoTo My_Int | ' Инициализация программных прерываний |
Fin: | ' Метка Fin |
DelayMS 1 | ' Пауза 1 мсек |
GoTo Fin | ' Выполнить переход к метке Fin |
My_Int: | ' Метка начала выполнения подпрограммы вызванной программным ' прерыванием |
Disable | ' Запретить программные прерывания |
Toggle LED | ' Переключить светодиод в противоположное состояние |
INTCON.2 = 0 | ' Сбросить флаг прерываний от таймера |
Resume | ' Вновь разрешить обработку возникающих прерываний |
Примечание 2
Когда в программе встречается команда On Interrupt, компилятор устанавливает бит GIE регистра INTCON в 1. Это значит, что нет необходимости производить отдельно установку этого бита.
На рисунке 1 приведена действующая модель on interrupt3.DSN, демонстрирующая работу команды On Interrupt. Модель работает под управлением приведенной выше программы on interrupt3.bas.