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);  
}

, 👍1

Обсуждение

Вы уверены, что 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


1 ответ


1

В вашем цикле отсутствует оператор else:

else
  digitalWrite(led_pin,LOW); 
,