• ESP8266--SDK开发(延时、定时器)


    一、前言

    使用延时软件定时器硬件定时器,需要包含头文件 #include "osapi.h"


    二、延时

    os_delay_us(us)	//微妙级延时
    
    • 1

    可以根据这个自定义一个毫秒级延时:

    void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
    {	
    	for(; C_time>0; C_time--) { 
    		os_delay_us(1000);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、定时器

    3.1、软件定时器

    软件定时器接口位于 /ESP8266_NONOS_SDK/include/osapi.h

    软件定时器使用的定时器由软件实现,定时器的函数在任务中被执行。因为任务可能被中断,或者被其他高优先级的任务延迟,因此以下 os_timer 系列的接口并不能保证定时器精确执行。

    毫秒级定时器

    #include "osapi.h"
    
    os_timer_t os_timer_one;	//定义软件定时器结构体变量
    
    //定时器回调函数
    void os_timer_one_function(void *parg) {
    	os_printf("parg: %s\n", parg);
    }
    
    void ICACHE_FLASH_ATTR
    user_init(void)
    {
    	//配置定时器
    	os_timer_setfn(&os_timer_one, os_timer_one_function, "parg");
    	//使能定时器
    	os_timer_arm(&os_timer_one, 1000, 1);	//1000:1000ms响应一次   1:循环(0:不循环)
    	//停止定时器
    	//os_timer_disarm(&os_timer_one)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    微秒级定时器

    在这里插入图片描述

    注意事项

    • 对于同一个 timer, os_timer_arm 或 os_timer_arm_us 不能重复调用,必须先os_timer_disarm。
    • os_timer_setfn 必须在 timer 未使能的情况下调用,在 os_timer_arm 或os_timer_arm_us 之前或者 os_timer_disarm 之后。

    案例:小灯闪烁

    #include "osapi.h"
    #include "gpio.h"
    
    os_timer_t os_timer_one;
    int led_count = 1;
    
    //定时器回调函数
    void os_timer_one_function(void *parg) {
    	os_printf("parg: %s\n", parg);
    
    	if(led_count % 2 == 0) {
    		GPIO_OUTPUT_SET(2,0);
    	}else {
    		GPIO_OUTPUT_SET(2,1);
    	}
    	led_count++;
    }
    
    void ICACHE_FLASH_ATTR
    user_init(void)
    {
    	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
    
    	//配置定时器
    	os_timer_setfn(&os_timer_one, os_timer_one_function, "parg");
    	//使能定时器
    	os_timer_arm(&os_timer_one, 1000, 1);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3.2、硬件定时器

    硬件中断定时器接口位于 /ESP8266_NONOS_SDK/examples/driver_lib/hw_timer.c

    如果需要精确的定时,例如,周期性操作某 GPIO,请使用硬件中断定时器,具体可参考hw_timer.c,硬件定时器的执行函数在中断里被执行。

    注意事项

    • 如果使用 NMI 中断源,且为自动填装的定时器,调用 hw_timer_arm 时参数 val 必须大于 100。
    • 如果使用 NMI 中断源,那么该定时器将为最高优先级,可打断其他 ISR。
    • 如果使用 FRC1 中断源,那么该定时器无法打断其他 ISR。
    • hw_timer.c 的接口不能跟 PWM 驱动接口函数同时使用,因为两者共用了同一个硬件定时器。
    • 硬件中断定时器的回调函数定义,请勿添加 ICACHE_FLASH_ATTR 宏。
    • 使用 hw_timer.c 的接口,请勿调用 wifi_set_sleep_type(LIGHT_SLEEP); 将自动睡眠模式设置为 Light-sleep。因为 Light-sleep 在睡眠期间会停 CPU,停 CPU 期间不能响应 NMI 中断。

    一般步骤

    1、初始化硬件定时器

    在这里插入图片描述

    2、设置定时器的回调函数

    在这里插入图片描述

    3、启动定时器

    在这里插入图片描述

    案例

    我们的工程是移植的官方examples中的IOT_Demo,工程中没有包含硬件定时器的API函数接口,所以我们要先移植hw_timer.c到我们的工程之中。
    在这里插入图片描述
    在这里插入图片描述

    #include "driver/hw_timer.h"
    
    //硬件定时器回调函数
    void hw_test_timer_cb(void)
    {
    
    }
    
    void ICACHE_FLASH_ATTR
    user_init(void)
    {
    	os_printf("=== System start ===\n");
        os_printf("SDK version:%s\n", system_get_sdk_version());
    
    
        //初始化硬件定时器
        hw_timer_init(FRC1_SOURCE,1);	//FRC1_SOURCE:中断源    1:循环
        //设置硬件定时器回调函数
        hw_timer_set_func(hw_test_timer_cb);
        hw_timer_arm(100);	//100us定时进入中断函数
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    北科天绘 16线3维激光雷达开发教程
    独孤思维:自动得3w,这样赚钱颠覆你的认知
    前端八股文(3)53-84
    华为数通方向HCIP-DataCom H12-831题库(单选题:141-160)
    Django【执行查询】(二)
    node、npm、nvm相关概念区别
    mac上的yolo
    Codeforces Round 836 (Div. 2) A - C
    (rabbitmq的高级特性)消息可靠性
    Spring、MyBatis框架和Redis数据库介绍 第1关:Spring 框架简介
  • 原文地址:https://blog.csdn.net/Mr_robot_strange/article/details/127670377