Хотя в нашем примере мы сохраняли только рабочий регистр и регистр STATUS[101], в других случаях может потребоваться сохранение и других РСН. Так, в Примере 7.3 сохраняется регистр FSR, поскольку он используется как в основной программе, так и в обработчике прерывания. Одним словом, если в процедуре обработки прерывания изменяются какие-либо РСН, то при выходе из обработчика должно быть восстановлено их исходное состояние. В любом случае первым необходимо сохранить содержимое рабочего регистра, поскольку он будет использоваться в качестве промежуточного хранилища при сохранении остальных регистров. Соответственно восстанавливаться рабочий регистр должен в самую последнюю очередь.
По мере возможности регистры, в которых сохраняется контекст программы, следует выбирать таким образом, чтобы они не зависели от банка памяти, используемого процессором в момент-прерывания. В микроконтроллере PIC16F84 все РОН отображены на оба банка, поэтому можно выбирать любые. Тем не менее это не слишком типичная ситуация, особенно если в модели используется большее число банков для поддержки большого количества уникальных РСН. В более новых моделях часто предусмотрена небольшая область памяти, отображенная на все банки, например, старшие 16 байт в модели PIC16F627/8, как показано на Рис. 5.4 (стр. 121). Более старые модели, такие как PIC16C74, вообще не имеют общих РОН. В этих случаях программист должен либо гарантировать, что прерывания не возникнут в те моменты, когда процессор работает с банком, отличным от используемого для сохранения, либо проверять состояние битов RP при входе в обработчик прерывания и переключаться на системный банк (обычно банк 0) перед сохранением регистра STATUS. Затем состояние битов RP в _status изменяется таким образом, чтобы оно соответствовало их исходному значению.
В нашем, намеренно упрощенном примере предполагается, что разрешено обслуживание только внешнего прерывания. В большинстве же случаев могут быть разрешены прерывания от нескольких источников. А поскольку в микроконтроллерах PIC имеется только один
bsf STATUS,RP0; Переключаемся на 1-й банк
btfsc INTCON,1; Проверяем флаг внешнего прерывания
goto EXTERNAL; ЕСЛИ установлен, переходим к соотв. обработчику
btfsc INTCON,2; Проверяем флаг прерывания от Таймера 0
goto TIMER0; ЕСЛИ установлен, переходим к соотв. обработчику
btfsc INTCON,0; Проверяем флаг прерывания по изменению порта В
goto CHANGE_B; ЕСЛИ установлен, переходим к соотв. обработчику
bcfsc EECON1,4; Проверяем флаг прерывания от EEPROM
goto EEPROM_WR; ЕСЛИ установлен, переходим к соотв. обработчику
... ...
IRQ_EXIT
bcf STATUS,RP0; Возвращаемся в 0-й банк
retfie ; и выходим из обработчика
Порядок опроса определяет уровень приоритета прерывания для случая одновременной генерации нескольких прерываний. Так что, если активно и внешнее прерывание, и прерывание от Таймера 0, то сначала будет обработано первое. В этом случае наличие отложенного запроса прерывания от Таймера 0 при возврате в основную программу приведет к повторному вызову процедуры обработки прерывания, где оно будет обработано (при условии, что в этот промежуток времени не возникло новых запросов прерывания с более высоким приоритетом). В любом случае соответствующий флаг должен сбрасываться, иначе прерывание будет генерироваться бесконечно! Сброс флага производится в соответствующей секции обработчика.
При сброшенном бите маски аналогичная методика опроса может применяться для контроля событий без использования прерываний. Например, при записи байта в EEPROM (см. Программу 15.2 на стр. 547) программа обычно ожидает установки флага EEIF (4-й бит регистра EECON1), после чего сбрасывает его и продолжает выполнение.