前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >103-ESP32_SDK开发-硬件定时器timer

103-ESP32_SDK开发-硬件定时器timer

作者头像
杨奉武
发布2021-12-01 15:04:10
5600
发布2021-12-01 15:04:10
举报
文章被收录于专栏:知识分享

说明

硬件定时器有两组,0和1. 然后每一组都有两个定时器,0和1.

所以共有四个定时器

什么是定时器?定时器具体是怎么到了时间进去中断的?

定时器里面是啥?就是个计数器.定时器的时钟,就是计数器的时钟.假设计数器的时钟是1Hz

假设设置了计数器计数到1的时候就进入中断,那么就是每隔1S进入中断了.

假设计数器的时钟是80MHz,我想每隔1ms进入一次中断,我应该设置计数值是多少呢???

计数器每记一次需要 1/80000000 秒 也就是 1/80000 毫秒

要记到80000次才到1ms

想定时多少毫秒,设置初值可以写成 X*(80000000/1000) X就是要定时的ms数

假设时钟分频了8,那么现在就是10MHz

我想每隔1ms进入一次中断,我应该设置计数值是多少呢???

计数器记一次是 1/10000000 秒 也就是 1/10000 毫秒

需要多少个 1/10000 毫秒 才能到1ms呢? 10000次

想定时多少毫秒,设置初值可以写成 X*(80000000/分频系数/1000) X就是要定时的ms数

想定时多少微秒,设置初值可以写成 X*(80000000/分频系数) X就是要定时的us数

使用定时器分组0的0号定时器产生1S中断

代码语言:javascript
复制
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "driver/timer.h"

#define gpio_pin 25


/*定时器中断函数
因为设置中断的时候,中断设置的 ESP_INTR_FLAG_IRAM 所以中断函数需要加 IRAM_ATTR
*/
void IRAM_ATTR timer_group0_isr(void *para)
{
    //获取定时器分组0中的哪一个定时器产生了中断
    uint32_t timer_intr = timer_group_get_intr_status_in_isr(TIMER_GROUP_0);
    if (timer_intr & TIMER_INTR_T0) {//定时器0分组的0号定时器产生中断
        /*清除中断*/
        timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
        /*重新使能定时器中断*/    
        timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0);
    }

    /*设置gpio输出高低电平*/
    gpio_set_level(gpio_pin, 1-gpio_get_level(gpio_pin));
}

void gpio_init(void){
    gpio_config_t io_conf;
    //禁止中断
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //输入输出模式
    io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
    //配置要设置的引脚
    io_conf.pin_bit_mask = (unsigned long long)1<<gpio_pin;
    //禁止下拉
    io_conf.pull_down_en = 0;
    //禁止上拉
    io_conf.pull_up_en = 0;
    //配置gpio(不设置上下拉默认输出低电平)
    gpio_config(&io_conf);

}

void app_main(void)
{ 
    gpio_init();//初始化gpio

    /*设置定时器初始化参数*/
    timer_config_t config = {
        .divider = 8,//分频系数[2-65535]
        .counter_dir = TIMER_COUNT_UP,//计数方式是向上计数
        .counter_en = TIMER_PAUSE,//调用timer_init函数以后不启动计数,调用timer_start时才开始计数
        .alarm_en = TIMER_ALARM_EN,//到达计数值启动报警(计数值溢出,进入中断)
        .auto_reload = 1,//自动重新装载预装值
    };
    /*初始化定时器;TIMER_GROUP_0(定时器分组0); TIMER_0(分组0中的0号定时器)*/
    timer_init(TIMER_GROUP_0, TIMER_0, &config);

    /*设置定时器预装值,0*/
    timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
    /*设置报警阈值*/ // 1000[定时1000ms]*(TIMER_BASE_CLK[定时器时钟]/8[分频系数]/1000[想延时ms级别所以除以1000]),
    timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1000*(TIMER_BASE_CLK/8/1000) );
    /*使能定时器中断*/
    timer_enable_intr(TIMER_GROUP_0, TIMER_0);
    /*注册定时器中断函数*/
    timer_isr_register(TIMER_GROUP_0, TIMER_0, 
        timer_group0_isr,//定时器回调函数
        (void *) TIMER_0, //传递给定时器回调函数的参数
        ESP_INTR_FLAG_IRAM, //把中断放到 IRAM 中
        NULL //调用成功以后返回中断函数的地址,一般用不到
    );
    /*启动定时器*/
    timer_start(TIMER_GROUP_0, TIMER_0);
}

下载进去之后,会看到led每隔1S闪耀

如果想让定时器是一次性的,可以把重新使能屏蔽

如果想使用分组1

TIMER_GROUP_1

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说明
    • 硬件定时器有两组,0和1. 然后每一组都有两个定时器,0和1.
      • 所以共有四个定时器
      • 什么是定时器?定时器具体是怎么到了时间进去中断的?
        • 定时器里面是啥?就是个计数器.定时器的时钟,就是计数器的时钟.假设计数器的时钟是1Hz
          • 假设设置了计数器计数到1的时候就进入中断,那么就是每隔1S进入中断了.
            • 假设计数器的时钟是80MHz,我想每隔1ms进入一次中断,我应该设置计数值是多少呢???
              • 计数器每记一次需要 1/80000000 秒 也就是 1/80000 毫秒
                • 要记到80000次才到1ms
                  • 想定时多少毫秒,设置初值可以写成 X*(80000000/1000) X就是要定时的ms数
                    • 假设时钟分频了8,那么现在就是10MHz
                      • 我想每隔1ms进入一次中断,我应该设置计数值是多少呢???
                        • 计数器记一次是 1/10000000 秒 也就是 1/10000 毫秒
                          • 需要多少个 1/10000 毫秒 才能到1ms呢? 10000次
                            • 想定时多少毫秒,设置初值可以写成 X*(80000000/分频系数/1000) X就是要定时的ms数
                              • 想定时多少微秒,设置初值可以写成 X*(80000000/分频系数) X就是要定时的us数
                              • 使用定时器分组0的0号定时器产生1S中断
                              • 下载进去之后,会看到led每隔1S闪耀
                              • 如果想让定时器是一次性的,可以把重新使能屏蔽
                              • 如果想使用分组1
                                • TIMER_GROUP_1
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档