一、概述
ESP32 的定时器分为 2 组,每组 2 个。ESP32 内置 4 个 64-bit 通用定时器。每个定时器包含一个 16-bit 预分频器和一个64-bit 可自动重新加载向上/向下计数器。详情可参考乐鑫文档
二、操作步骤
1、定时器初始化 - 启动定时器前应设置的参数,以及每个设置提供的具体功能。
2、定时器控制 - 如何读取定时器的值,如何暂停/启动定时器以及如何改变定时器的操作方式。
3、警报 - 如何设置和使用警报。
4、处理中断事务- 如何使用中断提供的回调函数。
知识点:
1、赫兹和秒的换算
HZ是频率的单位,是指每秒的周期次数(周期/秒);秒是时间的单位;f=1/T,T是周期。(其中f是指赫兹,T是指以秒为单位,10HZ即10次/秒)
1 HZ (1秒)1 kHz = 1 000 Hz(1MS) 1 MHz = 1 000 000Hz(1微秒)
2,分频器:分频就是把系统工作频率分频后当做定时器的工作频率;ESP32的输入时钟频率为80MHZ,就是1/80us=0.0125us计数器就会计数加一,如果设置分频系数为80,则1us就会计数加一,分频系数范围是0-65536
三、代码实现
下面用硬件定时器加中断实现一个1SLED的翻转,代码如下:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/timer.h"
#include "driver/gpio.h"
#define TIMER_DIVIDER (16)
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER)
#define GPIO_NUM_26 26
#define GPIO_OUTPUT_PIN_SEL (1ULL<<GPIO_NUM_26)
__uint8_t led_flag = 0;
void gpio_init(void)
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
void IRAM_ATTR timer_group1_isr(void *para){
uint32_t timer_intr = timer_group_get_intr_status_in_isr(TIMER_GROUP_1);
if (timer_intr & TIMER_INTR_T0) {
timer_group_clr_intr_status_in_isr(TIMER_GROUP_1, TIMER_0);
timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_0);
}
if(led_flag==0){
led_flag =1;
gpio_set_level(GPIO_NUM_26, 0);
}else{
led_flag=0;
gpio_set_level(GPIO_NUM_26, 1);
}
}
static void timer_init_test()
{
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = 1,
};
timer_init(TIMER_GROUP_1, TIMER_0, &config);
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0);
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, 1 * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_1, TIMER_0);
timer_isr_register(TIMER_GROUP_1,TIMER_0,
timer_group1_isr,
(void*)TIMER_0,
ESP_INTR_FLAG_IRAM,
NULL
);
timer_start(TIMER_GROUP_1, TIMER_0);
}
void app_main(void)
{
gpio_init();
timer_init_test();
while (1) {
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)