物联网专题11:ESP8266 定时器

软件定时器

ESP8266软件定时器的描述如下:

由上面的描述可以知道,使用软件定时器有以下步骤:

1 调用os_timer_disarm,先取消定时器定时;

在初始化定时器前,要先定义 os_timer_t 变量,取消定时器定时;

2 注册定时器回调函数;

3 开启定时器,如果想使用 毫秒级 定时器,可以使用如下 API;

接下来,编写软件定时器的代码,其实非常简单:

1 初始化函数:

// 初始化软件定时器
void ICACHE_FLASH_ATTR
BSP_OS_Timer_Init(uint32_t ms, bool	repeat_flag)
{
	// 关闭定时器
	// 参数一:要关闭的定时器
	//--------------------------------------------------------
	os_timer_disarm(&OS_Timer_1);	// 关闭软件定时器

	// 设置定时器
	// 参数一:要设置的定时器;参数二:回调函数(需类型转换);参数三:回调函数的参数
	//【注:os_timer_setfn必须在软件定时器未使能的情况下调用】
	//------------------------------------------------------------------------------------------
	os_timer_setfn(&OS_Timer_1,(os_timer_func_t *)OS_Timer_1_CallBack, NULL);	// 设置回调函数

	// 使能(启动)ms定时器
	// 参数一:要使能的定时器;参数二:定时时间(单位:ms);参数三:1=重复/0=只一次
	os_timer_arm(&OS_Timer_1, ms, repeat_flag);  // 设置定时器参数并使能定时器
	// 【如未调用system_timer_reinit,可支持范围:[5ms ~ 6,870,947ms]】
	// 【如果调用system_timer_reinit,可支持范围:[100ms ~ 428,496 ms]】
}

2 定时器回调函数:

// 定时器回调函数
void ICACHE_FLASH_ATTR OS_Timer_1_CallBack(void)
{
	F_LED = !F_LED;
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4), F_LED);			// 翻转LED
	os_printf("\r\n----OS_Timer_1_CallBack----\r\n");	// 进入回调函数标志
}

然后在主函数中进行调用(必须注释掉while死循环,否则无法执行):

user_init(void)
{
	uart_init(115200,115200);	// 初始化串口波特率
	os_delay_us(10000);			// 等待串口稳定
	os_printf("\r\n=================================================\r\n");
	os_printf("\t Project:\t%s\r\n", ProjectName);
	os_printf("\t SDK version:\t%s", system_get_sdk_version());
	os_printf("\r\n=================================================\r\n");

	BSP_LED_Init();			// 初始化 LED

	BSP_OS_Timer_Init(500, 1);	// 初始化软件定时器

	//while(1)
	//{
	//	system_soft_wdt_feed();		// 喂狗,防止复位

	//}
}

程序的执行结果如下,LED每0.5秒闪烁一次,串口正确打印调试信息:

如果还是在while中执行死循环+喂狗操作,程序不会被正确执行。因为软件定时器是在任务中执行的,而死循环会一直占用CPU,没有多余的空闲时间执行定时器的计时任务。所以,软件定时器,并不能保证精确执行。

 

硬件定时器

ESP8266的硬件定时器,如下图所示:

设置硬件定时器的步骤如下所示:

0 添加 driver_lib / driver / hw_timer.c 文件到 app / driver / 路径下;

1 调用 hw_timer_init 函数,初始化定时器;

2 设置定时器中断回调函数;

3 使能硬件定时器;

 

接下来是代码部分:

1 配置硬件定时器(注释掉死循环);

2 硬件定时器中断回调函数;

下载执行,LED每0.5秒闪烁,串口正确打印调试信息如下所示;

接下来,我们创建while 死循环,并不断喂狗。在这种操作下,按之前提到的,软件定时器是无法工作的,而硬件定时器依然能够正常工作,串口信息如下所示:

主函数:

user_init(void)
{
	uart_init(115200,115200);	// 初始化串口波特率
	os_delay_us(10000);			// 等待串口稳定
	os_printf("\r\n=================================================\r\n");
	os_printf("\t Project:\t%s\r\n", ProjectName);
	os_printf("\t SDK version:\t%s", system_get_sdk_version());
	os_printf("\r\n=================================================\r\n");

	BSP_LED_Init();			// 初始化 LED

	// 初始化硬件定时器,使用FRC1作为中断源
	hw_timer_init(0, 1);		// 【参数1:中断源】【参数2:是否重复】
	hw_timer_set_func(HW_Timer_CallBack);	// 注册定时器回调函数
	hw_timer_arm(500000);				// 使能定时器,定时时间为500 000us = 500ms

	while(1)
	{
		system_soft_wdt_feed();		// 喂狗,防止复位
	}
}

回调函数:

// 定时器回调函数
void HW_Timer_CallBack(void)
{
	F_LED = !F_LED;
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4), F_LED);			// 翻转LED
	os_printf("\r\n----HW_Timer_CallBack----\r\n");	// 进入回调函数标志
	os_printf("\r\n----Test dead loop----\r\n");    // 测试死循环
}

测试结果:LED每0.5秒闪烁,串口正确打印调试信息。

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值