Использование 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() {
}
Что я делаю не так?
@adrya407, 👍1
Обсуждение2 ответа
Лучший ответ:
Основная проблема заключается в том, что вы используете неправильный обработчик прерываний. Вы настраиваете 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
Таймеры Arduino зарезервированы для встроенных функций:
Timer0 зарезервирован для запуска миллисекундного прерывания для счетчика миллисекунд. Timer1 зарезервирован для измерения времени, прошедшего с момента последней перезагрузки. Timer2 зарезервирован для синхронизации PWM
Таким образом, использование этих таймеров не является хорошим предложением, если вы планируете использовать указанные выше параметры. На мой взгляд, Timer0 кажется хорошим выбором, так как синхронизация в микросекундах немного излишняя.
Здесь вы можете найти решение: https://learn.adafruit.com/multi-tasking-the-arduino-part- 2/таймеры
В UNO все три таймера участвуют в синхронизации ШИМ. Откуда берутся претензии к Timer1?, @timemage
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Генерация стабильной частоты
- Как исправить ошибку компиляции для tone (), используя тот же таймер, что и другая функция
- Использовать timer0, не влияя на millis() и micros().
Вы знаете, что вам не нужно использовать прерывания для этого. Вы можете указать таймеру изменить выходной контакт, когда счетчик переполняется или достигает значения
OCR1A
. Вы делаете это с помощью битаCOM1A1
COM1A0
в регистреTCCR1A
. Хотя вам придется использовать контакт 9 (или 10) вместо контакта 8., @Gerben