[群150178878]nRF51822-新手入门笔记【1】
转自: http://www.eeboard.com/bbs/thread-40359-1-1.html
这是1年前入门时记的笔记,有些问题很简单很入门,不过懒得修改了,使用的是旧版SDK,原理一样,希望对大家有帮助,后面的笔记比较乱,抽空继续整理一下,
为了防止个人理解错误,下面的回答大多都会引用了论坛资料或者链接。
1.如何让设备发起bongding请求
先设置权限BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&dis_init.dis_attr_md.read_perm)
在ios上,除非app试图读取的characteristic收到保护,否则是没有bongding请求发生的。(可参考ble_app_gls例程)
原回答如下:
On iOS, no bonding will occur unless an app tries to read a characteristic that is protected. If you use LightBlue, this app will not do any such reads unless you specifically asks it to. To trigger bonding, you should therefore make sure to navigate the services/characteristics in such way that either a protected read or write is triggered, which again should trigger bonding.
authorization doesn't have anything to do with bonding, it's just a way for the application to know and authorize each read/write.
The protection I mean is the one set with the BLE_GAP_CONN_SEC_* macros. If you try to read any characteristic that is set as for example BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(), this will trigger bonding.
2.如何添加用户自己的128bit UUID?
使用sd_ble_uuid_vs_add(param1, param2)函数添加自己的128bit的service或者UUID,6.0的softdevice固件支持添加最多10个128bitUUID。param1是16byte用户uuid, param2存放softdevice分配的UUIDtype, 从BLE_UUID_TYPE_VENDOR_BEGIN(0x02)开始算,总共能添加10条,以后每一条只需要这个vender uuid type就行.
注意,param1的第13,14byte 不用写也行,写了也没用,后面还需添加。
/* 范例 */
ble_uuid128_t uuid_128bits = {0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0, 0, 0x05, 0x79}; //中间两个0xF431,这是苹果的 ANCS service base uuid
ble_uuid_t ble_uuid;
uint8_t uuid_128bit_type; //此变量存放softdevice分配的 UUID type
ble_uuid.uuid = 0xF431;
err_code = sd_ble_uuid_vs_add(&uuid_128bits, uuid_128bit_type);
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_me–>service_handle);
3.如何发现ios的ANCS的service以及characteristic?
(1)使用函数sd_ble_uuid_vs_add()添加central的128bit UUID
(2)使用GATTC相关的函数查找service以及characteristic
sd_ble_gattc_primary_services_discover()
sd_ble_gattc_characteristics_discover()
4.如何清除绑定?
在static void bond_manager_init(void)函数中
// Initialize the Bond Manager
bond_init_data.flash_page_num_bond = FLASH_PAGE_BOND;
bond_init_data.flash_page_num_sys_attr = FLASH_PAGE_SYS_ATTR;
bond_init_data.evt_handler = NULL;
bond_init_data.error_handler = bond_manager_error_handler;
bond_init_data.bonds_delete = true; //此处可以清除绑定
err_code = ble_bondmngr_init(&bond_init_data);
APP_ERROR_CHECK(err_code);
通过ble_bondmngr_init()函数, 即初始化了绑定参数,又同时清除了之前的绑定
5.APP_BUTTON_INIT 拿来什么用?和普通的引脚初始化有什么不同?
原型: APP_BUTTON_INIT(BUTTONS, BUTTON_COUNT, DETECTION_DELAY, USE_SCHEDULER)
用于设置特定引脚作为button, USE_SCHEDULER参数决定是否调用button_handle函数
示例:
static void buttons_init(void)
{
static app_button_cfg_t buttons[] =
{
{HR_INC_BUTTON_PIN_NO, false, NRF_GPIO_PIN_PULLUP, button_event_handler},
{HR_DEC_BUTTON_PIN_NO, false, NRF_GPIO_PIN_PULLUP, button_event_handler} // Note: This pin is also BONDMNGR_DELETE_BUTTON_PIN_NO
};
APP_BUTTON_INIT(buttons, sizeof(buttons) / sizeof(buttons[0]), BUTTON_DETECTION_DELAY, false);
}
该函数底层用到app_timer_create(); 用32.768低功耗定时器来检测按键是否发生.
6.如何保护Flash程序不被读取?
NRF_NVMC–>CONFIG = 1; //开启FLASH写权限(写UIRC)
while (NRF_NVMC–>READY == NVMC_READY_READY_Busy)
{
// Do nothing.
}
NRF_UICR–>RBPCONF = 0x00000000;
NRF_NVMC–>CONFIG = 0;
7.advertising_init()函数中的广播数据中的flag应该怎么设置, Scan Response是否需要设置flag?
flags must be included in advertising data,
and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set
Advertising Data 必须设置flag, 设置对了其他的广播数据自由选择.
Scan Response Data不需要设置flag否则会出错
8.如何广播128bit UUID?
首先建议在main()函数中添加本次工程需要用到的所有的128bit vender service base uuid, 而且添加时必须放在ble_stack_init()函数后,因为该函数启动了softdevice. (我把它放在all_vs_uuid_add()函数中, 在main()函数中调用)
static void all_vs_uuid_add(void)
{
uint32_t err_code;
ble_uuid128_t uuid_128bits = RBL_SHIELD_UUID_BASE; //16byte 数据
err_code = sd_ble_uuid_vs_add(&uuid_128bits, &ble_rbl_shield.uuid_type);
APP_ERROR_CHECK(err_code);
}
广播的128bit vender service uuid可以放在advertising data中也可以放在scan response data中
static void advertising_init(void)
{
uint32_t err_code;
ble_advdata_t advdata;
uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
ble_advdata_t srdata;
ble_uuid_t adv_uuids[] =
{
{0x0000, ble_rbl_shield.uuid_type} //BLE_UUID_TYPE_BLE ble_rbl_shield.uuid_type
};
// Build and set advertising data
memset(&advdata, 0, sizeof(advdata));
//同时在advertising data和scan response data中广播128bit vs uuid
advdata.flags.size = sizeof(flags);
advdata.flags.p_data = &flags;
advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
advdata.uuids_complete.p_uuids = adv_uuids;
srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
srdata.uuids_complete.p_uuids = adv_uuids;
err_code = ble_advdata_set(&advdata, &srdata);
APP_ERROR_CHECK(err_code);
// Initialize advertising parameters (used when starting advertising)
memset(&m_adv_params, 0, sizeof(m_adv_params));
m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
m_adv_params.p_peer_addr = NULL; // Undirected advertisement
m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
m_adv_params.interval = APP_ADV_INTERVAL;
m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS;
}
如果遇到添加后程序错误, 那要注意, 因为128bit的uuid已经占了16bytes, 如果这时候你的local name或者你还广播了其他的UUID,超过了31bytes程序是会发生错误的.
9.为什么蓝牙连接上iphone后一会就自动断线了?
这里只说一种情况, 如果蓝牙的最大及最小的连接间隔设置的太小, 就会出现上述情况, 什么都不做但是过会会断线.iphone要求的连接间隔是:
Interval Max * (Slave Latency + 1) ≤ 2 seconds
Interval Min ≥ 20 ms
Interval Min + 20 ms ≤ Interval Max Slave Latency ≤ 4
connSupervisionTimeout ≤ 6 seconds
Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout
我们可以定为20ms~40ms
10. 如何通过蓝牙传输大量数据?
询问FAE后得到的回答如下
The easiest way to send large amounts of data is to send them sequentially as notifications.
Add a characteristic that is 20 bytes long and has the notify property. Split your data in 20 byte chunks and call sd_ble_gatts_hvx() repeatedly until you get the BLE_ERROR_NO_TX_BUFFERS back. At that time, wait until you get a BLE_EVT_TX_COMPLETE, at which point you again can send data until you get the BLE_ERROR_NO_TX_BUFFERS. Repeat until all data has been sent.
https://devzone.nordicsemi.com/index.php/dealing-large-data-packet-s-through-ble#reply-1755
有个ble event 宏定义为: BLE_EVT_TX_COMPLETE, 收到这个事件就代表本次传输完毕.另外我们是通过sd_ble_gatts_hvx()把待传输的数据尽可能地添加进tx buffer中去.
11.影响nRF51822(S110固件)数据传输速度的最大因素是什么?