文章目录

  • 一、nRF51822芯片介绍
  • 二、Keil环境搭建
    • 1、下载软件包
    • 2、选择设备
    • 3、配置JLINK
  • 三、nRFgo的下载
  • 四、蓝牙协议栈
    • (一)、S110
    • (二)、S120
    • (三)、S130
  • 五、串口透传例程
    • (一)、应用程序定时器(心跳)初始化
    • (二)、串口初始化
    • (三)、flash初始化
    • (四)、定时器初始化
    • (五)、蓝牙协议栈初始化
    • (六)、GAP参数初始化
    • (七)、服务初始化
    • (八)、GAP广播初始化
    • (九)、蓝牙连接参数初始化
    • (十)、开启广播
    • (十一)、低功耗模式

一、nRF51822芯片介绍

低功耗蓝牙和2.4 GHz SoC。nRF51822是一款通用的超低功耗SoC,非常适合Bluetooth®低功耗和2.4 GHz专有无线应用。它基于具有256/128KB闪存和32/16KB RAM32位ARM®Cortex™-M0CPU构建。灵活的2.4 GHz无线电支持蓝牙低功耗和2.4 GHz专有协议,例如Gazell。它集成了丰富的模拟和数字外设,可以通过可编程外设互连(PPI)系统直接进行交互,而无需CPU干预。灵活的GPIO使您可以将SPI主/从,TWI主和UART等数字接口连接到设备上的31个GPIO中的任何一个

资源:

  • 16 MHz Cortex-M0
  • 256/128 KB闪存,32/ 16 KB RAM
  • 2.4 GHz收发器
  • 2Mbps,1 Mbps,250 kbps
  • 蓝牙低功耗+4 dBm TX功率
  • 128位AES CCM
  • UART,SPI,TWI
  • 10位ADC

其他资料如下:

产品介绍

产品规格书

二、Keil环境搭建

1、下载软件包

也可以下载下面的SDK进行软件包的下载,但是我下载不了就用这个方法了。

nRF5 SDK

2、选择设备

3、配置JLINK


三、nRFgo的下载

nRFgo用于设备的烧录,当然也可以直接用jlink把协议栈、应用程序和bootloader烧录进去,但官方软件相对来说更加专业和好用。

nRFgo Studio下载链接

打开的烧录页面如下:


烧录的地址顺序为:

四、蓝牙协议栈

关于蓝牙协议的文章

协议栈的文档和下载地址:
蓝牙外围协议栈S110
蓝牙外围协议栈S120
蓝牙外围协议栈S130

官方SoftDevice(协议栈)说明文档

下面说明几个协议栈的适用方向:

(一)、S110

S110是用于nRF51系列的Bluetooth 4.1认证的外围协议栈。

  • 作为外围设备和广播器的并发链接
  • 可配置的ATT表
  • 隐私协议 1.1
  • 安全模式1 - 1、2和3级
  • 支持自定义UUID
  • 支持具有 2.4GHz专有协议的并发多重协议

简单来说就是S110是针对外围设备(终端节点)的协议栈,也就是说只能广播,不能扫描,用于从设备。

不同版本的协议栈所占用的大小不用,如当前最新版本s110_nrf51_8.0.0为例(数据来自于官方文档),Application项目部分ROM和RAM起始地址设置如下:

具体所需内存的值还要根据你所选择的功能决定,上图所示值仅仅是默认值,下面的协议栈同理。

(二)、S120


S120是用于nRF51系列的Bluetooth 4.1认证的中央或外围协议栈。

  • 作为充当观察者的中心设备或者充当广播员的外设的8个并发链接
  • 可配置的ATT表
  • 隐私协议1.1
  • 安全模式1 - 1、2和3级
  • 支持自定义UUID
  • 支持具有 2.4GHz专有协议的并发多重协议

简单来说就是S120是针对中心设备的协议栈,就是说可以扫描,用于主设备。

当前最新版本s120_nrf51_2.1.0所占大小为:

(三)、S130

