When I test the timer example with nrf52832 DK, it so nice to 4 minutes.
uint32_t time_ms = 240000;
But when I set the time interval over 5 minutes, then the event handler run more rapidly.
So, what should I do for long time period?
When I test the timer example with nrf52832 DK, it so nice to 4 minutes.
uint32_t time_ms = 240000;
But when I set the time interval over 5 minutes, then the event handler run more rapidly.
So, what should I do for long time period?
Hi JW,
By default, the timer runs at 16 MHz and the maximum bit width of the timer is 32-bit. This corresponds to a maximum timer value of:
(2^32)-1 = 4294967295
The reason why you see event handler more rapidly with 5 minutes, is that nrf_drv_timer_ms_to_ticks
use the configured frequency and the time_ms
parameter to generate the number of ticks, and return this in a 32 bit variable:
5*60*16000000 = 4800000000
This overflows the 32 bit variable, giving you a tick count of 505032705 = ~31.5 seconds.
You need to change the frequency of the timer to make it run run slower. This is done by changing the timer configuration:
timer_cfg.frequency = NRF_TIMER_FREQ_8MHz;
You can set it to any of the frequencies documented here.
Best regards,
Jørgen
Hi JW,
By default, the timer runs at 16 MHz and the maximum bit width of the timer is 32-bit. This corresponds to a maximum timer value of:
(2^32)-1 = 4294967295
The reason why you see event handler more rapidly with 5 minutes, is that nrf_drv_timer_ms_to_ticks
use the configured frequency and the time_ms
parameter to generate the number of ticks, and return this in a 32 bit variable:
5*60*16000000 = 4800000000
This overflows the 32 bit variable, giving you a tick count of 505032705 = ~31.5 seconds.
You need to change the frequency of the timer to make it run run slower. This is done by changing the timer configuration:
timer_cfg.frequency = NRF_TIMER_FREQ_8MHz;
You can set it to any of the frequencies documented here.
Best regards,
Jørgen
Hello Jørgen,
Thank you for answering my question. I can understand the timer configuration by your explanation.
But when I changed the frequency on 'nrf_drv_config.h'
from 16MHz
#define TIMER0_ENABLED 1
#if (TIMER0_ENABLED == 1)
#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit
#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER0_INSTANCE_INDEX 0
#endif
to 8MHz
#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_8MHz
and set the timer interval 1 second
uint32_t time_ms = 1000;
nothing changed.
The timer event handler run every 1 second at both configuration.
Your observations are correct, this change will not affect the time between event handler calls. What it will change is the output from nrf_drv_timer_ms_to_ticks()
, the variable time_ticks
. With time_ms = 1000
and frequency set to 16 MHz, the returned value will be 16 000 000. With time_ms = 1000
and frequency set to 8 MHz, it will return 8 000 000. Reducing the frequency will reduce the resolution of the timer, but it will increase the time the timer can run before overflowing.
Well, but when I set the time interval 5 minutes with time_ms = 300000
after change frequency to 8MHz, the event handler also run every 30 seconds.
I see there is a 32 bit multiplication inside the function, resulting in the return value being wrong. If you change line 618 in nrf_timer.h from return ((time_ms * 16000UL) >> prescaler);
to return ((time_ms * 16000ULL) >> prescaler);
, you should get correct behavior.
It works!! Thank you so much! But actually 'nrf_timer.h' is referred by every Keil projects. So..isn't there any problem with 16000ULL in other case? In my opinion, it might be okay because the difference between UL and ULL is just size.