Nordic nRF51822开发入门

3 篇文章 0 订阅

1        开发环境搭建

1.1  软件安装

1.        Keil软件安装;

2.        Jlink驱动安装;

3.        nRFgoStdio安装,该软件用来烧写蓝牙协议栈和应用软件。第二步安装了Jlink驱动后,不要安装nRFgo里自带的Jlink驱动。

4.        安装nRF51SDK,安装完成后,在Keil的目录里有51822的相关的例程和源码。

 

1.2  本例安装的软件版本

Windows: win7 64bit

Keil:V5.13.0.0 (mdk_513.exe)

Jlink:V4.96d (Setup_JLink_V496d.exe)

nRFgoStdio:V1.17.1 (nrfgostudio_win-64_1.17.1_installer.msi)

nRF51SDK: V6.1.0(nrf51_sdk_v6_1_0_b2ec2e6.msi)

SoftDevice:V7.1.0 (s110_nrf51822_7.1.0.zip)

1.3  遇到的问题

开发环境,包括软件环境以及硬件环境可以参考官方的User Guide 文档。期间遇到的问题有两个:

1.      nRFgoStdio无法识别nRF6310 MotherBoard?

在这里没有解决这个问题,对我的开发工作影响不大,我们的开发工作只需要更新ble stack和应用层APP即可,大部分时候只需要烧录app即可。

2.      keil打开.uvproj后缀名的工程,无法编译?

安装的最新的keil版本以及SDK需要打开.uvprojx后缀名的工程,则编译无错误。

3.      通过nRFgo烧写SoftDevice 和 ble_app_hrs无法工作?

这里存在nRF51SDK与SoftDevice和app的兼容性问题,本机安装了SDK的6版本,在Nordic官网SoftDevice有5,6,7三个版本,逐一尝试后,最新的版本7和app兼容,能正常工作。

4.      在调试期间可能遇到VTG灯变红、异常闪烁或不亮,nRFgo 和keil无法烧写?

如果是电池供电的话,则很可能是电池没电。检测电池的电压才1v,新电池1.6v左右。更换电池解决问题。

 

不能解决的问题,可以在Nordic官网论坛提问,会有Nordic的员工为你解答。

https://devzone.nordicsemi.com/questions/

2        串口UART

为了更好的结合串口打印信息,来分析代码的流程。故结合6310里的uart_example例程,来调试UART功能,并将该初始化函数移植到要分析的例程去。

 

在uart_exam ple的simple_uart_config函数中,对uart指定输出输入引脚,关键是找到6310板子上的该两个引脚的位置。因为没有6310的原理图,经过查阅了很多资料,终于找到这两个引脚,分别是P9 端口的,p2.0与p2.1,连接到电脑的USB串口线并另一个接地,在电脑端配置好相应的串口参数,则解决问题。

 

图表1 硬件连接

 

图表2 串口配置

 

nrf的SDK中已经实现了UART相关的初始化以及日志打印函数,详见“app_trace.h”文件。故在工程里include app_trace.h文件,并在工程的Target中添加宏“ENABLE_DEBUG_LOG_SUPPORT” 即可打印日志信息。

图表3 宏定义

app_trace.h中定义的几个函数:

Ø  void app_trace_init(void); // UART初始化函数,打印日志前必须先调用该函数

Ø  #define app_trace_log printf  // 日志打印,类似printf用法

Ø  void app_trace_dump(uint8_t * p_buffer,uint32_t len);  // 以十六进制的方式打印一段内存信息

 

3        hrs服务分析

3.1  流程图

图表4  BLE事件处理过程

1.      系统初始化,包括以下几个部分:

int main(void)

{

 

    // Initialize.

   leds_init();                 // 初始化led灯,设置led0,led1,led7为输出模式

   buttons_init();  // 初始化两个按钮button0 button1 为下拉输入模式,用来wakeup系统

   timers_init();     // 创建4个定时器,执行定时任务

   ble_stack_init();    //初始化和 使能协议栈,并注册事件处理函数

   device_manager_init();  // 用于已绑定的蓝牙设备管理,以及GAP层的一些安全参数设置

   gap_params_init();   // gap 层参数初始化,用于建立和管理连接

   advertising_init();     // 广播数据初始化

   services_init();           // 服务初始化,提供hrs、bas、dis三个服务

   sensor_sim_init();     // 传感器模拟器初始化

   conn_params_init(); // 连接参数初始化

 

    //Start execution.

   application_timers_start(); //启动定时器,battery 2s  heart rate 1s

   advertising_start();  // 开始广播,并设置

 

    //Enter main loop.

    for(;;)

    {

       power_manage();  // 监听蓝牙事件

    }

}

