Проблема с прерыванием по совпадению
- Войдите на сайт для отправки комментариев
Пнд, 21/10/2019 - 11:47
Доброго времени суток.
Прошу не судить строго - я только недавно начал пробовать работать с ардуино. Возник следующий вопрос - в моем коде
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int nOverflows = 0;//Keeps track of the number of overflows
void initBlinkTimer()
{
DDRB |= (1<<PB1);//Set PB1 as output
asm("cli");
TCCR0A = 0;
TCCR0B = 0;
TCCR0B |= (1<<CS02) | (1<<CS00);//Set the prescaler to 1024
TCCR0A |= (1<<WGM01); //Timer0 with CTC Mode
OCR0B = 250;//Compare TCNT0 with 250
TIMSK |= (1<<OCIE0B); //Interrupt at OCR0B compare match aka: execute interrupt when TCNT0 equals 16
asm("sei");//Enable global interrupts, so that the interrupt routine can be executed upon the OCR0B compare match
}
ISR(TIMER0_COMPB_vect)
{
nOverflows ++;
}
int main()
{
initBlinkTimer();
while(1){
if (nOverflows == 2){
PORTB ^= (1<<PB1);
nOverflows =0;
}
}
}
прерывание вызывается только 1 раз и все. Что не так? Если поставить значение переменной nOverflows == 1 то светодиод засветится, если более 1 (тоесть 2 и более) ничего не работает. Хотя по логике должно.
Как ни странно но добавление в обработчик прерывания строчки с обнулением счетчика решило проблему. тоесть
ISR(TIMER0_COMPB_vect) { nOverflows ++; TCNT0 = 0; }Но тогда почему он сам не сбрасывается в 0 при достижении максимума? это не понятно...
и чо, и миллис так намайна работает?
Дед! Я про тебя картинко утром на анекдотах увидал! Держи!
от спасибо. В рамочку повешаю.
На счет милис не понял.
Это пока просто проверка идеи, а так в будущем это будет генератор звуковой частоты с плавным изменением значения выходного сигнала (частоты) с помощью оптического энкодера. Для моргалки и милис подойдет))
ты счетчик в прерывании сбрасываешь в 0, т.е до 0хFF он не доходит, и прерывание по переполнению, на котором зиждеца millis() не срабатывает. По крайней мере - не должно, это ж нулевой таймер?
Кажись начинаю понимать. Милис конечно мне и даром не нужен, а ардуинка получается что ждет его? А его все нет и нет))) Да, таймер Т0 пользую. Других то в тини85 и нету (кроме Т1) но он тоже 8ми битный. потому и приходится так извращаться.
вот рабочий код прерывания по совпадению с регистром А
Настройка
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { TCCR0A = TCCR0A & 0b11111100; // Таймер в режиме Normal OCR0A = 245; // загрузим регистр совпадения TIMSK0 |= 0x3; // установить OCIE0A и TOIE0, разрешим совпадение А и переполнение TIFR0 |= 0x2; // очистим флаг OCF0A если до этого он был установлен, ждём следущего совпадения }процедура прерывания
ISR(TIMER0_COMPA_vect){ TCNT0 = 0xFF; // чтоб на следующем шаге сработало переполнение и посчитался millis . . . }