Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
Питание батарейное. Хочется не жечь батареи попусту, и через некоторое время переводить оптопары в состояние "выключено". Включать повторно - по кнопке клавиатуры. Клавиатура опрашивается в цикле, без использования прерываний.
Пока пытаюсь делать так:
При возникновении прерывания INT0:
--Запрещаю прерывания (cli);
--Запускаю Timer1 (он готов к счету, так что тут только "TCCR1B=0x01;");
--устанавливаю работу только с прерыванием от ICP и Timer1Overflow;
--разрешаю прерывания (sei);
При возникновении прерывания от ICP:
--Запрещаю прерывания (cli);
--Сохраняю результат Timer1;
--Переустанавливаю Timer1 (теперь он готов к счету, остается только запустить);
--Запускаю обратный счетчик "до отключения оптопар";
--устанавливаю работу только с прерыванием INT0 (готов к следующему замеру);
--разрешаю прерывания (sei);
MAIN:
- разрешаю прерывания (sei);
- Работаю в цикле:
---сканирую кнопки (постоянно);
---декрементирую обратный счетчик "до отключения оптопар" (если он включен);
При нажатии кнопки "проснуться":
- включаю оптопары;
- устанавливаю работу только с прерыванием INT0;
- разрешаю прерывания (sei);
При истечении счетчика "до отключения оптопар"
- выключаю оптопары;
- запрещаю прерывания (cli);
Идеологически все вроде бы красиво, но на практике не работает. При выполнении разрешения прерывания (sei) разрешенная функция обработки прерывания выполняется сразу же. Подозреваю, что собака зарыта в моем способе управления работой "только с прерыванием ХХХ".
Включение только INT0 я делаю так:
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT2: Off
// Timer(s)/Counter(s) Interrupt(s) initialization
GICR|=0x40;
MCUCR=0x02;
MCUCSR=0x00;
GIFR=0x40;
TIMSK=0x00;
Включение только ICP и Timer1Overflov я делаю так:
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// Timer(s)/Counter(s) Interrupt(s) initialization
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x24;
Почему при выполнении разрешения прерывания (sei) разрешенная функция обработки прерывания выполняется сразу же? Что я делаю неправильно?