3.2  关键函数分析

1.        timers_init();

该函数首先初始化定时器模块,然后创建了4个定时器,分别是为两个个service定时发送数据的。

Ø  定时每隔2s 从电池模拟器中读取数据,并使用蓝牙协议栈发送出去。

Ø  定时每隔1s从心率模拟器中读取数据,并使用蓝牙协议栈发送出去。

 

2.        ble_stack_init()

该函数主要初始化蓝牙协议栈并注册事件处理handler.

err_code =softdevice_ble_evt_handler_set(ble_evt_dispatch);

err_code =softdevice_sys_evt_handler_set(sys_evt_dispatch);

注册两种事件处理函数,一个是ble,另一个是sys。当BLE协议栈有event发生时,就会进入ble_evt_dispatch,当有系统event发生时则进入sys_evt_dispatch。我们这里只关注ble。

Ø  ble_evt_dispatch函数

static void ble_evt_dispatch(ble_evt_t *p_ble_evt)

{

   dm_ble_evt_handler(p_ble_evt);  //device manager 事件处理函数

   ble_hrs_on_ble_evt(&m_hrs, p_ble_evt); // hrs service  event处理函数

    ble_bas_on_ble_evt(&m_bas,p_ble_evt);// battery service event 处理函数

   ble_conn_params_on_ble_evt(p_ble_evt); // 连接管理相关event处理函数,这里连接相关的事件也会在以上的服务event handler中出现

#ifdef BLE_DFU_APP_SUPPORT   

    /**@snippet [Propagating BLE Stack events to DFU Service] */

   ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);

    /**@snippet [Propagating BLE Stack events to DFU Service] */

#endif // BLE_DFU_APP_SUPPORT   

   on_ble_evt(p_ble_evt);  // 自定义的处理函数,包括亮灯灭灯等与开发板有关的操作。

}

Ø  on_ble_evt函数

该函数做了三件事情:

1 当建立连接时,点亮led1,熄灭led0;

2 当断开连接时,熄灭led1,并重新开始广播,在广播函数中会点亮led0;

3 当广播超时,会熄灭led0,并进入system-off模式,按下按键Button0或者Button1会wakeup系统,并重新开始初始化

 

3.        advertising_init()

该函数进行广播数据的一些初始化工作,包括需要广播的UUID、需要广播的自定义数据以及广播类型等其他的参数设置。

 

4.        services_init()

该函数执行服务初始化,包括三个服务,bas(电池)、hrs(心率)以及dis(设备信息)。

一个service又包含多个characteristic(特征值),每个characteristic可以拥有不同的读写权限。

5.        gap_params_init函数

该函数主要初始化gap层连接的参数。

static void gap_params_init(void)

{

   uint32_t                err_code;

   ble_gap_conn_params_t  gap_conn_params;

   ble_gap_conn_sec_mode_t sec_mode;

   BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

   err_code = sd_ble_gap_device_name_set(&sec_mode,

                                         (const uint8_t *)DEVICE_NAME,

                                         strlen(DEVICE_NAME));

   APP_ERROR_CHECK(err_code);

   err_code =sd_ble_gap_appearance_set(BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT);

   APP_ERROR_CHECK(err_code);

   memset(&gap_conn_params, 0, sizeof(gap_conn_params));

 

   gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; // 0.5sec 连接间隔时间,指定一个最大值和最小值,以供Master 建立连接

   gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;// 1sec ,连接间隔时间,1.25毫秒的倍数,7.5ms~4s之间

   gap_conn_params.slave_latency    = SLAVE_LATENCY;// 从机潜伏,允许设备跳过的最大连接次数,为0,能快速收到Master发送过来的数据

   gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;// 监督超时时间,超时没有收到数据则认为连接断开

   err_code = sd_ble_gap_ppcp_set(&gap_conn_params);

   APP_ERROR_CHECK(err_code);

}

 

6.        application_timers_start();

启动定时器,battery服务每 2s发送一次数据,  heart rate 服务每1s发送一次数据。

 

 转载请保留出处:http://blog.csdn.net/onetwothreef/article/details/43835059

水平有限,如有错误,欢迎拍砖~

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值