Вы правы. Отлаживал свою программку и столкнулся что прерывания происходят весьма странно.По поводу сброса-запуска таймера в прерывании
-запрет прерывания в самом прерывании нелогичен, т.к. I-флаг сбрасывается в прерывании аппаратно. Другое дело очищать флаги или исключать из таблиц состояния вызывающие такие требования (например первый элемент Вашей таблицы, в котором сразу в таймер загружается максимальное число, а таймер не остановлен. Т.е. следующее прерывание будет несанкционированным)
-манипуляции с предустановками в TCNT1 можут привести к появлению флага TOV1, да и другие флаги могут взвестись. Причем на аппаратном уровне. Я так привык делать
-остановил
-очистил, чтобы начинать с одной точки
-загрузил требуемое значение
-сбросил флаги
-запустил
Итак, для полной прозрачности и уверенности, что всё теперь сделано правильно приведу пример.
Программа делает следующее. В 2-х циклах опрашивается кнопка вкл/выкл.
Когда кнопка нажимается в первом цикле, то начинается второй цикл. Когда нажата во втором - то первый цикл. В первом цикле разрешено прерывание по переполнению таймера 0, во втором таймера 1. Кнопка PA5 при замыкании вызывает "низкий".
Всё что касается настройки таймеров для читабельности подчеркну.
ldi work,0b00000101;
out TIMSK,work;разрешить прерывание по переполнению таймера 0 и таймера
rjmp stop
stop:
ldi work,0b00000100;
out TCCR0,work;выбрать К=256
ldi t_count0,250;
out TCNT0,t_count0;заряжаем таймер
stop1:
sbic PINA,PA5;проверяем на нажатие кнопку
rjmp stop1;не ражата - повторить опрос
otpusk_1:;нажата - проверить на отпускание
sbis PINA,PA5
rjmp otpusk_1
rjmp invertor;отпущена? выключаем таймер, запрещаем прерывания по нему, разрешаем по таймеру 1.
invertor:
ldi work,0b00000000;
out TCCR0,work;останавливаем
ldi t_count0,0;очищаем
out TCNT0,t_count0;заряжаем таймер;выводим.т.е. наш таймер0 "заглушен"
;теперь включаем прерывание по переполнению 16-битного таймера1:
ldi work,0b00000000;
out TCCR1А,work;тут ничего интересного нету, поэтому просто очищаем
ldi work,0b00000010;
out TCCR1В,work;выбрать К=8
ldi t_count1_H,0x01;
ldi t_count1_L,0x01;
out TCNT1H,t_count1_H;заряжаем таймер произвольными значениями, просто чтобы вызвать
out TCNT1L,t_count1_L;прерывание.
sw_pusk:
sbic PINA,PA5;проверяем на нажатие
rjmp sw_pusk;не нажата? повторная проверка
otpusk_2:
sbis PINA,PA5;нажата? проверяем на отпускание
rjmp otpusk_2;
rjmp stop;отпущена? перейти в цикл, где разрешено прерывание по таймеру0
Теперь наше прерывание.
TIM1_OVF:
ldi work,0x00
out TCCR1B,work;останов таймера
out TCNT1H,work;сбросить таймер-счётчик
out TCNT1L,work;
rjmp извлечь из таблички значение
извлечь из таблички значение:
бла-бла-бла. теперь у нас в TCNT1L и TCNT1H нужные числа
rjmp выход
выход:
ldi work,0xFF
out TIFR,work;сброс всех флагов
ldi work,0b00000010
out TCCR1B,work;запустить с К=8
reti