S130是nRF51系列的蓝牙4.2认证的中央和外围协议栈

  • 作为中心设备的观察者和外围设备的广播员的8个并发链接
  • 可配置的ATT表
  • 隐私协议1.1
  • 安全模式1 - 1、2、3和4级
  • 支持自定义UUID
  • 支持具有 2.4GHz的专有协议的并发多重协议
  • LE安全连接

S130即可作为主设备,又可作为从设备。

当前最新版本s130_nrf51_2.0.1所占大小为:

五、串口透传例程

该程序可以通过下载nRF_SDK下载、nRF_SDK说明文档来获取,下载不了的话可以采用科学上网工具。

下面我大概说一下配置的地方。

(一)、应用程序定时器(心跳)初始化

该函数原型为APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE, SCHEDULER_FUNC) 。
它是一个宏定义,用于定义RTC1定时器的预分频值PRESCALER、持有挂起执行的计时器操作的队列的大小OP_QUEUES_SIZE和是否开启指向调度程序事件处理程序的指针。

#define APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE, SCHEDULER_FUNC)                                  \do                                                                                             \{                                                                                              \static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((OP_QUEUES_SIZE) + 1),           \sizeof(uint32_t))];                                 \uint32_t ERR_CODE = app_timer_init((PRESCALER),                                            \(OP_QUEUES_SIZE) + 1,                                   \APP_TIMER_BUF,                                          \SCHEDULER_FUNC);                                        \APP_ERROR_CHECK(ERR_CODE);                                                                 \} while (0)

(二)、串口初始化

该函数用于设置UART的引脚和波特率等配置,同时初始化UART_FIFO的接收和发送缓冲区大小,另外还有事件句柄的定义,其中包括以下几种:

/**@brief Enumeration which defines events used by the UART module upon data reception or error.** @details The event type is used to indicate the type of additional information in the event* @ref app_uart_evt_t.*/
typedef enum
{APP_UART_DATA_READY,          /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */APP_UART_FIFO_ERROR,          /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */APP_UART_TX_EMPTY,            /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */APP_UART_DATA,                /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
} app_uart_evt_type_t;

我们主要用数据已接收事件APP_UART_DATA_READY、FIFO错误事件APP_UART_FIFO_ERROR和通信错误事件APP_UART_COMMUNICATION_ERROR。第一个事件采用app_uart_get函数来获取FIFO中的数据,其他两个采用APP_ERROR_HANDLER函数进行错误处理。

它的配置结构体如下:

/**@brief UART communication structure holding configuration settings for the peripheral.*/
typedef struct
{uint8_t                 rx_pin_no;    /**< RX pin number. */uint8_t                 tx_pin_no;    /**< TX pin number. */uint8_t                 rts_pin_no;   /**< RTS pin number, only used if flow control is enabled. */uint8_t                 cts_pin_no;   /**< CTS pin number, only used if flow control is enabled. */app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */bool                    use_parity;   /**< Even parity if TRUE, no parity if FALSE. */uint32_t                baud_rate;    /**< Baud rate configuration. */
} app_uart_comm_params_t;

另外串口数据的读写采用环形缓冲区,不懂的小伙伴可以自行百度一下,它的结构体定义如下,用起来还是挺方便的。^^

typedef struct
{int         size;   /* maximum number of elements           */int         start;  /* index of oldest element              */int         end;    /* index at which to write new element  */int         count;unsigned char   *elems;  /* vector of elements                   */
} CircularBuffer;

(三)、flash初始化

该函数pstorage_init主要用于存储和读出蓝牙名字。他的初始化结构体如下:

