通用定时器¶
简介¶
ESP32 芯片提供两组硬件定时器,每组包含两个通用硬件定时器。所有定时器均为 64 位通用定时器,包括 16 位预分频器和 64 位自动重载向上/向下计数器。
功能概述¶
下文介绍了配置和操作定时器的常规步骤:
定时器初始化 - 启动定时器前应设置的参数,以及每个设置提供的具体功能。
定时器控制 - 如何读取定时器的值,如何暂停/启动定时器以及如何改变定时器的操作方式。
警报 - 如何设置和使用警报。
处理中断事务- 如何使用中断提供的回调函数。
定时器初始化¶
两个 ESP32 定时器组中,每组都有两个定时器,两组共有四个定时器供使用。ESP32 定时器组的类型为 timer_group_t
,每组中的个体定时器类型为 timer_idx_t
。
首先调用 timer_init()
函数,并将 timer_config_t
结构体传递给此函数,用于定义定时器的工作方式,实现定时器初始化。特别注意以下定时器参数可设置为:
时钟源: 选择时钟源,它同时钟分频器一起决定了定时器的分辨率。默认的时钟源是 APB_CLK (一般是 80 MHz)。
分频器: 设置定时器中计数器计数的速度,
divider
的设置将用作输入时钟源的除数。模式: 设置计数器是递增还是递减。可通过从
timer_count_dir_t
中选取一个值,后使用counter_dir
来选择模式。计数器使能: 如果计数器已使能,则在调用
timer_init()
后计数器将立即开始递增/递减。您可通过从timer_start_t
中选取一个值,后使用counter_en
改变此行为。报警使能: 可使用
alarm_en
设置。自动重载: 设置计数器是否应该在定时器警报上使用
auto_reload
自动重载首个计数值,还是继续递增或递减。
要获取定时器设置的当前值,请使用函数 timer_get_config()
。
定时器控制¶
定时器使能后便开始计数。要使能定时器,可首先设置 counter_en
为 true
,然后调用函数 timer_init()
,或者直接调用函数 timer_start()
。您可通过调用函数 timer_set_counter_value()
来指定定时器的首个计数值。要检查定时器的当前值,调用函数 timer_get_counter_value()
或 timer_get_counter_time_sec()
。
可通过调用函数 timer_pause()
随时暂停定时器。要再次启动它,调用函数 timer_start()
。
要重新配置定时器,可调用函数 timer_init()
,该函数详细介绍见 定时器初始化。
除此之外,还可通过使用专有函数更改个别设置来重新配置定时器:
设置 |
专有函数 |
描述 |
---|---|---|
分频器 |
更改计数频率。为避免发生不可预测情况,更改分频器时应暂停定时器。如果定时器正在运行,则使用 |
|
模式 |
设置计数器应递增还是递减 |
|
自动重载 |
设置是否应在定时器警报上重载首个计数值 |
警报¶
要设置警报,先调用函数 timer_set_alarm_value()
,然后使用 timer_set_alarm()
使能警报。当调用函数 timer_init()
时,也可以在定时器初始化阶段使能警报。
警报已使能且定时器达到警报值后,根据配置,可能会出现以下两种行为:
如果先前已配置,此时将触发中断。有关如何配置中断,请参见 处理中断事务。
如
auto_reload
已使能,定时器的计数器将重新加载,从先前配置好的值开始再次计数。应使用函数timer_set_counter_value()
预先设置该值。
注解
如果已设置警报值且定时器已超过该值,则将立即触发警报。
一旦触发后,警报将自动关闭,需要重新使能以再次触发。
要检查某特定的警报值,调用函数 timer_get_alarm_value()
。
处理中断事务¶
调用 timer_isr_callback_add()
函数可以给某个定时器注册一个中断回调函数,顾名思义,该函数会在中断上下文中被执行,因此用户不能在回调函数中调用任何会阻塞 CPU 的 API。
相较于从头编写中断处理程序,使用中断回调函数的好处是,用户无需检测和处理中断的状态位,这些操作会由驱动中默认的中断处理程序替我们完成。
有关如何使用中断回调函数,请参考如下应用示例。
应用示例¶
64 位通用硬件定时器示例:peripherals/timer_group。
API 参考¶
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_callback_add
(timer_group_t group_num, timer_idx_t timer_num, timer_isr_t isr_handler, void *arg, int intr_alloc_flags)¶ Add ISR handle callback for the corresponding timer.
The callback should return a bool value to determine whether need to do YIELD at the end of the ISR.
- Note
This ISR handler will be called from an ISR. This ISR handler do not need to handle interrupt status, and should be kept short. If you want to realize some specific applications or write the whole ISR, you can call timer_isr_register(…) to register ISR.
- Parameters
group_num
: Timer group numbertimer_num
: Timer index of timer groupisr_handler
: Interrupt handler function, it is a callback 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.
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.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t
timer_isr_callback_remove
(timer_group_t group_num, timer_idx_t timer_num)¶ Remove ISR handle callback for the corresponding timer.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group numbertimer_num
: Timer index of timer group
-
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.
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.
- Note
If use this function to reigster ISR, you need to write the whole ISR. In the interrupt handler, you need to call timer_spinlock_take(..) before your handling, and call timer_spinlock_give(…) after your handling.
- 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.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
-
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_deinit
(timer_group_t group_num, timer_idx_t timer_num)¶ Deinitializes 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]
-
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, timer_intr_t intr_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 TIMERG1intr_mask
: Timer interrupt enable mask.TIMER_INTR_T0: t0 interrupt
TIMER_INTR_T1: t1 interrupt
TIMER_INTR_WDT: watchdog interrupt
-
esp_err_t
timer_group_intr_disable
(timer_group_t group_num, timer_intr_t intr_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 TIMERG1intr_mask
: Timer interrupt disable mask.TIMER_INTR_T0: t0 interrupt
TIMER_INTR_T1: t1 interrupt
TIMER_INTR_WDT: watchdog 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.
-
void
timer_group_intr_clr_in_isr
(timer_group_t group_num, timer_idx_t timer_num)¶ Clear timer interrupt status, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
-
void
timer_group_clr_intr_status_in_isr
(timer_group_t group_num, timer_idx_t timer_num)¶ Clear timer interrupt status, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
-
void
timer_group_enable_alarm_in_isr
(timer_group_t group_num, timer_idx_t timer_num)¶ Enable alarm interrupt, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
-
uint64_t
timer_group_get_counter_value_in_isr
(timer_group_t group_num, timer_idx_t timer_num)¶ Get the current counter value, just used in ISR.
- Return
Counter value
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.
-
void
timer_group_set_alarm_value_in_isr
(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val)¶ Set the alarm threshold for the timer, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.alarm_val
: Alarm threshold.
-
void
timer_group_set_counter_enable_in_isr
(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en)¶ Enable/disable a counter, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index.counter_en
: Enable/disable.
-
timer_intr_t
timer_group_intr_get_in_isr
(timer_group_t group_num)¶ Get the masked interrupt status, just used in ISR.
- Return
Interrupt status
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1
-
uint32_t
timer_group_get_intr_status_in_isr
(timer_group_t group_num)¶ Get interrupt status, just used in ISR.
- Return
Interrupt status
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1
-
void
timer_group_clr_intr_sta_in_isr
(timer_group_t group_num, timer_intr_t intr_mask)¶ Clear the masked interrupt status, just used in ISR.
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1intr_mask
: Masked interrupt.
-
bool
timer_group_get_auto_reload_in_isr
(timer_group_t group_num, timer_idx_t timer_num)¶ Get auto reload enable status, just used in ISR.
- Return
True Auto reload enabled
False Auto reload disabled
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1timer_num
: Timer index
-
esp_err_t
timer_spinlock_take
(timer_group_t group_num)¶ Take timer spinlock to enter critical protect.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1
-
esp_err_t
timer_spinlock_give
(timer_group_t group_num)¶ Give timer spinlock to exit critical protect.
- Return
ESP_OK Success
ESP_ERR_INVALID_ARG Parameter error
- Parameters
group_num
: Timer group number, 0 for TIMERG0 or 1 for TIMERG1
Type Definitions¶
-
typedef bool (*
timer_isr_t
)(void *)¶ Interrupt handle callback function. User need to retrun a bool value in callback.
- Return
True Do task yield at the end of ISR
False Not do task yield at the end of ISR
- Note
If you called FreeRTOS functions in callback, you need to return true or false based on the retrun value of argument
pxHigherPriorityTaskWoken
. For example,xQueueSendFromISR
is called in callback, if the return valuepxHigherPriorityTaskWoken
of any FreeRTOS calls is pdTRUE, return true; otherwise return false.
-
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.
Header File¶
Structures¶
-
struct
timer_config_t
¶ Data structure with timer’s configuration settings.
Public Members
-
timer_alarm_t
alarm_en
¶ Timer alarm enable
-
timer_start_t
counter_en
¶ Counter enable
-
timer_intr_mode_t
intr_type
¶ Interrupt mode
-
timer_count_dir_t
counter_dir
¶ Counter direction
-
timer_autoreload_t
auto_reload
¶ Timer auto-reload
-
uint32_t
divider
¶ Counter clock divider. The divider’s range is from from 2 to 65536.
-
timer_alarm_t
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_intr_t
¶ Interrupt types of the timer.
Values:
-
TIMER_INTR_T0
= BIT(0)¶ interrupt of timer 0
-
TIMER_INTR_T1
= BIT(1)¶ interrupt of timer 1
-
TIMER_INTR_WDT
= BIT(2)¶ interrupt of watchdog
-
TIMER_INTR_NONE
= 0¶
-
-
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
¶
-