四、nrf52832-蓝牙-定时器任务

蓝牙定时器任务
1.定时器:
    1.单次定时器:手动重启
    2.循环定时器:自动重启
    (这里使用的软件APP定时器是以RTC1为核心的)
2.定义一个定时器
    APP_TIMER_DEF(timer_id);
3.定时器定时函数:(实现延时)
    APP_TIMER_TICKS(ms)
    (RTC1只能识别tick,该函数可以实现ms到tick的转换)
常用定时器函数
1.timer初始化函数:app_timer_init()
2.创建timer函数: app_timer_create()
    mode:
        APP_TIMER_MODE_REPEATED
        APP_TIMER_MODE_SINGLE_SHOT
3.启动timer函数:app_timer_start()
4.停止timer函数:app_timer_stop()
nrf52832蓝牙协议栈下的timer任务
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf_gpio.h"
/* log日志需要的头文件 */
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
/* 定时器需要的头文件 */
#include "app_timer.h"
#include "bsp_btn_ble.h"
/* 蓝牙协议栈管理需要的头文件 */
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
/* 电源管理需要的头文件 */
#include "nrf_pwr_mgmt.h"
/* 排序写入模块需要的头文件 */
#include "nrf_ble_qwr.h"
/* GATT属性配置协议需要的头文件 */
#include "nrf_ble_gatt.h"
/* 建立连接参数需要的头文件 */
#include "ble_conn_params.h"
/* 蓝牙广播需要的头文件 */
#include "ble_advdata.h"
#include "ble_advertising.h"


/* 蓝牙的初始化宏定义 */
#define DEVICE_NAME					"BLE_template"						//设备名称

#define APP_BLE_OBSERVER_PRIO		3									//应用程序事件监视者优先级(应用程序不可修改)
#define APP_BLE_CONN_CFG_TAG		1									//ble配置标签
/* 连接时间的时间间隔是1.25ms的倍数(7.5ms~4000ms) */
#define MIN_CONN_INTERVAL			MSEC_TO_UNITS(100,UNIT_1_25_MS)		//设置最小连接时间
#define MAX_CONN_INTERVAL			MSEC_TO_UNITS(200,UNIT_1_25_MS)		//设置最小连接时间
#define SLAVE_LATENCY				0									//从机延时时间(可以利用跳过连接)
/* 监控超时时间是以10ms为倍数,100~32000ms */
#define CONN_SUP_TIMER				MSEC_TO_UNITS(4000,UNIT_10_MS)		//监控超时时间
/* 蓝牙参数延时时间定义 */
#define FIRST_CONN_PARAMS_UPDATE_DELAY	APP_TIMER_TICKS(5000)			//首次调用连接参数更新延时时间5s
#define NEXT_CONN_PARAMS_UPDATE_DELAY	APP_TIMER_TICKS(30000)			//每次调用连接参数更新间隔延时时间30s
#define MAX_CONN_PARAMS_UPDATE_COUNT		3							//设置放弃连接前尝试连接数
/* 广播时间间隔是以0.625的倍数 */
#define APP_ADV_INTERVAL				300								//广播间隔,187.5ms
#define APP_ADV_DURATION				0								//广播持续时间(0表示不超时)

#define	DEAD_BEEF						0xDEADBEEF						//应用于错误代码退出栈时确定堆栈位置

NRF_BLE_GATT_DEF(gatt);													//创建gatt实例
NRF_BLE_QWR_DEF(qwr);													//创建排队写入实例
BLE_ADVERTISING_DEF(advertising);										//创建广播实例

static uint16_t conn_handle = BLE_CONN_HANDLE_INVALID;					//创建连接句柄(初始状态为无设备连接)
/**
 * gap参数初始化函数(通用访问规范)
 */
static void gap_params_init(void)
{
	ret_code_t	err;
	ble_gap_conn_params_t	gap_conn_params;							//创建gap连接参数结构体
	ble_gap_conn_sec_mode_t	sec_mode;									//设置gap安全模式1
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
	/* 设置蓝牙设备名称 */
	err = sd_ble_gap_device_name_set(&sec_mode,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME));
	APP_ERROR_CHECK(err);
	memset(&gap_conn_params,0,sizeof(gap_conn_params));					//先将连接参数清零
	/* 设置gap连接参数 */
	gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;				//设置最小连接时间
	gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;				//设置最大连接时间
	gap_conn_params.slave_latency = SLAVE_LATENCY;						//设置从机延时时间
	gap_conn_params.conn_sup_timeout = CONN_SUP_TIMER;					//设置监督超时时间
	err = sd_ble_gap_ppcp_set(&gap_conn_params);						//初始化gap
	APP_ERROR_CHECK(err);
}
/**
 * gatt初始化函数(属性配置协议)
 */
