Пишу довольно большой проект. И столкнулся с проблемой. В программе используются два прерывания: при переполнении таймера0, и при завершении АЦП. Обработчик прерывания от tmr0 довольно длинный. В самом его начале запускается начало АЦП (ADSRA.6 = 1). Но атмега8 просто игнорирует прерывание от АЦП, в него она просто не залетает. В-общем, проблема свелась в следующему простому коду:
При комментировании delay(500) в прерывании от таймера, прерывание от АЦП СРАБАТЫВАЕТ. При внесении же delay_ms (500), т.е. "удлинения по времени" прерывания от таймера, прерывание от АЦП игнорируется. В чем может быть дело? P.S. Контроль данных АЦП выводится на ЛСД дисплей (100% рабочий). P.S.S. В протеусе все эмулится нормально.
Там сказано что AVR не помнит порядок появления накопленых прерываний (порядок установки их флагов) и поэтому обрабатывает их по порядку расположения в таблице прерываний в даташите.
Т.е. у вас перед флагом АЦП всегда есть флаг таймера (если он устанавливается за время большой паузы) - его и обрабатывает мега8.
Там же КРУПНО написано:
Делайте функции обработчики прерывания как можно короче ! Не засиживайтесь в них ...
Нужно тщательно продумывать алгоритм программы чтоб успевать обрабатывать все прерывания - т.е. не пропускать нужные события и обрабатывать их вовремя.
что такое delay(500), это сколько??? написали же, русским языком
Там сказано что AVR не помнит порядок появления накопленых прерываний (порядок установки их флагов) и поэтому обрабатывает их по порядку расположения в таблице прерываний в даташите.
Т.е. у вас перед флагом АЦП всегда есть флаг таймера (если он устанавливается за время большой паузы) - его и обрабатывает мега8.
т.е. таймер всегда находится в своем прерывании, т.к. за 0,5сек оно точно наступит
C-r-o-w писал(а):При комментировании delay(500) в прерывании от таймера, прерывание от АЦП СРАБАТЫВАЕТ.
Значит дело не во флагах, а в delay-е.
Я об этом и написал. Внимательно перечитайте если интересно.
Добавлено спустя 2 минуты 31 секунду:
SERGEY_M писал(а):т.е. таймер всегда находится в своем прерывании, т.к. за 0,5сек оно точно наступит
Нет. Прога почти всегда находится в прерывании от таймера. Таймер там не находится
Когда прога выходит из этого прерывания то обнаруживает два флага - от таймера (который внось возник за время длинной паузы) и от АЦП и обрабоатывает ПЕРВЫЙ их них по списку в даташите.
Если в конце прерывания сделать очистку флага от таймера то вероятно прога сможет попасть в прерывание от АЦП.
avr123.nm.ru писал(а):Если в конце прерывания сделать очистку флага от таймера то вероятно прога сможет попасть в прерывание от АЦП.
Да, идеи теперь две: либо переносить весь обработчик таймера в мэйн и сделать там свой "переполнитель" таймера, либо в прерывании от таймера тормозить сам таймер и обнулять его... Наверно лучше первое. Спасибо всем за внимание!