Using Timers on nRF52
By: Sanskar Biswal
Tags: Nrf52, Startup, Technology, Embedded Systems, Tutorial

Fig.1 nRF52 Development Kit

Prerequisites

This is tutorial is not intended to be a guide for learning C language or about the Nordic SDK platform. It’s primary target is to provide developers a concise guide about integrating peripheral modules and features into active applications.

If you are a beginner, I would recommend you look into an nRF52 Project Setup guide like this one.

Another easy way to get started with coding, without bothering with all basic stuff like files and driver inclusion, check out this Code Generation Tool

nrf52 Code Generator: https://vicara.co/nrf52-code-generator

Timer in a Microcontroller?

Fig.2 External Clock Source for Timer

A Timer can be said to be a specialized clock, which is used to measure intervals on a microcontroller. In a microcontroller, a timer can be used to tune the processing speed of an operation, set delays and also to synchronize user input and communication between a variety of peripheral devices.

As a result, timers form a very integral component of a microcontroller operations and having the skill to control the timer and its operations become an essential skill for any Embedded Systems developer.

Timer on nRF52

There are 5 instances of the timer on the nRF52832 module. Each module can be used independently.

Fig.3 Timer on nRF52

The timer/counter runs on the high-frequency clock source (HFCLK) and includes a four-bit (1/2X) prescaler that can divide the timer input clock from the HFCLK controller. Clock source selection between PCLK16M and PCLK1M is automatic according to TIMER base frequency set by the prescaler. The TIMER base frequency is always given as 16 MHz divided by the prescaler value.

Fig.4 Timer Instances

Programming Timer on nRF52832

Include Header

Fig.5 Include nrf_drv_timer

To use timer functions, nrf_drv_timer.h needs to be included into the project. It is available at SDK/integration/nrfx/legacy folder.

Update sdk_config.h

In this file, we need to enable TIMER_ENABLED flag and also the corresponding instance.

Fig.6 Enable Timer

Thus, if Timer-3 is to be used, we need to enable TIMER3_ENABLED 1

Fig.7 Enable Timer 1 Instance

Add Timer definition to Main File

Define Instance

static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(1);

Timer Callback Function

static void timer_handler(nrf_timer_event_t event_type, void* p_context)

{

switch(event_type)

{

case NRF_TIMER_EVENT_COMPARE0:

break;



case NRF_TIMER_EVENT_COMPARE1:

break;



case NRF_TIMER_EVENT_COMPARE2:

break;



case NRF_TIMER_EVENT_COMPARE3:

break;



case NRF_TIMER_EVENT_COMPARE4:

break;



case NRF_TIMER_EVENT_COMPARE5:

break;



default:

break;

}

}

This will be called every time a timer channel is triggered.

Initialize Timer Function

//@brief Function for Timer init function

static void timer_init()

{

//Can use the below values as default

nrf_drv_timer_config_t timer_cfg;

timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16; //user defined

timer_cfg.frequency = NRF_TIMER_FREQ_31250Hz; //user defined

timer_cfg.interrupt_priority = APP_IRQ_PRIORITY_LOW; //user defined

timer_cfg.mode = NRF_TIMER_MODE_TIMER;



ret_code_t err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);

APP_ERROR_CHECK(err_code);



//Timers 0,1 and 2 have 4 channels. Timers 3 and 4 have 6 channels.

//The below function needs to be called for each channel.

nrf_drv_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, nrf_drv_timer_ms_to_ticks(&m_timer ,1000), NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

}

Now all you need to do is call timer_init(); function from within the main function.

nrf_drv_timer_extended_compare needs to be called once for each timer channel used and it’s 4th parameter decides if the timer channel is a one shot or if it reloads. Interrupt priority options are 2, 3, 6, 7.

Conclusion

With the above steps anyone can easily get started with incorporating timers into their application code.

NOTE

There is another easier method to initialize and auto-generate code for nRF52. This tool, will handle all library additions and code generations for a variety of peripherals like SPI, I2C, UART etc.