static void gatt_init(void)
{
	ret_code_t err;
	err = nrf_ble_gatt_init(&gatt,NULL);
	APP_ERROR_CHECK(err);
}
/**
 * 空闲状态处理函数
 */
static void idle_state_handle(void)
{
	//挂起log
	if(NRF_LOG_PROCESS() == false)
	{
		//运行电源管理,以实现低功耗
		nrf_pwr_mgmt_run();
	}
}

/**
 * timer定时器初始化函数
 */
APP_TIMER_DEF(timer_task1);									//定义一个软件定时器
static void task1_timerout_handle(void * p_connect)
{	
	UNUSED_PARAMETER(p_connect);							//无参数传递
	nrf_gpio_pin_toggle(18);
}
static void timer_init(void)
{
	ret_code_t err = app_timer_init();						//初始化定时器
	APP_ERROR_CHECK(err);									//创建一个软件定时器
	app_timer_create(&timer_task1,APP_TIMER_MODE_REPEATED,task1_timerout_handle);
	APP_ERROR_CHECK(err);
}
/**
 * led灯初始化函数
 */
static void led_init(void)
{
	ret_code_t err;
	err = bsp_init(BSP_INIT_LEDS,NULL);
	APP_ERROR_CHECK(err);
}
/**
 *电源管理初始化函数
 */
static void power_management_init(void)
{
	ret_code_t err;
	err = nrf_pwr_mgmt_init();
	APP_ERROR_CHECK(err);
}
/**
 * 连接参数协商模块错误处理事件回调函数
 */
static void conn_params_error_handle(uint32_t nrf_error)
{
	APP_ERROR_CHECK(nrf_error);
}
/**
 * 连接参数协商模块事件回调函数
 */
