Цитата(sonycman @ Jan 24 2009, 19:47)

А я почему-то подумал, что extern должен быть с точно таким-же типом, что и оригинальная переменная...

Ну вообще говоря "желательно".
Прокатить такое может только если в файл с обработчиком ISR не включать тот h-файл, в котором объявлено переменную для остальных - я же предпочитаю объявлеия включать везде для проверки (если вдруг поменяю в .h uint16_t на uint32_t, а в .c забуду - компилятор выругатся.
Но тогда
vv.h
Код
extern volatile unsigned u;
vv.c
Код
#include <vv.h>
unsigned u;
Компиляция:
Код
vv.c:2: error: conflicting type qualifiers for 'u'
./vv.h:1: error: previous declaration of 'u' was here
Я как правило кеширую переменную в обработчике прерывания во веменную и сохраняю при выходе.
Можно и так, набросал вот

Код
template <typename T, volatile T& var>
class cache_volatile
{
public:
cache_volatile() : t(var) {}
~cache_volatile() { var = t; }
T t;
};
volatile uint8_t timer;
ISR(TIMER0_OVF_vect)
{
cache_volatile<uint8_t, timer> tim;
if( --tim.t == 0 ) {
tim.t = 127;
}
if( PINB & 0x02) return; // тут тоже запишется назад изменённое значение
if( tim.t & 0x01 ) PINB |= 0x01;
}
Код
__vector_9:
push __zero_reg__
push __tmp_reg__
in __tmp_reg__,__SREG__
push __tmp_reg__
clr __zero_reg__
push r24
lds r24,timer
subi r24,lo8(-(-1))
brne .L2
ldi r24,lo8(127)
.L2:
sbic 54-0x20,1
rjmp .L4
sbrc r24,0
sbi 54-0x20,0
.L4:
sts timer,r24
pop r24
pop __tmp_reg__
out __SREG__,__tmp_reg__
pop __tmp_reg__
pop __zero_reg__
reti