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

Not able to setup timer interrupt in nRF51822

Timer_interrupt.txt

Hi all, can anyone please help me in setup up the timer interrupt? I could only see the printing of "Entered 2". Kindly check on the attached text file for my code. Kindly assist. Thanks in advance.

Parents
  • Arduino source code is compiled as C++, but IRQ Handler is linked as C. So you have to declare void TIMER1_IRQHandler(void) with C linkage.

    #include <nrf.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void TIMER1_IRQHandler(void);
    #ifdef __cplusplus
    }
    #endif
    
    // count to us (micro seconds) conversion factor
    // set in start_timer()
    static volatile float countToUs = 1;
    
    // counter
    static volatile uint32_t tCount = 0;
    
    
    // set up and start Timer1
    void start_timer(void)
    {
        NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
        NRF_TIMER1->TASKS_CLEAR = 1;
        // set prescalar n
        // f = 16 MHz / 2^(n)
        uint8_t prescaler = 0;
        NRF_TIMER1->PRESCALER = prescaler;
        NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    
        // 16 MHz clock generates timer tick every 1/(16000000) s = 62.5 nano s
        // With compare enabled, the interrupt is fired every: 62.5 * comp1 nano s
        // = 0.0625*comp1 micro seconds
        // multiply this by 2^(prescalar)
    
        uint16_t comp1 = 500;
        // set compare
        NRF_TIMER1->CC[1] = comp1;
    
        // set conversion factor
        countToUs = 0.0625 * comp1 * (1 << prescaler);
    
        //printf("timer tick = %f us\n", countToUs);
    
        // enable compare 1
        NRF_TIMER1->INTENSET =
            (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    
        // use the shorts register to clear compare 1
        NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled <<
                              TIMER_SHORTS_COMPARE1_CLEAR_Pos);
    
        // enable IRQ
        NVIC_EnableIRQ(TIMER1_IRQn);
    
        Serial.println("Entered 2");
    
        // start timer
        NRF_TIMER1->TASKS_START = 1;
    
    }
    
    // Timer 1 IRQ handler
    // just increment count
    void TIMER1_IRQHandler(void)
    {
        Serial.println("Entered 3");
    
        if (NRF_TIMER1->EVENTS_COMPARE[1] &&
                NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE1_Msk) {
    
            // clear compare register event
            NRF_TIMER1->EVENTS_COMPARE[1] = 0;
    
            // increment count
            tCount++;
        }
    }
    
    void setup()
    {
        // put your setup code here, to run once:
        Serial.begin(9600);
    
        delay(2000);
    
        start_timer();
    }
    
    void loop()
    {
        // put your main code here, to run repeatedly:
        Serial.println("Entered 1");
    }
    

    Good Luck! :)

    New code:

    #include <nrf.h>
    
    // count to us (micro seconds) conversion factor
    // set in start_timer()
    static volatile float countToUs = 1;
    
    // counter
    static volatile uint32_t tCount = 0;
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void TIMER1_IRQHandler(void);
    #ifdef __cplusplus
    }
    #endif
    
    
    // Timer 1 IRQ handler
    // just increment count
    void TIMER1_IRQHandler(void)
    {
        if (NRF_TIMER1->EVENTS_COMPARE[1] &&
                NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE1_Msk) {
    
            // clear compare register event
            NRF_TIMER1->EVENTS_COMPARE[1] = 0;
    
            // increment count
            tCount++;
    
            if ((tCount % 300) == 0)
                Serial.println("Entered 3");
        }
    }
    
    
    // set up and start Timer1
    void start_timer(void)
    {
        NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
        NRF_TIMER1->TASKS_CLEAR = 1;
        // set prescalar n
        // f = 16 MHz / 2^(n)
        uint8_t prescaler = 0;
        NRF_TIMER1->PRESCALER = prescaler;
        NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    
        // 16 MHz clock generates timer tick every 1/(16000000) s = 62.5 nano s
        // With compare enabled, the interrupt is fired every: 62.5 * comp1 nano s
        // = 0.0625*comp1 micro seconds
        // multiply this by 2^(prescalar)
    
        uint16_t comp1 = 500;
        // set compare
        NRF_TIMER1->CC[1] = comp1;
    
        // set conversion factor
        countToUs = 0.0625 * comp1 * (1 << prescaler);
    
        //printf("timer tick = %f us\n", countToUs);
    
        // enable compare 1
        NRF_TIMER1->INTENSET =
            (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    
        // use the shorts register to clear compare 1
        NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled <<
                              TIMER_SHORTS_COMPARE1_CLEAR_Pos);
    
        // enable IRQ
        NVIC_EnableIRQ(TIMER1_IRQn);
    
        Serial.println("Entered 2");
    
        // start timer
        NRF_TIMER1->TASKS_START = 1;
    
    }
    
    void setup()
    {
        // put your setup code here, to run once:
        Serial.begin(9600);
    
        delay(2000);
    
        start_timer();
    }
    
    void loop()
    {
        // put your main code here, to run repeatedly:
        Serial.println("Entered 1");
        __WFE();
    }
    
Reply
  • Arduino source code is compiled as C++, but IRQ Handler is linked as C. So you have to declare void TIMER1_IRQHandler(void) with C linkage.

    #include <nrf.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void TIMER1_IRQHandler(void);
    #ifdef __cplusplus
    }
    #endif
    
    // count to us (micro seconds) conversion factor
    // set in start_timer()
    static volatile float countToUs = 1;
    
    // counter
    static volatile uint32_t tCount = 0;
    
    
    // set up and start Timer1
    void start_timer(void)
    {
        NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
        NRF_TIMER1->TASKS_CLEAR = 1;
        // set prescalar n
        // f = 16 MHz / 2^(n)
        uint8_t prescaler = 0;
        NRF_TIMER1->PRESCALER = prescaler;
        NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    
        // 16 MHz clock generates timer tick every 1/(16000000) s = 62.5 nano s
        // With compare enabled, the interrupt is fired every: 62.5 * comp1 nano s
        // = 0.0625*comp1 micro seconds
        // multiply this by 2^(prescalar)
    
        uint16_t comp1 = 500;
        // set compare
        NRF_TIMER1->CC[1] = comp1;
    
        // set conversion factor
        countToUs = 0.0625 * comp1 * (1 << prescaler);
    
        //printf("timer tick = %f us\n", countToUs);
    
        // enable compare 1
        NRF_TIMER1->INTENSET =
            (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    
        // use the shorts register to clear compare 1
        NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled <<
                              TIMER_SHORTS_COMPARE1_CLEAR_Pos);
    
        // enable IRQ
        NVIC_EnableIRQ(TIMER1_IRQn);
    
        Serial.println("Entered 2");
    
        // start timer
        NRF_TIMER1->TASKS_START = 1;
    
    }
    
    // Timer 1 IRQ handler
    // just increment count
    void TIMER1_IRQHandler(void)
    {
        Serial.println("Entered 3");
    
        if (NRF_TIMER1->EVENTS_COMPARE[1] &&
                NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE1_Msk) {
    
            // clear compare register event
            NRF_TIMER1->EVENTS_COMPARE[1] = 0;
    
            // increment count
            tCount++;
        }
    }
    
    void setup()
    {
        // put your setup code here, to run once:
        Serial.begin(9600);
    
        delay(2000);
    
        start_timer();
    }
    
    void loop()
    {
        // put your main code here, to run repeatedly:
        Serial.println("Entered 1");
    }
    

    Good Luck! :)

    New code:

    #include <nrf.h>
    
    // count to us (micro seconds) conversion factor
    // set in start_timer()
    static volatile float countToUs = 1;
    
    // counter
    static volatile uint32_t tCount = 0;
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void TIMER1_IRQHandler(void);
    #ifdef __cplusplus
    }
    #endif
    
    
    // Timer 1 IRQ handler
    // just increment count
    void TIMER1_IRQHandler(void)
    {
        if (NRF_TIMER1->EVENTS_COMPARE[1] &&
                NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE1_Msk) {
    
            // clear compare register event
            NRF_TIMER1->EVENTS_COMPARE[1] = 0;
    
            // increment count
            tCount++;
    
            if ((tCount % 300) == 0)
                Serial.println("Entered 3");
        }
    }
    
    
    // set up and start Timer1
    void start_timer(void)
    {
        NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
        NRF_TIMER1->TASKS_CLEAR = 1;
        // set prescalar n
        // f = 16 MHz / 2^(n)
        uint8_t prescaler = 0;
        NRF_TIMER1->PRESCALER = prescaler;
        NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    
        // 16 MHz clock generates timer tick every 1/(16000000) s = 62.5 nano s
        // With compare enabled, the interrupt is fired every: 62.5 * comp1 nano s
        // = 0.0625*comp1 micro seconds
        // multiply this by 2^(prescalar)
    
        uint16_t comp1 = 500;
        // set compare
        NRF_TIMER1->CC[1] = comp1;
    
        // set conversion factor
        countToUs = 0.0625 * comp1 * (1 << prescaler);
    
        //printf("timer tick = %f us\n", countToUs);
    
        // enable compare 1
        NRF_TIMER1->INTENSET =
            (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    
        // use the shorts register to clear compare 1
        NRF_TIMER1->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled <<
                              TIMER_SHORTS_COMPARE1_CLEAR_Pos);
    
        // enable IRQ
        NVIC_EnableIRQ(TIMER1_IRQn);
    
        Serial.println("Entered 2");
    
        // start timer
        NRF_TIMER1->TASKS_START = 1;
    
    }
    
    void setup()
    {
        // put your setup code here, to run once:
        Serial.begin(9600);
    
        delay(2000);
    
        start_timer();
    }
    
    void loop()
    {
        // put your main code here, to run repeatedly:
        Serial.println("Entered 1");
        __WFE();
    }
    
Children
Related