/**@brief Persistent storage operation completion callback function type.** @details The persistent storage operation completion callback is used by the interface to report*          success or failure of a flash operation. Since data is not copied for a store operation, *          a callback is an indication that the resident memory can now be reused or freed.* * @param[in] handle   Identifies the module and block for the callback that is received.* @param[in] op_code  Identifies the operation for the event that is notified.* @param[in] result   Identifies the result of a flash access operation. NRF_SUCCESS implies *                     operation succeeded.**                     @note Unmanaged (abnormal behaviour) error codes from the SoftDevice flash *                     access API are forwarded as is and are expected to be handled by the *                     application. For details refer to the implementation file and corresponding *                     SoftDevice flash API documentation.*                     * @param[in] p_data   Identifies the application data pointer. For a store operation, this points *                     to the resident source of application memory that the application can now *                     free or reuse. When there is a clear operation, this is NULL since no *                     application pointer is needed for this operation.* @param[in] data_len Length data the application provided for the operation. */
typedef void (*pstorage_ntf_cb_t)(pstorage_handle_t * p_handle,uint8_t             op_code,uint32_t            result,uint8_t *           p_data,uint32_t            data_len);/**@brief Struct containing module registration context. */
typedef struct
{pstorage_ntf_cb_t cb;             /**< Persistent storage operation completion callback function @ref pstorage_ntf_cb_t.  */pstorage_size_t   block_size;     /**< Desired block size for persistent memory storage. For example, if a module has a table with 10 entries, and each entry is 64 bytes in size,*   it can request 10 blocks with a block size of 64 bytes. The module can also request one block that is 640 bytes depending *   on how it would like to access or alter the memory in persistent memory.*   The first option is preferred when it is a single entry that needs to be updated often and doesn't impact the other entries.*   The second option is preferred when table entries are not changed individually but have a common point of loading and storing*   data. */pstorage_size_t   block_count;    /** Number of blocks requested by the module; minimum values is 1. */
} pstorage_module_param_t;

(四)、定时器初始化

该函数time2_init主要用于蓝牙透传和AT指令的处理,它的定时触发时间为发送20(字节)*32us=640。

(五)、蓝牙协议栈初始化

该函数ble_stack_init用于蓝牙协议栈的初始化。如果之前蓝牙协议栈地址配置错误的话,这里会进入硬件中断。

(六)、GAP参数初始化

该函数gap_params_init用于初始化GAP(Generic Access Profile),配置蓝牙名字和连接参数的配置。它的结构体如下:

/**@brief GAP connection parameters.** @note  When ble_conn_params_t is received in an event, both min_conn_interval and*        max_conn_interval will be equal to the connection interval set by the central.** @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:*       conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval*       that corresponds to the following Bluetooth Spec requirement:*       The Supervision_Timeout in milliseconds shall be larger than*       (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.*/
typedef struct
{uint16_t min_conn_interval;         /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t max_conn_interval;         /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t slave_latency;             /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/uint16_t conn_sup_timeout;          /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
} ble_gap_conn_params_t;
/**@brief GAP connection security modes.** Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n* Security Mode 1 Level 1: No security is needed (aka open link).\n* Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n* Security Mode 1 Level 3: MITM protected encrypted link required.\n* Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n* Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n*/
typedef struct
{uint8_t sm : 4;                     /**< Security Mode (1 or 2), 0 for no permissions at all. */uint8_t lv : 4;                     /**< Level (1, 2 or 3), 0 for no permissions at all. */} ble_gap_conn_sec_mode_t;

(七)、服务初始化

该函数services_init调用函数ble_nus_init,主要用于配置服务的UUID及其类型、配置各种特性等等。它的结构体如下:

/**@brief Nordic UART Service event handler type. */
typedef void (*ble_nus_data_handler_t) (ble_nus_t * p_nus, uint8_t * p_data, uint16_t length);/**@brief Nordic UART Service initialization structure.** @details This structure contains the initialization information for the service. The application* must fill this structure and pass it to the service using the @ref ble_nus_init*          function.*/
typedef struct
{ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
} ble_nus_init_t;

(八)、GAP广播初始化

该函数advertising_init用于配置广播中UART服务的UUID和可接收的最大长度等信息。它的结构体如下:

