TIMER¶
Introduction¶
The ESP32 chip contains two hardware timer groups. Each group has two general-purpose hardware timers. They are all 64-bit generic timers based on 16-bit prescalers and 64-bit auto-reload-capable up / down counters.
Functional Overview¶
Typical steps to configure an operate the timer are described in the following sections:
- Timer Initialization - what parameters should be set up to get the timer working and what specific functionality is provided depending on the set up.
- Timer Control - how to read the timer’s value, pause / start the timer, and change how it operates.
- Alarms - setting and using alarms.
- Interrupts- how to enable and use interrupts.
Timer Initialization¶
The two timer groups on-board of the ESP32 are identified using timer_group_t
. Individual timers in a group are identified with timer_idx_t
. The two groups, each having two timers, provide the total of four individual timers to our disposal.
Before starting the timer, it should be initialized by calling timer_init()
. This function should be provided with a structure timer_config_t
to define how timer should operate. In particular the following timer’s parameters may be set:
- Divider: How quickly the timer’s counter is “ticking”. This depends on the setting of
divider
, that will be used as divisor of the incoming 80 MHz APB_CLK clock.- Mode: If the the counter is incrementing or decrementing, defined using
counter_dir
by selecting one of values fromtimer_count_dir_t
.- Counter Enable: If the counter is enabled, then it will start incrementing / decrementing immediately after calling
timer_init()
. This action is set usingcounter_en
by selecting one of vales fromtimer_start_t
.- Alarm Enable: Determined by the setting of
alarm_en
.- Auto Reload: Whether the counter should
auto_reload
a specific initial value on the timer’s alarm, or continue incrementing or decrementing.- Interrupt Type: Whether an interrupt is triggered on timer’s alarm. Set the value defined in
timer_intr_mode_t
.
To get the current values of the timers settings, use function timer_get_config()
.
Timer Control¶
Once the timer is configured and enabled, it is already “ticking”. To check it’s current value call timer_get_counter_value()
or timer_get_counter_time_sec()
. To set the timer to specific starting value call timer_set_counter_value()
.
The timer may be paused at any time by calling timer_pause()
. To start it again call timer_start()
.
To change how the timer operates you can call once more timer_init()
described in section Timer Initialization. Another option is to use dedicated functions to change individual settings:
- Divider value -
timer_set_divider()
. Note: the timer should be paused when changing the divider to avoid unpredictable results. If the timer is already running,timer_set_divider()
will first pause the timer, change the divider, and finally start the timer again.- Mode (whether the counter incrementing or decrementing) -
timer_set_counter_mode()
- Auto Reload counter on alarm -
timer_set_auto_reload()
Alarms¶
To set an alarm, call function timer_set_alarm_value()
and then enable it with timer_set_alarm()
. The alarm may be also enabled during the timer initialization stage, when timer_init()
is called.
After the alarm is enabled and the timer reaches the alarm value, depending on configuration, the following two actions may happen:
- An interrupt will be triggered, if previously configured. See section Interrupts how to configure interrupts.
- When
auto_reload
is enabled, the timer’s counter will be reloaded to start counting from specific initial value. The value to start should be set in advance withtimer_set_counter_value()
.
注解
- The alarm will be triggered immediately, if an alarm value is set and the timer has already passed this value.
- Once triggered the alarm will be disabled automatically and needs to be re-armed to trigger again.
To check what alarm value has been set up, call timer_get_alarm_value()
.
Interrupts¶
Registration of the interrupt handler for a specific timer group and timer is done be calling timer_isr_register()
.
To enable interrupts for a timer group call timer_group_intr_enable()
. To do it for a specific timer, call timer_enable_intr()
. Disabling of interrupts is done with corresponding functions timer_group_intr_disable()
and timer_disable_intr()
.
When servicing an interrupt within an ISR, the interrupt need to explicitly cleared. To do so, set the TIMERGN.int_clr_timers.tM
structure defined in soc/esp32/include/soc/timer_group_struct.h, where N is the timer group number [0, 1] and M is the timer number [0, 1]. For example to clear an interrupt for the timer 1 in the timer group 0, call the following:
TIMERG0.int_clr_timers.t1 = 1
See the application example below how to use interrupts.
Application Example¶
The 64-bit hardware timer example: peripherals/timer_group.
API Reference¶
Header File¶
Functions¶
-
esp_err_t
timer_get_counter_value
(timer_group_t group_num, timer_idx_t timer_num, uint64_t *timer_val)¶ Read the counter value of hardware timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]timer_val
: Pointer to accept timer counter value.
-
esp_err_t
timer_get_counter_time_sec
(timer_group_t group_num, timer_idx_t timer_num, double *time)¶ Read the counter value of hardware timer, in unit of a given scale.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]time
: Pointer, type of double*, to accept timer counter value, in seconds.
-
esp_err_t
timer_set_counter_value
(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val)¶ Set counter value to hardware timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]load_val
: Counter value to write to the hardware timer.
-
esp_err_t
timer_start
(timer_group_t group_num, timer_idx_t timer_num)¶ Start the counter of hardware timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
-
esp_err_t
timer_pause
(timer_group_t group_num, timer_idx_t timer_num)¶ Pause the counter of hardware timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
-
esp_err_t
timer_set_counter_mode
(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir)¶ Set counting mode for hardware timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]counter_dir
: Counting direction of timer, count-up or count-down
-
esp_err_t
timer_set_auto_reload
(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload)¶ Enable or disable counter reload function when alarm event occurs.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]reload
: Counter reload mode.
-
esp_err_t
timer_set_divider
(timer_group_t group_num, timer_idx_t timer_num, uint32_t divider)¶ Set hardware timer source clock divider. Timer groups clock are divider from APB clock.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]divider
: Timer clock divider value. The divider’s range is from from 2 to 65536.
-
esp_err_t
timer_set_alarm_value
(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value)¶ Set timer alarm value.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]alarm_value
: A 64-bit value to set the alarm value.
-
esp_err_t
timer_get_alarm_value
(timer_group_t group_num, timer_idx_t timer_num, uint64_t *alarm_value)¶ Get timer alarm value.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]alarm_value
: Pointer of A 64-bit value to accept the alarm value.
-
esp_err_t
timer_set_alarm
(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en)¶ Enable or disable generation of timer alarm events.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]alarm_en
: To enable or disable timer alarm function.
-
esp_err_t
timer_isr_register
(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void *), void *arg, int intr_alloc_flags, timer_isr_handle_t *handle, )¶ Register Timer interrupt handler, the handler is an ISR. The handler will be attached to the same CPU core that this function is running on.
- Note
- If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, the handler function must be declared with IRAM_ATTR attribute and can only call functions in IRAM or ROM. It cannot call other timer APIs. Use direct register access to configure timers from inside the ISR in this case.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group numbertimer_num
: Timer index of timer groupfn
: Interrupt handler function.arg
: Parameter for handler functionintr_alloc_flags
: Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.handle
: Pointer to return handle. If non-NULL, a handle for the interrupt will be returned here.
-
esp_err_t
timer_init
(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config)¶ Initializes and configure the timer.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]config
: Pointer to timer initialization parameters.
-
esp_err_t
timer_get_config
(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config)¶ Get timer configure value.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]config
: Pointer of struct to accept timer parameters.
-
esp_err_t
timer_group_intr_enable
(timer_group_t group_num, uint32_t en_mask)¶ Enable timer group interrupt, by enable mask.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1en_mask
: Timer interrupt enable mask. Use TIMG_T0_INT_ENA_M to enable t0 interrupt Use TIMG_T1_INT_ENA_M to enable t1 interrupt
-
esp_err_t
timer_group_intr_disable
(timer_group_t group_num, uint32_t disable_mask)¶ Disable timer group interrupt, by disable mask.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1disable_mask
: Timer interrupt disable mask. Use TIMG_T0_INT_ENA_M to disable t0 interrupt Use TIMG_T1_INT_ENA_M to disable t1 interrupt
-
esp_err_t
timer_enable_intr
(timer_group_t group_num, timer_idx_t timer_num)¶ Enable timer interrupt.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
-
esp_err_t
timer_disable_intr
(timer_group_t group_num, timer_idx_t timer_num)¶ Disable timer interrupt.
- Return
- ESP_OK Success
- ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
Structures¶
-
struct
timer_config_t
¶ Data structure with timer’s configuration settings.
Public Members
-
bool
alarm_en
¶ Timer alarm enable
-
bool
counter_en
¶ Counter enable
-
timer_intr_mode_t
intr_type
¶ Interrupt mode
-
timer_count_dir_t
counter_dir
¶ Counter direction
-
bool
auto_reload
¶ Timer auto-reload
-
uint32_t
divider
¶ Counter clock divider. The divider’s range is from from 2 to 65536.
-
bool
Type Definitions¶
-
typedef intr_handle_t
timer_isr_handle_t
¶ Interrupt handle, used in order to free the isr after use. Aliases to an int handle for now.
Enumerations¶
-
enum
timer_group_t
¶ Selects a Timer-Group out of 2 available groups.
Values:
-
TIMER_GROUP_0
= 0¶ Hw timer group 0
-
TIMER_GROUP_1
= 1¶ Hw timer group 1
-
TIMER_GROUP_MAX
¶
-
-
enum
timer_idx_t
¶ Select a hardware timer from timer groups.
Values:
-
TIMER_0
= 0¶ Select timer0 of GROUPx
-
TIMER_1
= 1¶ Select timer1 of GROUPx
-
TIMER_MAX
¶
-
-
enum
timer_count_dir_t
¶ Decides the direction of counter.
Values:
-
TIMER_COUNT_DOWN
= 0¶ Descending Count from cnt.high|cnt.low
-
TIMER_COUNT_UP
= 1¶ Ascending Count from Zero
-
TIMER_COUNT_MAX
¶
-
-
enum
timer_start_t
¶ Decides whether timer is on or paused.
Values:
-
TIMER_PAUSE
= 0¶ Pause timer counter
-
TIMER_START
= 1¶ Start timer counter
-
-
enum
timer_alarm_t
¶ Decides whether to enable alarm mode.
Values:
-
TIMER_ALARM_DIS
= 0¶ Disable timer alarm
-
TIMER_ALARM_EN
= 1¶ Enable timer alarm
-
TIMER_ALARM_MAX
¶
-
-
enum
timer_intr_mode_t
¶ Select interrupt type if running in alarm mode.
Values:
-
TIMER_INTR_LEVEL
= 0¶ Interrupt mode: level mode
-
TIMER_INTR_MAX
¶
-
-
enum
timer_autoreload_t
¶ Select if Alarm needs to be loaded by software or automatically reload by hardware.
Values:
-
TIMER_AUTORELOAD_DIS
= 0¶ Disable auto-reload: hardware will not load counter value after an alarm event
-
TIMER_AUTORELOAD_EN
= 1¶ Enable auto-reload: hardware will load counter value after an alarm event
-
TIMER_AUTORELOAD_MAX
¶
-