This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

timer Interrupts nrf

//#define TRIGGER_INTERVAL 100 // ms
int LED = 8;
//int LED1 = 7;
int i = 0;
void timer_config(void)
{
NRF_TIMER0->TASKS_STOP = 1; // Stop timer
NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // taken from Nordic dev zone
NRF_TIMER0->BITMODE = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
NRF_TIMER0->PRESCALER = 8; // 1us resolution
NRF_TIMER0->TASKS_CLEAR = 1; // Clear timer
NRF_TIMER0->CC[0] = 62500; 
NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos; // taken from Nordic dev zone
NRF_TIMER0->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
//attachInterrupt(TIMER1_IRQn, TIMER1_Interrupt); // also used in variant.cpp to configure the RTC1 
NVIC_EnableIRQ(TIMER0_IRQn);
NRF_TIMER0->TASKS_START = 1; // Start TIMER
// digitalWrite(LED, HIGH);
// delay(3000);
// 
}

void setup() {
Serial.begin(115200);
pinMode(LED,OUTPUT);
digitalWrite(LED, LOW);
delay(3000);
timer_config();
}

void loop() {
// digitalWrite(LED, LOW);
// delay(1000);
// digitalWrite(LED, HIGH);
// delay(1000);
// //digitalWrite(LED, HIGH);
// //digitalWrite(LED, HIGH);

//while(1);
}

void TIMER0_IRQHandler()
{
// digitalWrite(LED, LOW);
// delay(1000);
// digitalWrite(LED, HIGH);
// delay(1000);
if (NRF_TIMER0->EVENTS_COMPARE[0] != 0)
{
//Serial.println("Timer interrupt called");
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
int i = i+1;
if(i%2 == 0)
{
digitalWrite(LED, LOW);
delay(1000);
}
else
{
digitalWrite(LED, HIGH );
delay(1000);
}

}
}

Hey this is my code for blinking an led using timer interrupt on nrf 52832board, there are no errors in the code but the code is not working as desired. The function TIMER_IRQHandler is not called during an interrupt.

can someone please help me to tackle this problem?

  • Hi,

    I do not see any problems with how you have configured the timer. Have you verified that TIMER0_IRQHandler() is not called by placing a breakpoint at the start of the function? (Additionally, you may get problems missing interrupts if your delay(1000) call takes longer time than for the timer to count up to 62500 again).

  • How to verify the TIMER0_IRQHandler()?

    Or can you just post the code which could toggle the led for every 1second using interrupt?

  • The simplest way to check if TIMER0_IRQHandler() is called is to put a breakpoint in the first lien of the function. If it is hit, that means that the interrupt mechanism works.

    Generally, this is also safer than toggling LEDs, as a common problem with using LEDs to debug is that if stuff happens too fast, you may not actually see the LED changing state. I see you allready have LED toggle mechanism there which I assume work (though I cannot see the implementation of your digitalWrite() function). As mentioned, you should not use the delay() function, which I assume is a busy wait. This will mess up your timing.

  • //#define TRIGGER_INTERVAL 100 // ms
    int LED = 8;
    //int LED1 = 7;
    int i = 0;
    void timer_config(void)
    {
    NRF_TIMER0->TASKS_STOP = 1; // Stop timer
    NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // taken from Nordic dev zone
    NRF_TIMER0->BITMODE = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
    NRF_TIMER0->PRESCALER = 8; // 1us resolution
    NRF_TIMER0->TASKS_CLEAR = 1; // Clear timer
    NRF_TIMER0->CC[0] = 62500;
    NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos; // taken from Nordic dev zone
    NRF_TIMER0->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
    //attachInterrupt(TIMER1_IRQn, TIMER1_Interrupt); // also used in variant.cpp to configure the RTC1
    NVIC_EnableIRQ(TIMER0_IRQn);
    NRF_TIMER0->TASKS_START = 1; // Start TIMER
    }

    void setup() {
    digitalWrite(LED, HIGH);
    delay(1000);
    timer_config();
    }

    void loop() {

    while (1);
    }

    void TIMER0_IRQHandler()
    {

    if (NRF_TIMER0->EVENTS_COMPARE[0] != 0)
    {
    NRF_TIMER0->EVENTS_COMPARE[0] = 0;
    digitalWrite(LED, LOW);
    }


    I removed the delay.

    But i could not see any improvement. I am still not able to call TIMER0_IRQHandler().

  • This code should work. I took your code and did a few trivial adaptations to be able to test it on the nRF52 DK. I expect it will work on any nRF5 device, though.

    void TIMER0_IRQHandler()
    {
        if (NRF_TIMER0->EVENTS_COMPARE[0] != 0)
        {
            NRF_TIMER0->EVENTS_COMPARE[0] = 0;
        }
    }
    
    void timer_config(void)
    {
        NRF_TIMER0->TASKS_STOP = 1; // Stop timer
        NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // taken from Nordic dev zone
        NRF_TIMER0->BITMODE = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
        NRF_TIMER0->PRESCALER = 8; // 1us resolution
        NRF_TIMER0->TASKS_CLEAR = 1; // Clear timer
        NRF_TIMER0->CC[0] = 62500;
        NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos; // taken from Nordic dev zone
        NRF_TIMER0->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
        //attachInterrupt(TIMER1_IRQn, TIMER1_Interrupt); // also used in variant.cpp to configure the RTC1
        NVIC_EnableIRQ(TIMER0_IRQn);
        NRF_TIMER0->TASKS_START = 1; // Start TIMER
    }
    
    void setup() 
    {
        timer_config();
    }
    
    int main(void)
    {
        setup();
        while (1);
    }
    

    The IRQ handler is called, verified by the breakpoint, as you can see from the screenshot.

Related