/**@brief Advertising data structure. This structure contains all options and data needed for encoding and*        setting the advertising data. */
typedef struct
{ble_advdata_name_type_t      name_type;                           /**< Type of device name. */uint8_t                      short_name_len;                      /**< Length of short device name (if short type is specified). */bool                         include_appearance;                  /**< Determines if Appearance shall be included. */uint8_t                      flags;                               /**< Advertising data Flags field. */int8_t *                     p_tx_power_level;                    /**< TX Power Level field. */ble_advdata_uuid_list_t      uuids_more_available;                /**< List of UUIDs in the 'More Available' list. */ble_advdata_uuid_list_t      uuids_complete;                      /**< List of UUIDs in the 'Complete' list. */ble_advdata_uuid_list_t      uuids_solicited;                     /**< List of solicited UUIDs. */ble_advdata_conn_int_t *     p_slave_conn_int;                    /**< Slave Connection Interval Range. */ble_advdata_manuf_data_t *   p_manuf_specific_data;               /**< Manufacturer specific data. */ble_advdata_service_data_t * p_service_data_array;                /**< Array of Service data structures. */uint8_t                      service_data_count;                  /**< Number of Service data structures. */bool                         include_ble_device_addr;             /**< Determines if LE Bluetooth Device Address shall be included. */ble_advdata_le_role_t        le_role;                             /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT.*/ble_advdata_tk_value_t *     p_tk_value;                          /**< Security Manager TK value field. Included when different from NULL.*/uint8_t *                    p_sec_mgr_oob_flags;                 /**< Security Manager Out Of Band Flags field. Included when different from NULL.*/
} ble_advdata_t;

(九)、蓝牙连接参数初始化

该函数conn_params_init主要用于配置蓝牙连接的连接更新延时、事件/错误句柄等连接相关的参数。它的结构体如下:

/**@brief Connection Parameters Module init structure. This contains all options and data needed for*        initialization of the connection parameters negotiation module. */
typedef struct
{ble_gap_conn_params_t *       p_conn_params;                    /**< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host. */uint32_t                      first_conn_params_update_delay;   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks). */uint32_t                      next_conn_params_update_delay;    /**< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0. */uint8_t                       max_conn_params_update_count;     /**< Number of attempts before giving up the negotiation. */uint16_t                      start_on_notify_cccd_handle;      /**< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event. */bool                          disconnect_on_fail;               /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise. */ble_conn_params_evt_handler_t evt_handler;                      /**< Event handler to be called for handling events in the Connection Parameters. */ble_srv_error_handler_t       error_handler;                    /**< Function to be called in case of an error. */
} ble_conn_params_init_t;
/**@brief GAP connection parameters.** @note  When ble_conn_params_t is received in an event, both min_conn_interval and*        max_conn_interval will be equal to the connection interval set by the central.** @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:*       conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval*       that corresponds to the following Bluetooth Spec requirement:*       The Supervision_Timeout in milliseconds shall be larger than*       (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.*/
typedef struct
{uint16_t min_conn_interval;         /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t max_conn_interval;         /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t slave_latency;             /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/uint16_t conn_sup_timeout;          /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
} ble_gap_conn_params_t;

(十)、开启广播

该函数原型为uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode),传入参数为广播模式,枚举如下:

/**@brief Advertising modes.
*/
typedef enum
{BLE_ADV_MODE_IDLE,          /**< Idle; no connectable advertising is ongoing.*/BLE_ADV_MODE_DIRECTED,      /**< Directed advertising attempts to connect to the most recently disconnected peer. */BLE_ADV_MODE_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */BLE_ADV_MODE_FAST,          /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */BLE_ADV_MODE_SLOW,          /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */
} ble_adv_mode_t;

(十一)、低功耗模式

最后的这个函数power_manage用于使蓝牙进入低功耗模式等待事件到来,调用的函数为sd_app_evt_wait。

