• NRF51822自学笔记(三)心率计


    依旧是官方给的例程恩……

    int main(void)
    {
    	
        uint32_t err_code;
    
        timers_init();
        gpiote_init();
        buttons_init();
        ble_stack_init();
        device_manager_init();
    
        // Initialize Bluetooth Stack parameters.
        gap_params_init();//初始化gap层连接
        advertising_init();
        services_init();
        conn_params_init();
    	
    
        // Start advertising.
        advertising_start();//启动定时器,battery每2S发送一次数据,heart rate每1S发送一次数据
    
        // Enter main loop.
        for (;;)
        {
            // Switch to a low power state until an event is available for the application
            err_code = sd_app_evt_wait();
            APP_ERROR_CHECK(err_code);
        }
    }

    先初始化,初始化了定时器,GPIO TASK&EVENT,按钮(pin16和pin17)BLE stack,device manager,gap层连接,广播,services,和conn params(相关参数)

    为啥battery每2s发送一次数据,heart rate每1s发送一次数据-。-在后面有解释

    来看看初始化BLE stack的函数

    static void ble_stack_init(void)
    {
        uint32_t err_code;
        
        // Initialize the SoftDevice handler module.
        SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
    
        // Enable BLE stack 
        ble_enable_params_t ble_enable_params;
        memset(&ble_enable_params, 0, sizeof(ble_enable_params));
        ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
        err_code = sd_ble_enable(&ble_enable_params);
        APP_ERROR_CHECK(err_code);
    
        // Register with the SoftDevice handler module for BLE events.
        err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);//若event发生,进入ble_evt_dispatch
        APP_ERROR_CHECK(err_code);
        
        // Register with the SoftDevice handler module for BLE system events.
        err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);//若system event,进入sys_evt_dispatch
        APP_ERROR_CHECK(err_code);
    }
    若event发生,则进入ble_evt_dispatch(),追踪一下
    static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    {
        dm_ble_evt_handler(p_ble_evt);//事件处理函数
        ble_hrs_on_ble_evt(&m_hrs, p_ble_evt);//hrs service event处理函数
        ble_bas_on_ble_evt(&bas, p_ble_evt);//bas service event处理函数
        ble_conn_params_on_ble_evt(p_ble_evt);//连接相关event处理函数
        on_ble_evt(p_ble_evt);//自定义函数(亮灯灭灯等)
    }
    追踪一下on_ble_evt()

    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t        err_code;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                led_stop();
                
                // Initialize the current heart rate to the average of max and min values. So that
                // everytime a new connection is made, the heart rate starts from the same value.
                m_cur_heart_rate = (MAX_HEART_RATE + MIN_HEART_RATE) / 2;
    
                // Start timers used to generate battery and HR measurements.
                application_timers_start();
    
                // Start handling button presses
                err_code = app_button_enable();
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:            
                // @note Flash access may not be complete on return of this API. System attributes are now
                // stored to flash when they are updated to ensure flash access on disconnect does not
                // result in system powering off before data was successfully written.
    
                // Go to system-off mode, should not return from this function, wakeup will trigger
                // a reset.
                system_off_mode_enter();
                break;
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT)
                {
                    led_stop();
                    
                    nrf_gpio_cfg_sense_input(HR_INC_BUTTON_PIN_NO,
                                             BUTTON_PULL, 
                                             NRF_GPIO_PIN_SENSE_LOW);
    
                    nrf_gpio_cfg_sense_input(HR_DEC_BUTTON_PIN_NO,
                                             BUTTON_PULL, 
                                             NRF_GPIO_PIN_SENSE_LOW);
    
                    system_off_mode_enter();
                }
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    1.这个函数用了个switch语句,判断条件的定义可以在ble_gap.h中找到

    enum BLE_GAP_EVTS
    {
      BLE_GAP_EVT_CONNECTED  = BLE_GAP_EVT_BASE,    /**< Connection established. */
      BLE_GAP_EVT_DISCONNECTED,                     /**< Disconnected from peer. */
      BLE_GAP_EVT_CONN_PARAM_UPDATE,                /**< Connection Parameters updated. */
      BLE_GAP_EVT_SEC_PARAMS_REQUEST,               /**< Request to provide security parameters. */
      BLE_GAP_EVT_SEC_INFO_REQUEST,                 /**< Request to provide security information. */
      BLE_GAP_EVT_PASSKEY_DISPLAY,                  /**< Request to display a passkey to the user. */
      BLE_GAP_EVT_AUTH_KEY_REQUEST,                 /**< Request to provide an authentication key. */
      BLE_GAP_EVT_AUTH_STATUS,                      /**< Authentication procedure completed with status. */
      BLE_GAP_EVT_CONN_SEC_UPDATE,                  /**< Connection security updated. */
      BLE_GAP_EVT_TIMEOUT,                          /**< Timeout expired. */
      BLE_GAP_EVT_RSSI_CHANGED,                     /**< Signal strength measurement report. */
    };
    又是一堆枚举常量= =……

    2.这个函数设置了心率的一个初始值(毕竟没装传感器,要用某些手段来试一下)

       m_cur_heart_rate = (MAX_HEART_RATE + MIN_HEART_RATE) / 2; 追踪一下宏定义发现最小值60最大值300……恩……

    3.这个函数调用application_timers_start(),使刚才创建的两个timer运行。

    static void application_timers_start(void)
    {
        uint32_t err_code;
    
        // Start application timers
        err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);
    
        err_code = app_timer_start(m_heart_rate_timer_id, HEART_RATE_MEAS_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);
    }

      0-0这就解释了一下刚才遗留的问题……为什么发送数据battery是2s一次,heart rate是1s一次。追踪一下app_timer_start()中的参数XXX_XXX_MEAS_INTERVAL

    #define BATTERY_LEVEL_MEAS_INTERVAL          APP_TIMER_TICKS(2000, APP_TIMER_PRESCALER) /**< Battery level measurement interval (ticks). */
    
    #define HEART_RATE_MEAS_INTERVAL             APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER) /**< Heart rate measurement interval (ticks). */

    追踪一下APP_TIMER_TICKS(),追踪到了app_timer.h里

    #define APP_TIMER_TICKS(MS, PRESCALER)
                ((uint32_t)ROUNDED_DIV((MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, ((PRESCALER) + 1) * 1000))
    第一个参数是ms,第二个宏定义 =0 。so0-0问题解决

    然后看看初始化按键这个函数

    static void buttons_init(void)
    {
        // Configure HR_INC_BUTTON_PIN_NO and HR_DEC_BUTTON_PIN_NO as wake up buttons and also configure
        // for 'pull up' because the eval board does not have external pull up resistors connected to
        // the buttons.
        static app_button_cfg_t buttons[] =
        {
            {HR_INC_BUTTON_PIN_NO, false, BUTTON_PULL, button_event_handler},
            {HR_DEC_BUTTON_PIN_NO, false, BUTTON_PULL, 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);
    }
    注释写的挺清楚……追踪一下button_event_handler()

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
        if (button_action == APP_BUTTON_PUSH)
        {
            switch (pin_no)
            {
                case HR_INC_BUTTON_PIN_NO://pin16
                    // Increase Heart Rate measurement
                    m_cur_heart_rate += HEART_RATE_CHANGE;
                    if (m_cur_heart_rate > MAX_HEART_RATE)
                    {
                        m_cur_heart_rate = MIN_HEART_RATE; // Loop back
                    }
                    break;
                    
                case HR_DEC_BUTTON_PIN_NO://pin17
                    // Decrease Heart Rate measurement
                    m_cur_heart_rate -= HEART_RATE_CHANGE;
                    if (m_cur_heart_rate < MIN_HEART_RATE)
                    {
                        m_cur_heart_rate = MAX_HEART_RATE; // Loop back
                    }
                    break;
                    
                default:
                    APP_ERROR_HANDLER(pin_no);
                    break;
            }
        }    
    }
    一个长且直观的按键扫描,switch判断哪个按键被按下,然后进行当前心率的加减。

    通过蓝牙广播1s发送一次数据,在手机端app上显示出来(像一个迟缓的示波器= =)。



  • 相关阅读:
    Java static keyword
    Final Keyword In Java
    Underscore template
    Query.extend() 函数详解-转载
    js闭包for循环总是只执行最后一个值得解决方法
    mui scroll和上拉加载/下拉刷新
    mui 手势事件配置
    118. 杨辉三角
    [ 周赛总结 ] 第 185 场力扣周赛
    55. 跳跃游戏
  • 原文地址:https://www.cnblogs.com/ldgforever/p/5854106.html
Copyright © 2020-2023  润新知