蓝牙学习--APP定时器(nRF52832)

什么是APP定时器

APP 定时器基于实时计数器 RTC1 的软件定时器,我们看到 RTC,首先想到的是用来记录时间的实时时钟,但是要注意,nRF52832 的 RTC并不是指实时时钟,我们不能通过 nRF52832 的 RTC 直接获取时间信息,nRF52832 的 RTC指的是对振荡源脉冲进行计数的实时计数器。SDK 中的 APP 定时器是使用 RTC1 作为时基来实现的。APP 定时器是基于实时计数器 RTC1、通过链表实现的软件定时器,APP 定时器具有软件定时器的一般特征,应用程序可以配置、创建、启动和停止定时器,应用程序也可以同时创建多个定时任务。

APP定时器的优缺点

优点:BLE总会启动RTC1,软件定时器又是基于RTC1,可创建的定时器数量多,能实现更长时间的定时,使用更灵活、方便。更重要的是省电,尤其在 BLE 应用中,省电效果更明显。

缺点:如果调用者优先级高,则在返回之前不会执行软件定时器的回调,不适用短时间定时,占用CPU时间。

APP定时器的种类

单次定时器:定时器会从应用程序设置的初始时间开始,以tick为计时单位进行倒计时,当计数值减为0时调用回调函数执行。回调函数执行完毕,则定时器停止。

周期定时器:周期定时器在时间到期执行完回调函数后,重新开始计时,直到下次时间到期,再次执行回调函数,然后一直循环下去。

创建APP定时器流程

定义APP定时器和超时时间 -> 编写超时事件回调函数 -> 初始化APP定时器程序模块 -> 创建单次定时器/创建周期定时器 -> 启动创建定时器

接下来我们来具体看这个APP定时器如何使用

1.定义APP定时器

APP定时器使用宏APP_TIMER_DEF定义具体的定时器

2.确定定时时间

因为我们的APP定时器是基于RTC1的,RTC只能分辨出tick,也就是时钟节拍,但是这个时钟节拍和时间的对应关系需要我们去计算,需要修改时间时都要我们去计算的话,非常麻烦。所以我们的SDK专门提供了一个宏来解决我们此时的问题。

这里面的单位是ms。也就是我们的超时时间设置成了100ms。

3.编写超时事件回调函数

APP 定时器超时后即会回调创建定时器时注册的超时事件回调函数,该回调函数即是
应用程序实现功能的地方,在这个函数里面,我们可以编写功能代码。

4.初始化APP定时器

使用 APP 定时器时,需要引用头文件“app_timer.h”。

初始化函数

这直接在主函数中调用就可以APP定时器初始化完成了

5.创建APP定时器

APP 定时器通过调用 app_timer_create()函数创建的。

APP定时器模式分为两种

6.启动/停止APP定时器

APP 定时器创建成功后并不会启动,需要应用程序去启动。启动和停止一个 APP 定时
器的函数分别是 app_timer_start()和 app_timer_stop()。

app_timer_start():

app_timer_stop():

全部代码:

#include <stdbool.h>   
#include <stdint.h>
#include "nrf_delay.h"
#include "boards.h"
#include "nrf_drv_rtc.h"
#include "nrf_drv_clock.h"
#include "app_timer.h" 


//定义APP定时器m_led_toggle_timer_id(LED定时器),用于驱动指示灯D1,每100ms翻转一次D1的状态
//定义一个APP定时器
APP_TIMER_DEF(led_toggle_timer_id);                                  
                              
//LED定时器超时时间:100ms
#define LED_TOGGLE_INTERVAL         APP_TIMER_TICKS(100)    

//配置低频时钟,时钟源设置的是外部32.768KHz晶体
static void lfclk_config(void)
{
    //初始化时钟模块,设置低频时钟源
	  ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    //请求低频时钟,输入参数为NULL表示低频时钟启动后不产生事件
    nrf_drv_clock_lfclk_request(NULL);
}


//LED定时器超时事件回调函数
static void led_toggle_timeout_handler(void * p_context)
{
	UNUSED_PARAMETER(p_context); 
  nrf_gpio_pin_toggle(LED_1);
}

//初始化APP定时器程序模块和创建APP定时器
static void timers_init(void)
{
    ret_code_t err_code;

    //初始化APP定时器程序模块
    err_code = app_timer_init();
	  //检查错误代码
    APP_ERROR_CHECK(err_code);

    //创建APP定时器:LED定时器,周期定时器,启动后周期运行,用于驱动指示灯闪烁
    err_code = app_timer_create(&led_toggle_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                led_toggle_timeout_handler);
	  APP_ERROR_CHECK(err_code);//检查错误代码
}

int main(void)
{
	ret_code_t err_code;
	//初始化开发板上的4个LED,即将驱动LED的GPIO配置为输出,
	bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
	//初始化APP定时器程序模块和创建APP定时器
	timers_init();
	//初始化低频时钟LFCLK
	lfclk_config();
	
	while (true)
	{
			if(nrf_gpio_pin_read(BUTTON_2) == 0)
			{
					//软件消抖
					nrf_delay_ms(20);
					//按键S2有效
					if(nrf_gpio_pin_read(BUTTON_2) == 0)
					{
						//停止LED定时器
						err_code = app_timer_stop(led_toggle_timer_id);
						APP_ERROR_CHECK(err_code);
					}
			}
			//检测按键S3是否按下
			if(nrf_gpio_pin_read(BUTTON_3) == 0)
			{
					//软件消抖
					nrf_delay_ms(20);
					//如果按键S3有效
					if(nrf_gpio_pin_read(BUTTON_3) == 0)
					{
						//开启LED定时器
						err_code = app_timer_start(led_toggle_timer_id,LED_TOGGLE_INTERVAL,led_toggle_timeout_handler);
						APP_ERROR_CHECK(err_code);
					}
			}
	}
}

这是周期执行的代码,用两个按键控制LED定时任务的执行和停止。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焦不得

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值