ISR для таймера на Arduino MEGA вызывается только один раз
Я пытаюсь написать код Arduino для мигания светодиода с помощью таймера 4 на Arduino MEGA (atmega2560). Я сбросил регистры таймера и ввел все необходимые значения, чтобы довести их до 16 МГц до 1 Гц (rescalar = 1024, OCR4B = 15624), а затем написал мигающий код внутри блока служебной подпрограммы. Теперь, когда я запускаю программу, ISR вызывается только один раз. Я видел из видео на Youtube, что даже несмотря на то, что настройка регистров TCCR и TIMSK находится в функции setup (), она повторяется бесконечно, как цикл. Ниже приведен мой код. Любая помощь будет безмерно оценена. Спасибо.
int led_pin = 10;
static int counter = 0;
int led_blink = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(led_pin,OUTPUT);
cli();
TCCR4A = 0;
TCCR4B = 0;
TCNT4 = 0;
OCR4B = 15625; //установить максимальный счетчик 16 МГц -> 1 Гц
TCCR4B |= (1<<CS10) | (1<<CS12) | (1<<WGM12); // prescalar = 1024 , CTC(OCR3B) mode
TIMSK4 |= (1<<OCIE4B);
sei();
interrupts();
}
ISR(TIMER4_COMPB_vect)
{
Serial.println(millis());
led_blink = !led_blink;
}
void loop() {
// put your main code here, to run repeatedly:
if(led_blink == 1)
digitalWrite(led_pin,HIGH);
}
@Ashwathama, 👍1
Обсуждение1 ответ
Смотрите также:
- Запустить Timer1 в ATmega2560 со сборкой
- Установить ШИМ по периоду? И он переменный?
- Считать данные датчика повторно через указанное время?
- Arduino mega PinChangeInterrupt с 16 битным таймером
- Arduino Mega 2560 подсчет задержек между событиями на разных контактах
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
Вы уверены, что ISR вызывается только один раз? С вашим текущим кодом светодиод будет только гореть, а не мигать (так как вы его нигде не выключаете). Получаете ли вы последовательный вывод на последовательном мониторе, который показывает значения `millis ()'?, @chrisl
Можно задать переменную и выполнить "тяжелую работу" за пределами ISR, но здесь вы немного отклонились в сторону.
digitalWrite
очень дешев, и наличие его в ISR не должно создавать проблем, но "Serial.println" - очень сложная функция, которая сама по себе использует таймеры и занимает несколько мс для выполнения., @PMFВы можете использовать uint8_t для переменной led_blink, и она должна быть изменчивой. В противном случае компилятор может оптимизировать его, когда выяснится, что он не может измениться. Также led_pin волшебным образом не очищается. Он останется неизменным навсегда, если вы не напишете на него НИЗКО..., @KIIV
О, мне жаль, да, я забыл, что вы написали LED to low в другом состоянии, но даже после этого я заметил, что Serial.println(millis()) все еще работал только один раз. Но к несчастью, когда я попытался добавить значения в оба OCR4A и написал ISR для регистра, это сработало отлично, даже Serial.println() работал. Кто-нибудь может объяснить, пожалуйста, почему? Также спасибо вам за то, что поделились своими знаниями. Я понятия не имел, что Serial.println() использует таймеры. Вещи для новичков., @Ashwathama