-

Сохранение SREG в прерываниях

Зачем вообще сохранять SREG в прерываниях?

Сохранять нужно не только SREG, а все, что используется в основной программе и может быть изменено в прерывании. Прерывание поому и прерывание, что может возникнуть в любой момент времени. Например, между вот этими двумя командами:

cmp R18,R22
brlo LABEL1

Что будет, если в этом прерывании будет изменен, например, признак C в SREG ? Будет переход не в зависимости от результата сравнения R18 и R22, а в зависимости от того, что делалось в прерывании. То есть - случайно. То есть - у микроконтроллера съезжает крыша и он делает совсем не то, что от него требовалось...


Вообще-то возможен вариант, когда ничего сохранять не надо. Например, в прерывании вы выставляете флажок, сообщающий основной программе о том, что оно имело место быть, например:

Timer0int:

ldi FLAG,1
reti

Команда LDI биты признаков в SREG не меняет, изменение регистра FLAG вполне "законное" - следовательно, такой обработчик "правильный". Если же вы захотите установить только один бит регистра FLAGI, нужно SREG сохранять - так как команда SBR признаки меняет, являясь, по сути, командой ORI. В этом случае обработчик должен выглядеть так:

Timer0int:

push R16     ; сохранить регистр!
in R16,SREG  ;
и в него сохранить SREG
sbr FLAG,1
out SREG,R16 ;
SREG восстановить
pop R16      ;
и регистр тоже!
reti

Тут следует заметить, что в весьма популярном среди  начинающих микроконтроллере AT90s1200 стека нет (точнее, есть, но аппаратный - только для сохранения адреса возврата) и команд PUSH / POP, соответственно, тоже. В этом случае отведите один регистр только для сохранения в нем SREG, обработчик примет вид:

Timer0int:

in R1,SREG   ; R1 нигде не использовать!
sbr FLAG,1
out SREG,R1  ;
получилось даже короче, только регистра жалко :-)
reti


И в завершение совет использующим Algorithm Builder. Не забывайте, что регистры R16 и R17 используются в макрорасширениях, например, если вы используете команду

1 -> R1

То генерируется следующая последовательность команд:

ldi r16,1
mov R1,R16

Следовательно, при достаточно сложном обработчике лучше не умничать, а сохранить эти регистры. Иначе потом, вставив одну команду, рискуете получить занимательный геморрой с поиском крайне трудноловимой ошибки. Не будете же вы каждый раз просматривать листинг (хотя - на мой взгляд - дело очень полезное!)

 

 

(с)nml 08-Dec-2006


кнауф грунтовка