Arduino Nano 33 IoT - Timer interrupts

Hi, I need to use a function that will cyclically call with interrupts every 5 seconds.
Currently my code looks like this:

void setup()
{
  Serial.begin(115200);
  REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3) ;
  while ( GCLK->STATUS.bit.SYNCBUSY == 1 );
  
  TcCount32* TC = (TcCount32*) TC3;

  TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
  while (TC->STATUS.bit.SYNCBUSY == 1);

  TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT32;
  while (TC->STATUS.bit.SYNCBUSY == 1);
  TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_NFRQ;
  while (TC->STATUS.bit.SYNCBUSY == 1);

  TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024;
  while (TC->STATUS.bit.SYNCBUSY == 1);

  TC->CC[0].reg = 0x39386;
  while (TC->STATUS.bit.SYNCBUSY == 1);

  TC->INTENSET.reg = 0;
  TC->INTENSET.bit.MC0 = 1;

  NVIC_EnableIRQ(TC3_IRQn);

  TC->CTRLA.reg |= TC_CTRLA_ENABLE;
  while (TC->STATUS.bit.SYNCBUSY == 1);
}

void loop()
{
  Serial.println("DO NOTHING");
  delay(1000);
}

void TC3_Handler()
{
  TcCount32* TC = (TcCount32*) TC3;

  if (TC->INTFLAG.bit.MC0 == 1)
  {
    Serial.println("INTERRUPT");
    TC->INTFLAG.bit.MC0 = 1;
  }
}

Theoretically from the equation i used:

Interrupt frequency (Hz) = (Arduino clock speed: 48MHz) / (Prescaler: 1024 * (Compare match register: 234374 (in decimal) + 1))

, comes out that the interrupt should be called every 5 seconds, but it is called around every 1.5 seconds.

Would someone be able to help on this topic?

You shouldn't be calling Serial inside a function. Can't you blink the onboard LED or something?

Writing over the UART was only indicative if the function was being called correctly. I changed the code using two diodes:

#define LED_RED   3
#define LED_GREEN 2

bool led_on = false;

void setup()
{
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);

...
*No changes*
...

void loop()
{
  digitalWrite(LED_RED, HIGH);
  delay(1000);
  digitalWrite(LED_RED, LOW);
  delay(1000);
}

void TC3_Handler()
{
  TcCount32* TC = (TcCount32*) TC3;
  if (TC->INTFLAG.bit.MC0 == 1)
  {
    if (led_on)
    {
      digitalWrite(LED_GREEN, LOW);
      led_on = false;
    }
    else
    {
      digitalWrite(LED_GREEN, HIGH);
      led_on = true;
    }
    TC->INTFLAG.bit.MC0 = 1;
  }
}

As expected, the red LED is working properly and the green LED lights up and goes out with an interval of about 1.5 seconds.

I know, just trying to rule out possible unrelated contributing issues... thanks.

When I run those numbers, I get 0.2

, which is exactly 5 seconds.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.