Использование timer0 на Arduino Uno

Я пытаюсь найти простой пример прерывания timer0, но ни один из них не работает. Ни этот код, который я пытался запустить:

boolean toggle0 =0;

void setup() {
pinMode(8, OUTPUT);
  cli();

  // Установить прерывание от таймера 1 на 1 Гц
  TCCR1A = 0; // Установить весь регистр TCCR1A в 0
  TCCR1B = 0; // То же самое для TCCR1B
  TCNT1  = 0; // Инициализируем значение счетчика равным 0

  // Установить регистр совпадения сравнения с шагом 1 Гц
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (должно быть < 65536)

  // Включаем режим CTC
  TCCR1B |= (1 << WGM12);

  // Установите биты CS12 и CS10 для прескалера 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);

  // Разрешить прерывание сравнения таймера
  TIMSK1 |= (1 << OCIE1A);

  sei();
}

ISR(TIMER0_COMPA_vect){  // Изменяем 0 на 1 для таймера 1 и 2 для таймера 2
  if (toggle0){
    digitalWrite(8,HIGH);
    toggle0 = 0;
  }
  else{
    digitalWrite(8,LOW);
    toggle0 = 1;
  }
}

void loop() {

}

Что я делаю не так?

, 👍1

Обсуждение

Вы знаете, что вам не нужно использовать прерывания для этого. Вы можете указать таймеру изменить выходной контакт, когда счетчик переполняется или достигает значения OCR1A. Вы делаете это с помощью бита COM1A1 COM1A0 в регистре TCCR1A. Хотя вам придется использовать контакт 9 (или 10) вместо контакта 8., @Gerben


2 ответа


Лучший ответ:

1

Основная проблема заключается в том, что вы используете неправильный обработчик прерываний. Вы настраиваете Timer1, но обработчик прерываний предназначен для Timer0:

boolean toggle0 = 0;

void setup() {
pinMode(8, OUTPUT);
  cli();
// устанавливаем прерывание от таймера 1 на 1 Гц
  TCCR1A = 0;// устанавливаем весь регистр TCCR1A в 0
  TCCR1B = 0;// то же самое для TCCR1B
  TCNT1  = 0;//инициализировать значение счетчика до 0
  // установить регистр совпадения для сравнения с шагом 1 Гц
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (должно быть < 65536)
  // включаем режим CTC
  TCCR1B |= (1 << WGM12);
  // Установите биты CS12 и CS10 для прескалера 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  // включить прерывание сравнения таймера
  TIMSK1 |= (1 << OCIE1A);

  sei();
}

ISR(TIMER1_COMPA_vect){  // изменяем 0 на 1 для таймера 1 и 2 для таймера 2
  toggle0 = !toggle0;
  digitalWrite(8, toggle0);
}

void loop() {

}
,

Спасибо, не могли бы вы обновить его, чтобы он работал с прерыванием timer0?, @adrya407

@adrya407 adrya407 Я бы не рекомендовал, так как Timer0 используется для millis(), задержек и так далее. Если вы измените тики с 1,024 мс (прерывание переполнения) на CTC ровно с 1 с (сравните прерывание совпадения), то переполнение больше не будет работать., @KIIV


0

Таймеры Arduino зарезервированы для встроенных функций:

Timer0 зарезервирован для запуска миллисекундного прерывания для счетчика миллисекунд. Timer1 зарезервирован для измерения времени, прошедшего с момента последней перезагрузки. Timer2 зарезервирован для синхронизации PWM

Таким образом, использование этих таймеров не является хорошим предложением, если вы планируете использовать указанные выше параметры. На мой взгляд, Timer0 кажется хорошим выбором, так как синхронизация в микросекундах немного излишняя.

Здесь вы можете найти решение: https://learn.adafruit.com/multi-tasking-the-arduino-part- 2/таймеры

,

В UNO все три таймера участвуют в синхронизации ШИМ. Откуда берутся претензии к Timer1?, @timemage