zoukankan      html  css  js  c++  java
  • 103-ESP32_SDK开发-硬件定时器timer

    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    说明

    硬件定时器有两组,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中断

    #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

  • 相关阅读:
    aspnet_Membership_SetPassword
    FlipView使用
    结构之法字符串及链表的探索编程之美第3章
    window和linux下svn的使用
    【算法导论第13章】红黑树
    【算法导论】第16章贪心算法
    【算法导论】第15章动态规划
    ubuntu11.04下myeclipse开发环境的搭建(jdk6+tomcat6+myeclipse8.0+mysql)
    【matlab】在vc6.0中调用matlab中的正态分布产生随机数
    gnome/gtk+开发环境搭建
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/15110828.html
Copyright © 2011-2022 走看看