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

nrf51822 TIMER 1 and TIMER 2

In timer example in sdk 11, I replace the Timer 0 by timer 1 and timer 2 but the LED did not blink. Can you guys please guide me through this? In nrf_drv_config.h I have already replace:

#define TIMER1_ENABLED 0 
#define TIMER2_ENABLED 0

by

    #define TIMER1_ENABLED 1
 #define TIMER1_ENABLED 1

Anh can you please show me how to use 2 timers in one time? For example, TIMER0 incharge of LED1 and TIMER1 incharged of LED2. And they blink at different period of time, say: 500 ms and 700 ms?. I have tried this following code but the LED just turn on but not blink. Thank you for your support.

Here is my code:

#include "nrf.h"
#include "bsp.h"

#include "nrf_drv_timer.h"
#include "bsp.h"
#include "app_error.h"

#define LED1															11
#define LED2															12

const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(1);
const nrf_drv_timer_t TIMER_LED_1 = NRF_DRV_TIMER_INSTANCE(2);

void led_init(){
	nrf_gpio_cfg_output(LED1);
	nrf_gpio_cfg_output(LED2);
}


/**
 * @brief Handler for timer events.
 */
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    
    switch(event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            LEDS_INVERT(1UL<<LED2);
            break;
        
        default:
            //Do nothing.
            break;
    }    
}

/**
 * @brief Handler for timer events.
 */
void timer_led_event_handler_1(nrf_timer_event_t event_type, void* p_context)
{
    
    switch(event_type)
    {
        case NRF_TIMER_EVENT_COMPARE1:
            LEDS_INVERT(1UL<<LED1);
            break;
        
        default:
            //Do nothing.
            break;
    }    
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
		uint32_t time_ms_1 = 700;
	uint32_t time_ticks, time_ticks_1;
    uint32_t err_code = NRF_SUCCESS;
    led_init();
    //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
    err_code = nrf_drv_timer_init(&TIMER_LED, NULL, timer_led_event_handler);
    APP_ERROR_CHECK(err_code);
    
		err_code = nrf_drv_timer_init(&TIMER_LED_1, NULL, timer_led_event_handler_1);
    APP_ERROR_CHECK(err_code);
	
    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);
		time_ticks_1 = nrf_drv_timer_ms_to_ticks(&TIMER_LED_1, time_ms_1);
	
    nrf_drv_timer_extended_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
	
	nrf_drv_timer_extended_compare(
         &TIMER_LED_1, NRF_TIMER_CC_CHANNEL1, time_ticks_1, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);
    
    nrf_drv_timer_enable(&TIMER_LED);
		nrf_drv_timer_enable(&TIMER_LED_1);
    while(1)
    {
        __WFI();
    }
}

/** @} */
  • I can't guide you on the timer driver since I normally avoid the drivers in firmware apps unless absolutely required, but here is a link to some code I did recently that did two HF_CLK timers on gpiote for nRF52. Logic is the same for RTC timers except the prefix for the registers is NRF_RTC1, 2, etc. As the user pointed out nRF51 didn't have the TEP Fork which I had used. But they got it working anyway.

    The example writes gpio via gpiote, but you can easily use the events to drive ISR handlers instead: devzone.nordicsemi.com/.../

  • Here is some other code that that turns on the LED for 50msec. It uses the RTC and a ISR handler. The timer is one shot. LED_MASK is just whatever bit pattern you need to write to turn on your leds. You just call flash led to make it work. The RTC timers don't have the shorts that let you turn the HF_CLK timers into an astable device. But you can easily use the other CC registers for your entire on/off cycle. So timer clear turns on led, cc0 turns off led, cc1 reset timer and process repeats.

    void RTC1_IRQHandler (void)
    {
    	
    	NRF_RTC1->TASKS_CLEAR = 1;
    	NRF_RTC1->TASKS_STOP =1;
        NRF_RTC1->EVENTS_COMPARE[0] = 0;
    	NRF_GPIO->OUTSET = (LED_MASK);
    			                     
    
    	
    }
    void flash_led  (void)
    {
    	NRF_GPIO->OUTCLR = (LED_MASK);
    	NRF_RTC1->TASKS_STOP        = 1;                      // Stop timer, if it was running
        NRF_RTC1->TASKS_CLEAR       = 1;
    	NRF_RTC1->PRESCALER = 31;
    	NRF_RTC1->CC[0] = 50;
    		
    		
    	NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk;
    	NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
    				
    	NVIC_ClearPendingIRQ(RTC1_IRQn);
    	NVIC_EnableIRQ(RTC1_IRQn);
    	NRF_RTC1->TASKS_START = 1;	
    	
    }
    
  • Actually I had a project which use SD, and SD use 1 RTC and 1 Timer already. Therefore, I have only 1 RTC and 2 timers left. I have already use 1 RTC for another function and I want to use Timer 1 and Timer 2 for other tasks. They just count the time and run into interrupts, where I put my function into. Therefore, I want to ask if I can use 3 timers (1 RTC and 2 Timers) in parallel in SD and how to make it works? Thank you for your kind support.

  • In your comment I think you made a typo, the SD's use Timer0 and RTC0. 1 and above are available for both types of timers.

    You can easily use one timer for multiple things it just involves more code and ISR's. A good example of this is the app_timer. And if you are creating a lot of timers, app_timer is a good resource. Though since it makes use of a lot of ISR's to accomplish what it does, latency can be long and jittery. So, don't expect millisecond accuracy, maybe 10 msec accuracy instead.

    You can find it used in most examples. The beacon example uses it for led's. Here is the documentation: infocenter.nordicsemi.com/index.jsp

Related