前面已经学习的协议栈,GAP ,GATT等一些基础知识,虽然不是完全明白,多多少少有些基础。今天也小事牛刀一下编写自己的一个私有服务程序。因为前期准备 不足,造成很大的麻烦,还好最后找出问题来。今天我们就编写一个 LED私有服务,其他私有服务 编写大同小异,废话少说,上正体。
1、前期准备:
(1)、jlink V9.5(我的版本比较高)
(2)、打开nRF51822的RTT仿真(这个流程网上很多,大家可以参考一下,流程很简单,下面会有说明步骤)
(3)、开发板
1.1、打开RTT仿真
这个是jlink带有的功能,省去一个串口,很方便,具体步骤如下:
(1)、打开jlink串口调试
(2)、打开成功,会提示连接成功。
(3)、代码修改sdk_config,h里面的NRF_LOG_ENABLED 宏定义。(使用nrf51822 的12.3.0 sdk)
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 0
修改成
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 1
(4)、在sdk_config,h里面把串口仿真宏定义取消掉
#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART
#define NRF_LOG_BACKEND_SERIAL_USES_UART 1
修改成
#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART
#define NRF_LOG_BACKEND_SERIAL_USES_UART 0
(5)、在sdk_config,h里面把RTT仿真宏定义打开
#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
#define NRF_LOG_BACKEND_SERIAL_USES_RTT 0
修改成
#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
#define NRF_LOG_BACKEND_SERIAL_USES_RTT 1
(6)、直接下载程序可以看到结果
2、前期准备已经完成,现在直接编写程序 ,我用的模板是E:\蓝牙练习工程 :ble_app_rscs 模板,模板没什么区别,自己随便找的一个。这个私有服务,我们实现 的是LED私有服务程序。
2.1、初始化GPIO
int main(void)
{
uint32_t err_code;
bool erase_bonds=true;
// Initialize.
err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
/************************************自定义功能区***********************************************************/
//外设初始化
ALL_GPIO_Init();
/*********************************************************************************************************/
timers_init();
buttons_leds_init(&erase_bonds);
ble_stack_init();//协议栈初始化
peer_manager_init(erase_bonds);
if (erase_bonds == true)
{
NRF_LOG_INFO("Bonds erased!\r\n");
}
services_init();
gap_params_init();
advertising_init();
sensor_simulator_init();
conn_params_init();
// Start execution.
application_timers_start();
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("--------Bluetooth runing start ------------\r\n");
// Enter main loop.
for (;;)
{
if (NRF_LOG_PROCESS() == false)
{
power_manage();
}
}
}
2.2、修改services_init();增加自己的私有服务
static void services_init(void)
{
uint32_t err_code;
ble_lbs_init_t led_init;
ble_rscs_init_t rscs_init;
ble_bas_init_t bas_init;
ble_dis_init_t dis_init;
/***********************自定义私有 LED服务******************************/
led_init.led_write_handler = LED_write_handler; //led回调函数
err_code = ble_lbs_init( &led_library, &led_init);
APP_ERROR_CHECK(err_code);
/********************************************************************/
// Initialize Running Speed and Cadence Service
memset(&rscs_init, 0, sizeof(rscs_init));
rscs_init.evt_handler = NULL;
rscs_init.feature = BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT |
BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT;
后面代码省略...............................
}
2.3、增加自己的私有服务时候,如果没有添加ble_lbs.c文件,就要添加进去
路径在:
E:\蓝牙练习工程\nRF5_SDK_12.3.0_d7731ad\nRF5_SDK_12.3.0_d7731ad\components\ble\ble_services\ble_lbs
2.4、修改 LBS_UUID_BASE 宏定义
这个宏定义可以修改,也可以不修改。修改了以后,手机测试软件不会显示LED服务,而是显示 Unknown Server。
#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}
2.5协议栈的 派发函数修改 ble_evt_dispatch();
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
/** The Connection state module has to be fed BLE events in order to function correctly
* Remember to call ble_conn_state_on_ble_evt before calling any ble_conns_state_* functions. */
ble_conn_state_on_ble_evt(p_ble_evt);
pm_on_ble_evt(p_ble_evt);
ble_rscs_on_ble_evt(&m_rscs, p_ble_evt);
ble_bas_on_ble_evt(&m_bas, p_ble_evt);
ble_conn_params_on_ble_evt(p_ble_evt);
bsp_btn_ble_on_ble_evt(p_ble_evt);
on_ble_evt(p_ble_evt);
ble_advertising_on_ble_evt(p_ble_evt);
/*****************增加LED**********************/
ble_lbs_on_ble_evt(&led_library, p_ble_evt);
/***********************************************/
}
2.6 编写LED回调函数,在main.c里面编写感觉函数太多,我这里是单独封装的全局调用函数.
/*****************************************************************************
函数名 :LED_write_handler
函数参数:
函数返回值 :
函数描述:
函数功能: LED回调函数
***************************************************************************/
void LED_write_handler(ble_lbs_t * p_lbs, uint8_t led_state)
{
if (led_state)
{
NRF_LOG_INFO("1-----LED2_on LED3_OFF:---\r\n");
LED2_ON ;
LED3_OFF ;
}
else
{
NRF_LOG_INFO("2-----LED1_OFF LED3_ON:---\r\n");
LED2_OFF ;
LED3_ON ;
}
}
2.7.打开手机测试软件,搜蓝牙
2.8,连接之后,点击开关按键
2.9,点击开关
2.10、到这里我们可以看到LED灯效果,大家可以更改宏定义LBS_UUID_BASE 来更改UUID ,来看看对比一下最后的实现结果有什么不同,这里就不做多余解释。要多动手 看一下。要注意 ,宏定义必须是128位,也就是16字节。大家也可以尝试一下编写串口或者其他私有服务,不同点就是调用的函数不一样。