nRF52832 作为一个低功耗蓝牙芯片,其数据发送发送速率一直都偏低(高就不叫低功耗了^_^),作为初学者在网上找了很多资料,终于找到通过修改ATT_MTU来提升发送速率的方法,最快能达到8.2KB/s,现在就分享出来
首先我用的协议栈是 nRF5_SDK_14.2.0 ,将\examples\ble_peripheral中的 ble_app_template 作为模板,以此进行修改
废话不说,先上代码,首先是定义
#define TIMER_INTERVAL APP_TIMER_TICKS(29) //定时器时间间隔
1 BLE_NUS_DEF(m_nus); //加入串口服务结构(修改) 2 BLE_CMD_DEF(m_cmd); //加入命令服务结构 3 APP_TIMER_DEF(m_timer1); //定时器1 4 5 uint8_t hr_data[250]; 6 uint8_t cmd_data; //接收的命令 7 bool send_state = false; //发送状态,默认不发送 8 9 static uint16_t length = 244;
主函数基本没修改,主要初始化了一组数据用来测试发送,加入了调度器,因为使用的定时器定时进行发送,而蓝牙发送不好放在中断里进行,定时器中断就做一个接发送函数放入调度器的操作。定义了一个全局数组,用来存放发送的数据。
1 int main(void) 2 { 3 bool erase_bonds; 4 5 // Initialize. 6 log_init(); 7 timers_init(); 8 buttons_leds_init(&erase_bonds); 9 ble_stack_init(); 10 gap_params_init(); 11 gatt_init(); 12 advertising_init(); 13 services_init(); 14 conn_params_init(); 15 peer_manager_init(); 16 17 // Start execution. 18 NRF_LOG_INFO("Template example started."); 19 20 advertising_start(erase_bonds); 21 22 for(uint8_t i=0;i<250;i++) hr_data[i]=i; //初始化数据包 23 SEGGER_RTT_printf(0, "\n");// 此处打印信息 24 25 APP_SCHED_INIT(20, 2); //初始化调度器 26 27 // Enter main loop. 28 for (;;) 29 { 30 app_sched_execute(); //调度 31 32 if (NRF_LOG_PROCESS() == false) 33 { 34 power_manage(); 35 } 36 } 37 }
先看定时器
1 static void timers_init(void) 2 { 3 // Initialize timer module. 4 uint32_t err_code = app_timer_init(); 5 APP_ERROR_CHECK(err_code); 6 7 err_code = app_timer_create(&m_timer1, APP_TIMER_MODE_REPEATED, timer_timeout_handler); 8 APP_ERROR_CHECK(err_code); 9 }
定时器中断服务函数
1 void timer_timeout_handler(void * p_context) 2 { 3 if ( send_state == true ) 4 { 5 hr_data[0]++; 6 if(hr_data[0]>255) hr_data[0]=0; //改变第一个字节 7 app_sched_event_put(NULL, 0, ble_nus_send); // 加入调度 8 } 9 }
蓝牙发送函数
1 void ble_nus_send(void) 2 { 3 uint32_t err_code; 4 do 5 { 6 err_code = ble_nus_string_send(&m_nus, hr_data, &length); 7 if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) ) 8 { 9 APP_ERROR_CHECK(err_code); 10 } 11 } while (err_code == NRF_ERROR_BUSY); 12 }
接下来是蓝牙服务,这里我使用了两个自定义的服务,因为之前测试发送同一个串口服务进行收发的话,在连续接收数据时候,发送的命令会被堵塞,所以索性改了两个服务,分别用来收发,不知道大家有碰到过这种情况没,有的话欢迎一起交流交流。
1 static void services_init(void) 2 { 3 uint32_t err_code; 4 ble_nus_init_t nus_init; 5 ble_cmd_init_t cmd_init; 6 7 /* 初始化串口服务 */ 8 memset(&nus_init, 0, sizeof(nus_init)); 9 err_code = ble_nus_init(&m_nus, &nus_init); 10 APP_ERROR_CHECK(err_code); 11 12 /* 初始化自定义命令服务 */ 13 memset(&cmd_init, 0, sizeof(cmd_init)); 14 cmd_init.data_handler = cmd_data_handler; //命令处理函数 15 err_code = ble_cmd_init(&m_cmd, &cmd_init); 16 APP_ERROR_CHECK(err_code); 17 }
命令数据处理函数,定义了一个全局变量,用来指示发送状态,根据接收的命令修改状态,以及开关定时器。
1 static void cmd_data_handler(ble_cmd_evt_t * p_evt) 2 { 3 ret_code_t err_code; 4 SEGGER_RTT_printf(0, "Receive a command\n");// 此处打印信息 5 cmd_data = p_evt->params.rx_data.p_data[0]; //接收1个字节作为命令 6 7 switch ( cmd_data ) 8 { 9 case BLE_STOP_CMD : 10 send_state = false; //停止发送 11 err_cod