本帖最后由 N32BLE 于 2022-7-15 08:57 编辑
#技术资源#
此贴目的是让使用者能够快速熟悉N32WB03x系列蓝牙SOC芯片的API函数的使用方式,以减少开发前期的准备时间,降低开发难度。
包含以下几个小节:蓝牙应用模块 蓝牙安全加密模块 软件定时器 蓝牙睡眠模块 硬件延迟模块 蓝牙程序编程建议
一、蓝牙应用模块
1.1、ns_ble_stack_init 功能:蓝牙协议栈初始化,注册蓝牙消息回调和用户自定义消息回调。 语法:void ns_ble_stack_init(struct ns_stack_cfg_t const* p_handler); 参数:[in] p_handler:蓝牙应用回调函数配置,详细参考结构体ns_stack_cfg_t定义; 返回值:无 使用示例: struct ns_stack_cfg_t app_handler; app_handler.ble_msg_handler = app_ble_msg_handler; //user ble msg handler app_handler.user_msg_handler = app_user_msg_handler; //user custom msg handler ns_ble_stack_init(&app_handler);
1.2、ns_ble_gap_init 功能:蓝牙通用参数配置,比如蓝牙mac地址,名称,角色,连接参数等,详情参考结构体struct ns_gap_params_t的定义。 语法:voidns_ble_gap_init(structns_gap_params_t const* p_dev_info); 参数:[in] p_dev_info:蓝牙通用参数结构体指针。 返回值:无 使用示例: struct ns_gap_params_t dev_info = {0}; memcpy(dev_info.mac_addr.addr, "\x01\x02\x03\x04\x05\x06" , BD_ADDR_LEN); dev_info.mac_addr_type = GAPM_STATIC_ADDR; dev_info.appearance = 0; dev_info.dev_role = GAP_ROLE_PERIPHERAL; dev_info.dev_name_len = sizeof(CUSTOM_DEVICE_NAME)-1; memcpy(dev_info.dev_name, CUSTOM_DEVICE_NAME, dev_info.dev_name_len); dev_info.dev_conn_param.intv_min = MSECS_TO_UNIT(MIN_CONN_INTERVAL,MSECS_UNIT_1_25_MS); dev_info.dev_conn_param.intv_max = MSECS_TO_UNIT(MAX_CONN_INTERVAL,MSECS_UNIT_1_25_MS); dev_info.dev_conn_param.latency = SLAVE_LATENCY; dev_info.dev_conn_param.time_out = MSECS_TO_UNIT(CONN_SUP_TIMEOUT,MSECS_UNIT_10_MS); dev_info.conn_param_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; ns_ble_gap_init(&dev_info);
1.3、ns_ble_add_prf_func_register
功能:注册服务(profile)添加函数,后续系统将调用注册好的服务添加函数,添加相应的服务。
语法:boolns_ble_add_prf_func_register(ns_ble_add_prf_func_t func);
参数:[in] func:添加服务(profile)函数, 函数实现方式参考例程函数app_dis_add_dis ;
返回值:true:注册成功。false:注册失败。
使用示例: ns_ble_add_prf_func_register(app_dis_add_dis);
1.4、ns_ble_prf_task_register
功能:注册服务(profile)的子任务事件到蓝牙应用事件回调列表;
语法:bool ns_ble_prf_task_register(struct prf_task_t *prf);
参数:[in] prf:服务(profile)子任务结构体指针,详情参考结构体prf_task_t
返回值:true:注册成功。false:注册失败;
使用示例:
struct prf_task_t prf; prf.prf_task_id = TASK_ID_DISS; prf.prf_task_handler = &app_dis_handlers; ns_ble_prf_task_register(&prf);
1.5、prf_get_itf_func_register
功能:注册服务(profile)任务接口函数获取函数;
语法:bool prf_get_itf_func_register(struct prf_get_func_t *prf);
参数:[in] prf:服务任务接口获取函数的指针;
返回值:true:注册成功。false:注册失败;
使用示例:
struct prf_get_func_t get_func; get_func.task_id = TASK_ID_DISS; get_func.prf_itf_get_func = diss_prf_itf_get; prf_get_itf_func_register(&get_func);
1.6、ns_ble_adv_init
功能:初始化ble蓝牙广播参数并初始化;
语法:void ns_ble_adv_init(struct ns_adv_params_t const* p_adv_init);
参数:[in] p_adv_init:广播初始化参数结构体指针;
返回值:无
使用示例:
struct ns_adv_params_t user_adv = {0}; //init advertising data user_adv.adv_data_len = ADVERTISE_DATA_LEN; memcpy(user_adv.adv_data,ADVERTISE_DATA,ADVERTISE_DATA_LEN); user_adv.scan_rsp_data_len = ADV_SCNRSP_DATA_LEN; memcpy(user_adv.scan_rsp_data,ADV_SCNRSP_DATA,ADV_SCNRSP_DATA_LEN); user_adv.attach_appearance = false; user_adv.attach_name = true; user_adv.ex_adv_enable = false; user_adv.adv_phy = PHY_1MBPS_VALUE; user_adv.directed_adv.enable = false; user_adv.fast_adv.enable = true; user_adv.fast_adv.duration = CUSTOM_ADV_FAST_DURATION; user_adv.fast_adv.adv_intv = CUSTOM_ADV_FAST_INTERVAL; ser_adv.slow_adv.enable = true; user_adv.slow_adv.duration = CUSTOM_ADV_SLOW_DURATION; user_adv.slow_adv.adv_intv = CUSTOM_ADV_SLOW_INTERVAL; user_adv.ble_adv_msg_handler = app_ble_adv_msg_handler; ns_ble_adv_init(&user_adv);
1.7、ns_ble_adv_start
功能:开始(使能)蓝牙广播
语法:void ns_ble_adv_start(void);
参数:无
返回值:无
使用示例:
ns_ble_adv_start();
1.8、ns_ble_adv_stop
功能:停止蓝牙广播
语法:void ns_ble_adv_stop(void);
参数:无
返回值:无
使用示例:
ns_ble_adv_stop();
1.9、ns_ble_adv_data_set
功能:设置广播数据包的内容
语法:void ns_ble_adv_data_set(uint8_t* p_dat, uint16_t len);
参数:[in] p_dat:设置的广播包数据。[in] len:设置的广播包数据的长度;
返回值:无
使用示例:
ns_ble_adv_data_set(CUSTOM_USER_ADVERTISE_DATA,CUSTOM_USER_ADVERTISE_DATA_LEN);
1.10、ns_ble_scan_rsp_data_set
功能:设置广播扫描回应数据包的内容
语法:void ns_ble_scan_rsp_data_set(uint8_t* p_dat, uint16_t len);
参数:[in] p_dat:设置的广播扫描回应包数据。[in] len:设置的广播扫描回应包数据的长度;
返回值:无
使用示例:
ns_ble_scan_rsp_data_set(CUSTOM_USER_ADV_SCNRSP_DATA,CUSTOM_USER_ADV_SCNRSP_DATA_LEN);
1.11、ns_ble_ex_adv_data_set
功能:设置扩展广播数据包的内容
语法:void ns_ble_ex_adv_data_set(uint8_t* p_dat, uint16_t len);
参数:[in] p_dat:设置扩展广播包数据,注意这里不可以使用局部变量的指针。[in] len:设置扩展广播包数据的长度。
返回值:无
使用示例:
const staticuint8_t ex_adv[] = {"\x29\xff""1234567890123456789012345678901234567890"};
ns_ble_ex_adv_data_set((uint8_t*) ex_adv, sizeof(ex_adv)-1);
1.12、ns_ble_scan_init
功能:初始化蓝牙BLE扫描功能的参数;
语法:voidns_ble_scan_init(structns_scan_params_t *p_init);
参数:[in] p_init:扫描功能参数结构体指针,详细参考结构体ns_scan_params_t内部定义;
返回值:无
使用示例:
struct ns_scan_params_t init = {0}; static const uint8_t target_name[] = {"NS_RDTS_SERVER"}; init.type = SCAN_PARAM_TYPE; init.dup_filt_pol = SCAN_PARAM_DUP_FILT_POL; init.connect_enable = SCAN_PARAM_CONNECT_EN; init.prop_active_enable = SCAN_PARAM_PROP_ACTIVE; init.scan_intv = SCAN_PARAM_INTV; init.scan_wd = SCAN_PARAM_WD; init.duration = SCAN_PARAM_DURATION; init.filter_type = SCAN_FILTER_BY_NAME; init.filter_data = (uint8_t*)&target_name; ns_ble_scan_init(&init);
1.13、ns_ble_start_scan
功能:开启蓝牙BLE扫描功能
语法:void ns_ble_start_scan(void);
参数:无
返回值:无
使用示例:
ns_ble_start_scan();
1.14、ns_ble_stop_scan
功能:停止蓝牙BLE扫描功能
语法:void ns_ble_stop_scan(void);
参数:无
返回值:无
使用示例:
ns_ble_stop_scan();
1.15、ns_ble_start_init
功能:主机主动发起蓝牙BLE连接。注意仅供主机设备调用
语法:void ns_ble_start_init(uint8_t *addr, uint8_t addr_type);
参数:[in] addr:将连接的从设备地址。[in] addr_type:将连接的设备地址类型,扫描返回的信息包含地址类型
返回值:无
使用示例:
ns_ble_start_init("\x11\x11\x11\x11\x11\x11",GAPM_STATIC_ADDR);
1.16、ns_ble_update_param
功能:主机或从机主动发起蓝牙BLE连接参数更新请求
语法:void ns_ble_update_param(structgapc_conn_param *conn_param);
参数:[in] conn_param:连接参数结构体指针
返回值:无
使用示例:
struct gapc_conn_param conn_param;
conn_param.intv_min = 12; //15ms conn_param.intv_max = 12; //15ms conn_param.latency = 5; conn_param.time_out = 500; //5000ms ns_ble_update_param(&conn_param);
1.17、ns_ble_mtu_set
功能:主机或从机主动发起蓝牙BLE mtu参数更新请求。应注意用户数据包有效数据长度比MTU小3字节。
语法:void ns_ble_mtu_set(uint16_t mtu);
参数:[in] mtu:蓝牙BLE mtu值,最大值为517;
返回值:无
使用示例:
ns_ble_mtu_set(247); //set mtu as 247
1.18、ns_ble_phy_set
功能:主机或从机主动发起蓝牙BLE PHY参数更新请求
语法:void ns_ble_phy_set(enum gap_phy_val phy);
参数:[in] phy:蓝牙BLE phy参数值,可选参数参考enum gap_phy_val声明。
返回值:无
使用示例:
ns_ble_phy_set(GAP_PHY_125KBPS); //set phy as coded 125kbps
1.19、ns_ble_active_rssi
功能:主机或从机主动发起蓝牙BLE rssi读取请求。读取的值通过蓝牙事件回调函数的APP_BLE_GAP_RSSI_IND消息返回。
语法:void ns_ble_active_rssi(uint32_t interval);
参数:[in] interval:蓝牙BLE rssi读取间隙,时间单位毫秒,输入0值时只读取一次。
返回值:无
使用示例:
void app_ble_msg_handler(struct ble_msg_t const *p_ble_msg)
{ switch(p_ble_msg->msg_id) { case APP_BLE_OS_READY: NS_LOG_INFO("APP_BLE_OS_READY\r\n"); break; case APP_BLE_GAP_CONNECTED: app_ble_connected(); ns_ble_active_rssi(40); //enable rssi read every 1000ms break; case APP_BLE_GAP_DISCONNECTED: app_ble_disconnected(); break; caseAPP_BLE_GAP_RSSI_IND: NS_LOG_INFO("rssi:%d\r\n",p_ble_msg->msg.p_gapc_rssi->rssi); //打印rssi break; default: break; } }
1.20、ns_ble_disconnect
功能:主机或从机主动发起蓝牙BLE断开连接请求。成功断开连接会通过蓝牙事件回调函数的APP_BLE_GAP_DISCONNECTED消息返回。
语法:void ns_ble_disconnect(void);
参数:无
返回值:无
使用示例:
ns_ble_disconnect();
1.21、 ns_ble_dle_set
功能:主机或从机请求设置DLE参数。如需变更,建议使用示例代码的参数。
语法:void ns_ble_dle_set(uint16_t tx_octets, uint16_t tx_time);
参数:[in] tx_octets:单个链路数据通道PDU的最大数据量。[in] tx_time:单个链路数据通道PDU的发送时间最大微秒数。
返回值:无
使用示例:
ns_ble_dle_set(251, 2120);
1.22、rf_tx_power_set
功能:主机或从机设置射频信号发射功率;
语法:void rf_tx_power_set(rf_tx_power_t pwr);
参数:[in] pwr:设置的射频信号发射功率,可选参数如下结构体定义,
typedef enum
{ TX_POWER_0_DBM = 0, /* 0 dBm */ TX_POWER_Neg2_DBM, /* -2 dBm */ TX_POWER_Neg4_DBM, /* -4 dBm */ TX_POWER_Neg8_DBM, /* -8 dBm */ TX_POWER_Neg15_DBM, /* -12 dBm */ TX_POWER_Neg20_DBM, /* -20 dBm */ TX_POWER_Pos2_DBM, /* +2 dBm */ TX_POWER_Pos3_DBM, /* +3 dBm */ TX_POWER_Pos4_DBM, /* +4 dBm */ TX_POWER_Pos6_DBM, /* +6 dBm */ }rf_tx_power_t; 返回值:无
使用示例:
rf_tx_power_set(TX_POWER_Pos4_DBM);
二、安全加密模块 2.1、ns_sec_init
功能:初始化蓝牙安全加密模块。
语法:void ns_sec_init(struct ns_sec_init_t const* init);
参数:[in] init:蓝牙安全模块初始化参数结构体指针。详情参考结构体ns_sec_init_t内部定义。
返回:无
使用示例:
struct ns_sec_init_t sec_init={0}; sec_init.rand_pin_enable = false; sec_init.pin_code = 123456; sec_init.pairing_feat.auth = ( SEC_PARAM_BOND | (SEC_PARAM_MITM<<2) | (SEC_PARAM_LESC<3) | (SEC_PARAM_KEYPRESS<<4) ); sec_init.pairing_feat.iocap = SEC_PARAM_IO_CAPABILITIES; sec_init.pairing_feat.key_size = SEC_PARAM_KEY_SIZE; sec_init.pairing_feat.oob = SEC_PARAM_OOB; sec_init.pairing_feat.ikey_dist = SEC_PARAM_IKEY; sec_init.pairing_feat.rkey_dist = SEC_PARAM_RKEY; sec_init.pairing_feat.sec_req = SEC_PARAM_SEC_MODE_LEVEL; sec_init.bond_enable= BOND_STORE_ENABLE; sec_init.bond_db_addr = BOND_DATA_BASE_ADDR; sec_init.bond_max_peer = MAX_BOND_PEER; sec_init.bond_sync_delay = 5000; sec_init.ns_sec_msg_handler = NULL; ns_sec_init(&sec_init);
2.2、ns_sec_get_bond_status
功能:返回是否已绑定了的状态。
语法:bool ns_sec_get_bond_status(void);
参数:无
返回:ture:已绑定。false:未绑定。
示例:
bool bond_status = ns_sec_get_bond_status();
2.3、ns_sec_get_iocap
功能:返回设备的接口能力参数,供蓝牙相关库调用,一般用户代码不需要调用。
语法:uint8_t ns_sec_get_iocap(void);
参数:无
返回:设备的接口能力参数,是函数ns_sec_init初始化设置进去的值。
示例:
uint8_t io_cap = ns_sec_get_iocap();
2.4、ns_sec_bond_db_erase_all
功能:擦除所有已绑定的设备。因为擦除flash会阻塞运行,建议不要在已连接状态下执行,必须影响连接的可能性。
语法:void ns_sec_bond_db_erase_all(void);
参数:无
返回:无
示例:
ns_sec_bond_db_erase_all();
三、软件定时器 3.1、ns_timer_create
功能:创建一个软件定时器,在延迟delay毫秒数后调用fn这个函数。如需循环定时器可以在回调处理处再次创建 一个定时器。注意需要在协议栈初始化好后,即APP_BLE_OS_READY消息发出之后才能使用该API函数。 语法:timer_hnd_t ns_timer_create(const uint32_t delay, timer_callback_t fn);
参数:delay:延迟的时间,单位是1毫秒。
fn:延迟delay毫秒后的回调函数。
返回值:定时器的id
示例:timer_hnd_t timer_id = ns_timer_create(1000,my_timer_callback);
3.2、ns_timer_modify
功能:修改指定一个定时器的延时时间
语法:timer_hnd_t ns_timer_modify(const timer_hnd_t timer_id,const uint32_t delay);
参数:timer_id:需要修改的定时器id
delay:修改后的延迟时间,单位为1毫秒
返回值:修改后的定时器id
示例:timer_id= ns_timer_modify(timer_id,2000);
3.3、ns_timer_cancel
功能:取消指定的一个定时器
语法:void ns_timer_cancel(const timer_hnd_t timer_id);
参数:timer_id:需要取消的定时器id
返回值:无
示例:ns_timer_cancel(timer_id);
3.4、ns_timer_cancel_all
功能:取消所有已经创建的定时器
语法:void ns_timer_cancel_all(void);
参数:无
返回值:无
示例:ns_timer_cancel_all();
四、蓝牙睡眠模块 4.1、ns_sleep 功能:蓝牙睡眠功能进入函数,函数会基于蓝牙协议栈工作状态,如果没有需要执行的任务则自动进入睡眠状态, 在定时任务或者硬件中断唤醒后恢复系统状态。一般调用于main函数主循环,调度函数rwip_schedule后面。 语法:void ns_sleep(void); 参数:无
返回值:无
示例:ns_sleep();
4.2、ns_sleep_lock_acquire 功能:蓝牙睡眠模式锁请求,即申请系统不进入睡眠模式。比如开启某些高速外设(如串口)不希望系统进入睡眠而关掉 它,可以通过请求睡眠模式锁禁止系统进入睡眠。 语法:uint8_t ns_sleep_lock_acquire(void); 参数:无
返回值:true:请求锁成功。false:请求锁失败。
示例:
if(ns_sleep_lock_acquire()) { //require sleep lock success }
4.3、ns_sleep_lock_release 功能:蓝牙睡眠模式锁释放,当所有的睡眠模式锁释放后,系统可以在没有任务挂起时将进入睡眠模式。 语法:uint8_t ns_sleep_lock_release(void); 参数:无
返回值:true:释放锁成功。false:释放锁失败,目前没有可以释放的锁。
示例:
if(ns_sleep_lock_release()) { //release sleep lock success }
4.4、进入和退出睡眠模式的虚函数 __weak void app_sleep_prepare_proc(void); 功能:预设的虚函数,用于给用户重新实现进入睡眠之前需要做任务。 __weak void app_sleep_resume_proc(void) 功能:用于给用户重新实现睡眠唤醒之后需要做任务,比如可以重新初始化因为睡眠关闭的硬件外设,例如使能GPIO的时钟。
五、硬件延迟模块 5.1、delay_cycles
功能:延迟等待指定数量的cycles返回; 语法:void delay_cycles(uint32_t ui32Cycles);
参数:ui32Cycles:需要等待的cycles数量,一个cycles的时间约为(10/110) 微秒;
返回:无
示例:delay_cycles(1000);
5.2、delay_n_us
功能:延迟等待指定数量的微秒
语法:void delay_n_us(uint32_t val);
参数:val:需要等待的微秒数;
返回:无
示例:delay_n_us(1000);
5.3、delay_n_10us
功能:延迟等待指定数量的10微秒
语法:void delay_n_10us(uint32_t val);
参数:val:需要等待的10微秒数;
返回:无
示例:delay_n_10us(1000);
5.4、delay_n_100us
功能:延迟等待指定数量的100微秒
语法:void delay_n_100us(uint32_t val);
参数:val:需要等待的100微秒数
返回:无
示例:delay_n_100us(1000);
5.5、delay_n_ms
功能:延迟等待指定数量的毫秒
语法:void delay_n_ms(uint32_t val);
参数:val:需要等待的毫秒数
返回:无
示例:delay_n_ms(1000);
六、蓝牙程序编程建议 6.1、不要连续执行占用时间太长的代码,将会阻碍蓝牙消息处理。建议尽可实现用户代码粹片化,每个任
务消息或轮询只占用小片时间。
6.2、不要在中断服务函数执行太长时间,避免阻碍蓝牙消息处理,建议通过挂起消息,定时器或者标志位
的方式在任务或轮询里实现逻辑代码。
6.3、不要在中断服务函数调用硬件外设。睡眠后如果中断事件挂起,中断
服务函数将会在app_sleep_resume_proc之前调用,外设在唤醒后还没初始化,如在中断服务函
数调用硬件外设,则会因为外设未初始化而导致出错。
6.4、包含蓝牙的工程中断服务函数注意需要通过ModuleIrqRegister函数注册,并且用户代码的中断优先级
只能使用2和3(蓝牙协议栈使用0和1)。
6.5、注意进入低功耗sleep模式下,高速外设(如USART)将被关闭,需要在唤醒后程序初始化才能使用。
6.6、用户的逻辑代码推荐在任务回调函数里面实现,可以是消息事件回调或者定时任务回调。
|