文章目录
- 一、前言
- 二、延时
- 三、定时器
- 3.1、软件定时器
- 3.2、硬件定时器
一、前言
使用延时、软件定时器、硬件定时器,需要包含头文件 #include "osapi.h"
二、延时
os_delay_us(us) //微妙级延时
可以根据这个自定义一个毫秒级延时:
void ICACHE_FLASH_ATTR delay_ms(u32 C_time)
{
for(; C_time>0; C_time--) {
os_delay_us(1000);
}
}
三、定时器
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)
}
微秒级定时器
注意事项
- 对于同一个 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);
}
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定时进入中断函数
}