Перестает работать loop при работе прерывания по таймеру.
- Войдите на сайт для отправки комментариев
Пнд, 10/05/2021 - 00:50
Пишу скетч под atmega328p, где используется прерывание 2 таймер счетчика.
Все, что в функции прерывания работает отлично, но вообще не работает все что написано в процедуре loop.
Почему?
Догадываюсь, что нужно что то настроить в нулевом таймере... или нет?
код выкладывайте, без этого не о чем говорить
Такая хрень случается, когда прерывание таймера слишком длинное и на остальное не остается времени.
int x = 1; unsigned long time_f; void setup() { TCCR1B = 0b00000001; TCCR1A = 0b00100001; TCCR2B = 0b00000001; TCCR2A = 0b10100001; TIMSK2 |= (1<<0); SREG |= (1<<7); DDRD |= (1<<3); PORTD &=~(1<<3); DDRB |= ((1<<2) | (1<<3)); PORTB &=~((1<<2) | (1<<3)); } ISR (TIMER2_OVF_vect){ time_f = micros(); .... .... .... .... func1(); if((micros()-time_f) < 1 { func2(); } } void loop(){ func3(); }Выполняется func1() и func2() . во первых не могу понять почему вызывается func2(), неужели вся функция прерывания выполняется меньше 1 мкс. У меня там длиннющий код из 25 команд.
Во вторых не выполняется func3();
nik182
я правильно понял, что если функция прерывания будет выполнятся очень долго, то не будет вызываться loop(). Очень долго это 256*(время такта) ?
Такт системы 4 мкс, строка 25 будет выполняться всегда. Программирование прерываний подразумевает выполнение внутри прерывания только временизависимого кода. Типа выставления ноги при управлении тиристором. Всё остальное следует делать в цикле луп, по флагу из прерывания. Мы так и не увидели прерывание полностью. С коммерческими тайнами в платный раздел. Там помогут.
На месте компилятора я строку 25 вообще бы отказался обрабатывать.
micros() в ISR "не ходит".
А с какой целью isr прописан внутри setup ???
с чего бы это, с миллисом не спутаЛ?
во первых не могу понять почему вызывается func2(), неужели вся функция прерывания выполняется меньше 1 мкс.
Вы в условии знак "больше- меньше" не перепутали?
Строка 25 и будет выполнятся, если длина прерывания менее 1 мкс
с чего бы это, с миллисом не спутаЛ?
Полноценно не ходит.
ISR(TIMER0_OVF_vect) { ... timer0_fract = f; timer0_millis = m; <<<<<<< (1) timer0_overflow_count++; <<<<<<< (2) } unsigned long millis() { ... cli(); m = timer0_millis; <<<<<<< (1) SREG = oldSREG; return m; } unsigned long micros() { m = timer0_overflow_count; <<<<<<< (2) ... SREG = oldSREG; return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); }1. Спасибо за намек про 4 мкс, выставил предделитель 0-го таймера на 1.
Теперь работает micros в прерывании и я измерил время выполнения функции прерывания = 3мкс.
ВСЕ заработало! Даже не сразу понял. Дело было в том что нулевой таймер работал слишком медленно.
А с какой целью isr прописан внутри setup ???
Извините, скобочку забыл
int x = 1; unsigned long time_f; void setup() { TCCR1B = 0b00000001; TCCR1A = 0b00100001; TCCR2B = 0b00000001; TCCR2A = 0b10100001; TIMSK2 |= (1<<0); SREG |= (1<<7); DDRD |= (1<<3); PORTD &=~(1<<3); DDRB |= ((1<<2) | (1<<3)); PORTB &=~((1<<2) | (1<<3)); } ISR (TIMER2_OVF_vect){ time_f = micros(); .... .... .... .... func1(); if((micros()-time_f) < 1 { func2(); } } void loop(){ func3(); }А код-то где? Он секретный?
Тогда
не о чем говорить
ТС, почитайте что нить о volatile, есть такой модификтор. Было бы не плохо, если бы работая с прерываниями вы понимали что такое атомарность. Ну а если вам лень, то для всех переменных объявленных глобально и используемых в прерываниях добавляйте этот модификатор. В вашем случае хуже не будет. Например:
ТС, почитайте что нить о volatile, есть такой модификтор. Было бы не плохо, если бы работая с прерываниями вы понимали что такое атомарность. Ну а если вам лень, то для всех переменных объявленных глобально и используемых в прерываниях добавляйте этот модификатор. В вашем случае хуже не будет. Например:
Спасибо за любой совет, мне не лень, обязательно почитаю.
Я первый раз на форуме, но чувствуется какая то агрессия среди завсегдатаев, чтоб не дай бог проект не оказался коммерческим и я не заработал не поделившись с остальными)
Код не секретный, но я считаю нет смысла кидать километр кода , и достаточно кинуть кусок, где возникает суть вопроса. И, как оказалось, я был прав. Уважаемому nik182 этого оказалось достаточным и он помог, ткнув в правильном направление, за что ему и остальным огромное спасибо!) Всем добра!
Тема закрыта
агрессия среди завсегдатаев, чтоб не дай бог проект не оказался коммерческим и я не заработал не поделившись с остальными)
Точно подмечено! Больше того, старожилы постоянно пытаются украсть код новичков, ведь в нем всегда много свежих идей и приемов программирования! Пруфы в #1 и #13! Вы очень мудро поступили, не дав полный код
Код не секретный, но я считаю нет смысла кидать километр кода , и достаточно кинуть кусок, где возникает суть вопроса.
Вы неправильно считаете.
Если Вы задаете вопрос, сопровождать его следует кодом, который компилируется. Вы можете сколько угодно выбрасывать фрагменты из своего первоначального кода, но тот остаток, что Вы помещаете на форуме, должен с одной стороны компилироваться, а с другой - иллюстрировать проблему.