static void on_conn_params_event_handle(ble_conn_params_evt_t * event)
{
	ret_code_t err;
	//连接参数协商失败
	if(event->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
	{
		err = sd_ble_gap_disconnect(conn_handle,BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
		APP_ERROR_CHECK(err);
	}
	//连接参数协商成功
	else if(event->evt_type == BLE_CONN_PARAMS_EVT_SUCCEEDED)
	{
	}
}
/**
 * 连接参数协商模块初始化
 */
static void conn_params_init(void)
{
	ret_code_t err;
	ble_conn_params_init_t cp_init;												//创建连接参数结构体
	memset(&cp_init,0,sizeof(cp_init));											//连接参数结构体数据清零
	cp_init.p_conn_params		= NULL;											//从主机获取连接参数
	cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;	//首次连接更新参数请求时间
	cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;		//连接参数请求更新间隔时间
	cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;		//放弃连接前尝试连接次数
	cp_init.start_on_notify_cccd_handle  = BLE_GATT_HANDLE_INVALID;				//连接参数更新从连接事件开始计时
	cp_init.evt_handler = on_conn_params_event_handle;							//注册连接参数更新回调函数
	cp_init.error_handler = conn_params_error_handle;							//注册连接参数更新错误回调函数
	cp_init.disconnect_on_fail = false;											//连接参数更新失败不断开连接
	err = ble_conn_params_init(&cp_init);
	APP_ERROR_CHECK(err);
}
/**
 * BLE事件处理函数
 */
static void ble_evt_handler(ble_evt_t const * event,void * p_connect)
{
	ret_code_t err;
	switch(event->header.evt_id)
	{
		/* 断开连接事件 */
		case BLE_GAP_EVT_DISCONNECTED:
			NRF_LOG_INFO("GAP disconnect");
			break;
		/*  连接成功事件 */
		case BLE_GAP_EVT_CONNECTED:
			NRF_LOG_INFO("GAP Connect");
			err = bsp_indication_set(BSP_INDICATE_CONNECTED);					//连接成功,led常亮
			APP_ERROR_CHECK(err);
			conn_handle = event->evt.gap_evt.conn_handle;						//配置连接事件回调函数
			err = nrf_ble_qwr_conn_handle_assign(&qwr,conn_handle);				//将排队写入实例与连接关联			
			APP_ERROR_CHECK(err);
			break;
		/* PHY更新事件 */
		case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
			{
				NRF_LOG_INFO("PHY update request");
				ble_gap_phys_t const phys = {									//创建phy结构体
					.rx_phys = BLE_GAP_PHY_AUTO,
					.tx_phys = BLE_GAP_PHY_AUTO
				};
				err = sd_ble_gap_phy_update(event->evt.gap_evt.conn_handle,&phys);
				APP_ERROR_CHECK(err);
			}
			break;
		/* GATT客户端响应超时事件 */
		case BLE_GATTC_EVT_TIMEOUT:
			NRF_LOG_INFO("GATT Client timeout");								//从机响应超时,断开连接
			err = sd_ble_gap_disconnect(event->evt.gattc_evt.conn_handle,
										BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
			APP_ERROR_CHECK(err);
			break;
		/* GATT服务器响应超时事件 */
		case BLE_GATTS_EVT_TIMEOUT:
			NRF_LOG_INFO("GATT server Timeout");								//主机响应超时,断开连接
			err = sd_ble_gap_disconnect(event->evt.gattc_evt.conn_handle,
										BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
			APP_ERROR_CHECK(err);
			break;

		default :
		break;
	}
}
/**
 * 蓝牙协议栈初始化函数
 */
static void ble_stack_init(void)
{
	ret_code_t err;
	err = nrf_sdh_enable_request();											//蓝牙协议栈请求使能
	APP_ERROR_CHECK(err);
	uint32_t ram_start = 0;
	err = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG,&ram_start);		//初始化蓝牙协议栈(默认配置)
	APP_ERROR_CHECK(err);
	err = nrf_sdh_ble_enable(&ram_start);									//蓝牙协议栈使能
	APP_ERROR_CHECK(err);
	NRF_SDH_BLE_OBSERVER(ble_observer,APP_BLE_OBSERVER_PRIO,ble_evt_handler,NULL);	//配置蓝牙监测者,检测蓝牙协议栈事件
}
/**
 * 广播事件回调函数
 */
static void adv_evt_handler(ble_adv_evt_t event)
{
	ret_code_t err;
	switch(event)
	{
		case BLE_ADV_EVT_FAST:												//快速广播启动事件
			NRF_LOG_INFO("fast advertising");
			err = bsp_indication_set(BSP_INDICATE_ADVERTISING);				//led指示
			APP_ERROR_CHECK(err);
			break;
		case BLE_ADV_EVT_IDLE:												//广播超时事件
			err = bsp_indication_set(BSP_INDICATE_IDLE);
			APP_ERROR_CHECK(err);
			break;
		default:
		break;
	}
}
/**
 * 广播初始化函数
 */
static void advertising_init(void)
{
	ret_code_t err;
	ble_advertising_init_t init;
	memset(&init,0,sizeof(init));
	init.advdata.name_type = BLE_ADVDATA_FULL_NAME;							//全名
	init.advdata.include_appearance = true;									//包含外观
	init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;		//设置为一般可发现模式,不支持BR/EDR
	init.config.ble_adv_fast_enabled = true;								//设置为快速广播模式
	init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;					//广播时间间隔
	init.config.ble_adv_fast_timeout = APP_ADV_DURATION;					//广播持续时间
	init.evt_handler = adv_evt_handler;										//广播事件回调函数
	err = ble_advertising_init(&advertising,&init);							//广播初始化函数
	APP_ERROR_CHECK(err);
	ble_advertising_conn_cfg_tag_set(&advertising,APP_BLE_CONN_CFG_TAG);
}
/**
 * 启动广播函数
 */
static void advertising_start(void)
{
	ret_code_t err;
	err = ble_advertising_start(&advertising,BLE_ADV_MODE_FAST);
	APP_ERROR_CHECK(err);
}
/**
 * 排队写入事件错误回调函数
 */
static void nrf_qwr_error_handler(uint32_t nrf_error)
{
	APP_ERROR_CHECK(nrf_error);
}
/**
 * 服务初始函数
 */
static void services_init(void)
{
	ret_code_t err;
	nrf_ble_qwr_init_t qwr_init = {0};
	qwr_init.error_handler = nrf_qwr_error_handler;
	err = nrf_ble_qwr_init(&qwr,&qwr_init);									//初始化排队写入模块
	APP_ERROR_CHECK(err);
}

static void log_init(void)
{
	ret_code_t err = NRF_LOG_INIT(NULL);
	APP_ERROR_CHECK(err);
	NRF_LOG_DEFAULT_BACKENDS_INIT();
}

int main(void)
{
	log_init();
	nrf_gpio_cfg_output(18);
	nrf_gpio_pin_clear(18);

	timer_init();
	led_init();
	power_management_init();
	ble_stack_init();
	gap_params_init();
	gatt_init();
	advertising_init();
	services_init();
	conn_params_init();

	NRF_LOG_INFO("已完成初始化配置");
	advertising_start();
	app_timer_start(timer_task1,500,NULL);						//开启定时器任务
	NRF_LOG_FLUSH();
	
	while(1)
	{
		idle_state_handle();
	}
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值