nRF51822蓝牙开发相关推荐

  1. iOS蓝牙开发---CoreBluetooth[BLE 4.0] 初级篇[内附Demo地址]

    一.蓝牙基础知识 (一)常见简称 1.MFI  make for ipad ,iphone, itouch 专们为苹果设备制作的设备,开发使用ExternalAccessory 框架(认证流程貌似挺复 ...

  2. [转]Android蓝牙开发浅谈

    转自:http://www.eoeandroid.com/thread-18993-7-1.html 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少    ...

  3. 《低功耗蓝牙开发权威指南》——第2章基本概念

    本节书摘来自华章社区<低功耗蓝牙开发权威指南>一书中的第2章基本概念,作者 (英)Robin Heydon,更多章节内容可以访问云栖社区"华章社区"公众号查看 第2章 ...

  4. STM32开发 -- 蓝牙开发详解(2)

    如需转载请注明出处:https://juyou.blog.csdn.net/article/details/100708695 接着 STM32开发 – 蓝牙开发详解(1) 这一篇接着讲. 看了好久好 ...

  5. 05-iOS蓝牙开发总结

    蓝牙开发总结 只要熟悉蓝牙的流程,和蓝牙中每一个角色的作用,其实蓝牙通讯并没有想象中的难 1.蓝牙中心CBCentralManager:一般指得是iPhone手机 2.设备(外设)CBPeripher ...

  6. 01-iOS蓝牙开发简介

    蓝牙开发简介 1.1-iOS蓝牙实现方案 iOS中提供了4个框架用于实现蓝牙连接 1.<GameKit.framework>:用法非常简单 只能用于iOS设备之间的连接,多用于蓝牙对战的游 ...

  7. Qt on android 蓝牙开发(控制小车)

    因为要做一个用蓝牙控制小车的app,就用着QT搞了下,网上关于QT蓝牙开发的资料比较少,我在这里记录下过程希望对看到了人有所帮助 首先在项目文件里添加 QT += bluetooth 这样就可以用QT ...

  8. Android蓝牙开发

    一.配置权限 AndroidManifest.xml里加入权限 <uses-permissionandroid:name="android.permission.BLUETOOTH_A ...

  9. 《低功耗蓝牙开发权威指南》——第3章低功耗蓝牙的体系结构

    本节书摘来自华章社区<低功耗蓝牙开发权威指南>一书中的第3章低功耗蓝牙的体系结构,作者 (英)Robin Heydon,更多章节内容可以访问云栖社区"华章社区"公众号查 ...

最新文章

  1. 基于corosync和NFS服务器实现LNMP的高可用
  2. ajax入门体会(转)
  3. sql怎样删除重复值
  4. Flutter BottomNavigationBar 三分钟实现一个常用APP首页底部导航菜单栏
  5. 软件架构(9)---UML 图
  6. 热血动漫番太好看了!用Python爬取了1T的动漫,内存都爆了
  7. 【深度语义匹配模型】实践篇:语义匹配在贝壳找房智能客服中的应用
  8. mysql 线程内存 回收_【MySQL】InnoDB后台线程与内存缓存池
  9. 如何用java编写五子棋_java编写五子棋
  10. android 通知写法_android清除通知栏消息的代码
  11. IE编程1(.net)——读取IE窗口信息
  12. ggplot去掉背景网格线和更改为白色背景
  13. Python学习 - 列表
  14. 读文献——《Batch Normalization Accelerating Deep Network Training by Reducing Internal Covariate Shift》
  15. css3 transition transform属性造成文字抖动
  16. 数据科学之 如何找到指标的最 佳分裂点的几个想法
  17. 【黄啊码】MySQL入门—4、掌握这些数据筛选技能比你学python还有用-1
  18. JPA @PersistenceContext和@Transactional Annotation
  19. 小程序开发之瀑布流布局
  20. 用浏览器快速开启Docker的体验之旅

热门文章

  1. 创新工厂面试题详解:共打了多少鱼
  2. 团队-排课软件-项目总结
  3. Qt之QGraphicsVideoItem播放视频
  4. 我想做一款软件,易语言的
  5. eclipse导入Junit和测试
  6. vue项目pc端使用rem进行适配 (lib-flexible+postcss-pxtorem)
  7. 用 CSS 做一个美化的 button 按钮
  8. 可以给小米盒子装鸿蒙系统吗,小米盒子可以安装第三方软件吗_小米盒子怎么安装第三方软件-系统城...
  9. 现代计算机的内存储器由,内存储器包括哪些
  10. 服务器CPU型号后缀的区别,CPU的那些后缀是啥意思?一文教你读懂CPU的型号标识!...