Цитата(zltigo @ May 15 2008, 09:41)

В данном случае идет речь о чисто сишных + расширения компилятора возможностях.
Вообщем, есть достаточно простой метод. Без асма, но надо проследить один момент (об этом чуть позже). Я обычно поступаю следующим образом
Код
//Флаг необходимости запуска тяжелой части
#define NeedRunPart2 GPIOR0_Bit0
//Флаг блокировки, если не нужно разрешать прерывания, можно убрать
#define Part2Lock GPIOR0_Bit1
#pragma diag_suppress=Ta006
__interrupt void Int_part1(void)
{
//Легкая часть прерывания
....
if (....) NeedRunPart2=1;
....
}
__interrupt void Int_part2(void)
{
//Тут вызываем функции, извращаемся как хотим
....
....
....
}
#pragma diag_default=Ta006
#pragma vector=какой надо
__interrupt __raw void INT_dispatch(void)
{
((void(*)(void))Int_part1)();
__disable_interrupt();
if (!NeedRunPart2) return;
if (Part2Lock) return;
Part2Lock=1;
NeedRunPart2=0;
__enable_interrupt();
((void(*)(void))Int_part1)();
__disable_interrupt();
Part2Lock=0;
}
Главное тут - проверить, чтобы проверяемые и устанавливаемые флаги были в младших адресах пространства ввода-вывода, чтобы компилятор мог пользоваться SBIC/SBIS для проверки и SBI/CBI для манипуляций. Тогда можно не сохранять контекст в диспечере прерываний - эти комманды не портят SREG и другие регистры.
Вот такой код получается у диспечера:
Код
// 34 __interrupt __raw void INT_dispatch(void)
INT_dispatch:
// 35 {
// 36 ((void(*)(void))Int_part1)();
RCALL Int_part1
// 37 __disable_interrupt();
CLI
// 38 if (!NeedRunPart2) return;
SBIS 0x1E, 0x00
RJMP ??INT_dispatch_0
// 39 if (Part2Lock) return;
SBIC 0x1E, 0x01
RJMP ??INT_dispatch_0
// 40 Part2Lock=1;
SBI 0x1E, 0x01
// 41 NeedRunPart2=0;
CBI 0x1E, 0x00
// 42 __enable_interrupt();
SEI
// 43 ((void(*)(void))Int_part1)();
RCALL Int_part1
// 44 __disable_interrupt();
CLI
// 45 Part2Lock=0;
CBI 0x1E, 0x01
// 46 }
??INT_dispatch_0:
RETI
Кстати, приведенный код разрешает вложенные прерывания, для выполнения быстрой части пока выполняется медленная часть. Если этого не нужно, можно упростить.
И на посошок, не забыть запретить варнинг линкеру, что производится вызов обработчика прерывания как фунцкции.
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин