This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Setting TIMER2 interval

How do I set TIMER2 to interrupt every 1 ms?

Sounds like a very basic question, but I haven't succeed. For TIMER1 I can get it working, but for TIMER2 the highest frequecy I have achieved is about 100 Hz.

The code is as follows:

void init_timer2(void)
{
	// Start 32 MHz crystal oscillator
	NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
	NRF_CLOCK->TASKS_HFCLKSTART = 1;
	// Wait for the external oscillator to start up
	while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
		// Do nothing.
	}
	NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
	NRF_TIMER2->PRESCALER = 4; // what should be here?
	NVIC_EnableIRQ(TIMER2_IRQn);
        NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
        NRF_TIMER2->CC[0] = ???;
        NRF_TIMER2->CC[1] = ???;
        NRF_TIMER2->CC[2] = ???;
        NRF_TIMER2->CC[3] = ???; 
	NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE2_Enabled
	<< TIMER_INTENSET_COMPARE2_Pos;
	sd_softdevice_forward_to_application();
	NRF_TIMER2->TASKS_START = 1;
}

I don't know what should be put into the place of '???'s above. I guess there is a good documentation somewhere, so I would be happy to get a pointer there, too. Indeed, a working code would be best.

Edit: Format (please use preformatted text button when inserting code)

Parents
  • Hi,

    The prescaler sets the base timer tick like this (given in us): TimerTick = 16M / 2^prescaler.

    For instance, if we set 4: TimerTick = 16M/2^4 = 1 us.

    In order to generate an interrupt each 1ms:

    
    #define TIMER2_CC_DELAY 1000
    ...
    NRF_TIMER2->PRESCALER = 4;
    NRF_TIMER2->CC[0] = TIMER2_CC_DELAY; // Fbase = 16M/2^4 * 1000 = 1 ms.
    /*Reset of init*/
    
    

    In your handler:

    
    void TIMER2_IRQHandler(void)
    {    
        if(NRF_TIMER2->EVENTS_COMPARE[0])
        {
            nrf_gpio_pin_toggle(18);
            NRF_TIMER2->EVENTS_COMPARE[0] = 0;
            // Need to update the CC[0]
            NRF_TIMER2->CC[0] += TIMER2_CC_DELAY;
        }
    }
    

    For a more precise measurement you can add a static variable inside the interrupt handler to count instead of reading the CC[]-register.

    Best regards Håkon

  • The reason this must be there is because the timer is not cleared between each interrupt. When you've finished your first interrupt, the timer will keep on incrementing until it overflows. You then have two options:

    1. Keep updating the CC-register
    2. Clear the timer between each interrupt. This can be done manually, or via SHORTS register.

    Best regards Håkon

Reply
  • The reason this must be there is because the timer is not cleared between each interrupt. When you've finished your first interrupt, the timer will keep on incrementing until it overflows. You then have two options:

    1. Keep updating the CC-register
    2. Clear the timer between each interrupt. This can be done manually, or via SHORTS register.

    Best regards Håkon

Children
No Data
Related