ESP32-IDF02-3 外设-定时器
Posted Ciaran-byte
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32-IDF02-3 外设-定时器相关的知识,希望对你有一定的参考价值。
定时器
文章目录
1. 通用定时器
1.1 概述
esp32的定时器有两组四个(每组两个),每个定时器都具有一个16bit的预分频器和一个32bit的向上/向下计数器
1.1.1 时钟
时钟来源是APB时钟,默认是80MHZ
1.1.2 预分频器
范围是0-65535,定义为0的时候是65536分频,定义为1和2的时候都是2分频
1.1.3 计数器
向上或者向下计数均可
1.2 配置步骤
- 定时器初始化结构体
- 定时器控制参数
- 使能中断
- 中断服务函数
- 开启/暂停计数
1.2.1 定时器初始化
主要是配置定时器配置结构体
//01 定义定时器配置结构体
timer_config_t config;
config.divider = Timer_Divider; //这里配置的是1tick=0.5ms
config.counter_en = TIMER_PAUSE; //先不使能定时器
config.counter_dir = TIMER_COUNT_UP; //向上计数
config.auto_reload = TIMER_AUTORELOAD_EN; //自动重新装载
config.alarm_en = TIMER_ALARM_EN; //开启警报,到了阈值之后会触发中断
1.2.2 定时器控制参数
//02 控制定时器
timer_init(BSP_TIMER_GROUP, BSP_TIMER, &config); //配置第0组第0个定时器
timer_set_counter_value(BSP_TIMER_GROUP, BSP_TIMER, Counter_Value); //计数器初值设置为0
timer_set_alarm_value(BSP_TIMER_GROUP, BSP_TIMER, Alarm_value); // 设定警报值,到了这个数以后就会触发中断
1.2.3 使能中断
//03 使能定时器中断
timer_enable_intr(BSP_TIMER_GROUP, BSP_TIMER); //使能定时器中断
timer_isr_callback_add(BSP_TIMER_GROUP, BSP_TIMER, timer_group_isr_callback, 0, 1);//注册中断服务函数
1.2.4 中断服务函数
定时器到达警报值的时候,就会触发定时器中断,然后就会调用中断服务函数,这里不需要清楚中断标志位,系统都自己做好了
static bool IRAM_ATTR timer_group_isr_callback(void* args) //timer_isr
{
//中断服务函数,请在这里完成定时器中断要做的事情
led_toggle();
return true;
}
1.2.5 开启/暂停计数
void bsp_timer_start() //定时器开始
{
timer_start(BSP_TIMER_GROUP, BSP_TIMER);
}
void bsp_timer_pause() //定时器停止
{
timer_pause(BSP_TIMER_GROUP, BSP_TIMER);
}
1.3 案例–通用定时器控制led开闭
- bsp_timer.h
#ifndef _BSP_TIMER_H_
#define _BSP_TIMER_H_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include"driver/timer.h"
//定义定时器组
#define BSP_TIMER_GROUP TIMER_GROUP_0
#define BSP_TIMER TIMER_0
//定义参数
#define Timer_Divider 40000 //配置时钟,因为时钟是80M,40000以后,增加一个数字0.5ms
#define Counter_Value 0 //定时器初值
#define Alarm_value 1000 //警报阈值,这里10000*0.5ms = 5s
//函数声明
void bsp_timer_init();//初始化定时器
void bsp_timer_start(); //打开定时器
void bsp_timer_pause(); //关闭定时器
#endif
- bsp_timer.cpp
#include "bsp_timer.h"
#include "bsp_led.h"
static bool IRAM_ATTR timer_group_isr_callback(void* args) //timer_isr
{
//中断服务函数,请在这里完成定时器中断要做的事情
led_toggle();
return true;
}
void bsp_timer_init() //定时器配置
{
//01 定义定时器配置结构体
timer_config_t config;
config.divider = Timer_Divider; //这里配置的是1tick=0.5ms
config.counter_en = TIMER_PAUSE; //先不使能定时器
config.counter_dir = TIMER_COUNT_UP; //向上计数
config.auto_reload = TIMER_AUTORELOAD_EN; //自动重新装载
config.alarm_en = TIMER_ALARM_EN; //开启警报,到了阈值之后会触发中断
//02 控制定时器
timer_init(BSP_TIMER_GROUP, BSP_TIMER, &config); //配置第0组第0个定时器
timer_set_counter_value(BSP_TIMER_GROUP, BSP_TIMER, Counter_Value); //计数器初值设置为0
timer_set_alarm_value(BSP_TIMER_GROUP, BSP_TIMER, Alarm_value); //设置警报值
//03 使能定时器中断
timer_enable_intr(BSP_TIMER_GROUP, BSP_TIMER); //使能定时器中断
timer_isr_callback_add(BSP_TIMER_GROUP, BSP_TIMER, timer_group_isr_callback, 0, 1);//注册中断服务函数
}
void bsp_timer_start() //定时器开始
{
timer_start(BSP_TIMER_GROUP, BSP_TIMER);
}
void bsp_timer_pause() //定时器停止
{
timer_pause(BSP_TIMER_GROUP, BSP_TIMER);
}
- main.cpp
#include "bsp_led.h"
#include "bsp_timer.h"
void setup() {
led_init();
bsp_timer_init();
bsp_timer_start();
while (1)
{
}
}
void loop() {
}
2. 看门狗定时器
2.1 概述
esp32中包含中断看门狗和任务看门狗
- 中断看门狗: 中断看门狗用于检测执行freeRTOS任务的时候被长时间阻塞。当中断发送阻塞的时候,会触发panic handler,可以在menuconfig中设置panic handler被触发的时候怎么处理,默认是进行reset。中断看门狗可以在configuration menu中调整超时时间。如果中断服务函数时间过长就会引发中断看门狗复位。处理方法应该是让isr函数尽可能简短,如果实在不行,就调整中端口看门狗的timeout时间
- 任务看门狗是用户自己定义的。可以用于检测进程时候发生了阻塞。当长时间没有喂狗,就会引发任务看门狗复位,如果用户需要让任务看门狗复位的时候做些自定义的时候,可以修改esp_task_wdt_isr_user_handler
2.2 任务看门狗例程
#include "esp_task_wdt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led.h"
void setup() {
esp_task_wdt_init(1,true); //初始化,定义超时时间为1s,并且看门狗到时间了以后就出发panic handler进行重启
esp_task_wdt_add(NULL); //写null就是监控当前的任务
led_init();
led_on();
vTaskDelay(500 / portTICK_PERIOD_MS);
led_off();
while (1)
{
esp_task_wdt_reset(); //任务看门狗定时器复位,也就是喂狗操作
}
}
// the loop function runs over and over again until power down or reset
void loop() {
}
以上是关于ESP32-IDF02-3 外设-定时器的主要内容,如果未能解决你的问题,请参考以下文章