概述
蓝牙
1.nrf52832的蓝牙程序结构
1.配置log日志
2.配置APP定时器 (使用的是rtc1的软件定时器)
3.电源管理模块初始化
4.蓝牙协议栈初始化
5.GATT和GAP初始化
6.广播初始化
7.服务初始化
8.配置连接参数
9.开启广播
10.启动连接
蓝牙示例程序
相关资料可以参考官方sdk文件(头文件较多,建议直接使用官方例程修改)
1.文件路径:examplesble_peripheralble_app_blinkypca10040s132arm5_no_packs
蓝牙从机示例程序
注意:烧录程序时记得先烧录蓝牙协议栈,再烧录工程
(本例程参考nrf52832开发指南)
#include <stdbool.h>
#include <stdint.h>
#include <string.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 "Hz" //设备名称
#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定时器初始化函数
*/
static void timer_init(void)
{
ret_code_t err = app_timer_init();
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");
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");
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();
timer_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
advertising_init();
services_init();
conn_params_init();
NRF_LOG_INFO("已完成初始化配置");
advertising_start();
NRF_LOG_FLUSH();
while(1)
{
idle_state_handle();
}
}
最后
以上就是威武电脑为你收集整理的二、nrf52832的蓝牙工程模板的全部内容,希望文章能够帮你解决二、nrf52832的蓝牙工程模板所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复