Цитата(d7d1cd @ Sep 12 2012, 21:45)

Спасибо за столь подробное пояснение. Подскажите как разрешить\запретить вложенные прерывания.
В составе ЦПУ MSP430 имеется регистр SR (другое название --R2) -- это регистр состояния процессора. Регистр состоит из множества флагов (бит), которые индицируют и управляют работой ЦПУ. Среди этих флагов есть флаг, отвечающий за глобальное разрешение прерываний. На него как бы сходятся все индивидуальные прерывания -- от портов, от таймеров, от компаратора, от АЦП и т.д. Прерывание от каждого устройства подчиняется своим индивидуальным флагам разрешения. Но все прерывания подчиняются одному глобальному флагу разрешения прерываний. В качестве некоторого аналога такой системы прерываний можно рассматривать как систему электроснабжения -- множество выключателей в комнатах и один общий рубильник. Разница только в направлении распространения воздействия: в электрической разводке энергия поступает от общего рубильника ко индивидуальным выключателям, а в системе прерываний МК -- прерывания транслируются в обратном направлении -- от периферийных устройств к глобальному флагу разрешения прерываний.
Когда этот флаг опущен (бит GIE равен "0") в системе не возникнет ни одно прерывание. Иначе говоря, если процессор выполняет какую-то программу, то она гарантированно не будет прервана, ни один обработчик прерываний не будет вызван. (Правда, в MSPЗ430 есть еще и не маскируемые прерываний, но этот случай лучше рассмотреть как-нибудь потом.)
Допустим, Вы пишите свою прогу. Прежде чем войти в бесконечный цикл (в функции main), Вы должны разрешить прерывания. Тогда Ваша прога, выполняя свою основную (фоновую) задачу, будет способна быстро реагировать на возникающие в системе события. "События" -- это различные внезапные (неожиданные) изменения чего-нибудь, например, счетчик до считал до конца или на входе порта изменился уровень сигнала. События (создают, провоцируют, генерируют) приводят к прерываниям работы основной (фоновой) программы.
Если поднят флаг GIE и разрешено индивидуальное прерывание от события (от устройства), то ход исполнения основной программы прерывается и вызывается код обработчика этого прерывания.
Непосредственно перед входом в обработчик прерывания происходит следующее (упрощено):
- в стеке сохраняется адреса программы, где произошло ее прерывание,
- в стек помещается состояние процессора (регистр SR),
- регистр SR очищается (обратите внимание -- в том числе сбрасывается и флаг глобального разрешения прерываний -- GIE. А это значит, что уже никакие другие прерывания не будут отрабатываться),
- и наконец вызывается обработчик прерывания.
При выходе из обработчика прерывания из стека восстанавливается состояние регистра состояния SR. Но сохраненное в стеке состояние регистра SR имеет поднятый флаг GIE, таким образом получается, что при выходе из прерывания автоматически снова разрешаются прерывания. Но пока исполняется код обработки прерывания другие прерывания запрещены.
Но Вы -- программист. Вы -- автор своего проекта, Вы знаете что вы делаете. И если Вам так необходимо обрабатывать вложенные прерывания, то Вы можете разрешить их -- установив снова флаг глобального разрешения прерываний GIE в своем обработчике прерываний.
Как устанавливается этот флаг -- зависит от компилятора. Например, в
msp-gcc я это делаю с помощью команды
__bis_SR_register(GIE), в IAR-е это можно сделать командой
_EINT(). Вам лучше посмотреть в документацию компилятора, который Вы используете.
Единственное, о чем бы я хотел Вас предупредить, -- не увлекайтесь вложенными прерываниями! Если у Вас возникает такая необходимость -- значит, Вы идете не той дорогой! Это еще не ошибка, но это уже знак "Впереди опасность!"
Извините, что много написал. Рассчитывал не только на Вас. Многим школьникам и студентам, думаю, поможет правильно ориентироваться в прерываниях.