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
It should not affect other projects, as this only changes the multiplication result from 32 to 64 bits. The ASSERT in the nrf_timer_ms_to_ticks()
should have fired when you called the function with time_ms = 300000, but this does not seems to have happened. I'm not sure why, but I have reported this issue internally.
If you want to keep the ASSERT and make sure all inputs are valid, you can use this function:
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
uint64_t ticks = ((time_ms * 16000ULL) >> prescaler);
ASSERT(ticks <= UINT32_MAX);
return (uint32_t)ticks;
}
You can configure the timer frequency all the way down to 31250 Hz, which should give you a maximum of ~2290.6 minutes. If you want to run timers longer, you can use the RTC. The RTC can be configured to run for up to ~582.5 hours before overflowing. RTC is also lower power than the TIMER.
It should not affect other projects, as this only changes the multiplication result from 32 to 64 bits. The ASSERT in the nrf_timer_ms_to_ticks()
should have fired when you called the function with time_ms = 300000, but this does not seems to have happened. I'm not sure why, but I have reported this issue internally.
If you want to keep the ASSERT and make sure all inputs are valid, you can use this function:
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
uint64_t ticks = ((time_ms * 16000ULL) >> prescaler);
ASSERT(ticks <= UINT32_MAX);
return (uint32_t)ticks;
}
You can configure the timer frequency all the way down to 31250 Hz, which should give you a maximum of ~2290.6 minutes. If you want to run timers longer, you can use the RTC. The RTC can be configured to run for up to ~582.5 hours before overflowing. RTC is also lower power than the TIMER.