https://blog.csdn.net/g360250466/article/details/78606704

Nrf51822 回顾:

1、工程样本

分为4部分,其中:

Starup Code中存放的是启动文件,设置NRF51822的启动项和系统时钟。

Source codecun存放的是main.c 文件。

Services中存放的是蓝牙的服务代码。

Libraies中放的是nrf51822提供的一些库函数。

带有BLE前缀的就是蓝牙相关的函数,带有app前缀的文件是和app应用有关系的文件夹。

2、框架

控制层:

1、主机控制器(HCI),也称设备管理器

设备管理器是基带中的一个功能模块,控制一般的蓝牙设备行为。他负责所有与数据无关的蓝牙系统操作,如:扫描,连接,被发现等的设置。

2、链路层(LL)

链路层负责链路管理,链路控制。包括负责创建,维护和释放逻辑链路已经更新设备之间物理链路的相关参数。

3、物理层:

物理层模块负责从物理信道传输和接受信息数据包。在基带和物理之间,一条控制路允许基带模块控制物理层的时隙和频率载波。同时,物理层模块向物理信道和基带发送和几首符合格式要求的数据流。

主协议层:

GAP(通用访问规范)

通用访问配置文件GAP,该profile保证不同的bluetooth产品可以相互发现对方并建立连接。它定义了蓝牙设备如何发现和建立与其他设备的安全(或不安全)连接。他处理一些一般模式的业务(如询问,命名,搜索)和一些安全性问题,同时还处理一些有关连接的业务,如链路的建立、信道和连接建立。

GATT层是传输真正数据所在的层。包括了一个数据传输和存储的框架。

GATT定义了两类角色。服务器和客户端。通常情况下我们的开发板是作为服务器的。手机作为客户端。

一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。

属性:一个属性包含句柄,UUID,值。

特性:一个特性包含2个属性,一个属性用于声明,一个属性用于存放特性的值。(我的理   解就是功能。串口服务中接收是一个特性,发送是一个特性。LED服务中,LED只   有接收数据的功能,所以只有一个特性。接收到1是亮,接收到0是灭。按键服务中,     只有发送的功能,按下就发送通知。所以也只有一个特性)服务:一个服务包含一个   或多个特性。

Profile(数据配置文件):一个profile可以包含一个或者多个服务

客户端特性配置描述符(Client Characteristic Configuration Descriptor,CCCD),这个描述符是给任何支持通知或指示功能的特性额外增加的。在CCCD中写入“1”使能通知功能,写入“2”使能指示功能,写入“0”同时禁止通知和指示功能这个描述符是服务器来配置的,通过写事件来向其中写入值。

空中操作性质:

写和没有回应的写,允许GATT客户端写入一个值到GATT服务器的一个特性中。它们之间的不同的地方在于一个没有回应的写事件没有任何应用层上的确认或回应。

读,读性质表明一个GATT客户端可以读取在GATT服务器中特性的值。

通知和指示性质允许GATT服务器在其某个特性改变的时候对GATT客户端进行提醒,通知和指示之间不同支出在于指示有应用蹭上的确认,而通知没有。

服务可以给通过sd_ble_gatts_service_add()进行添加。Service_uuid就是你想用于服务的UUID。变量service_handle是一个输出变量,当创建服务的时候会返回一个唯一的句柄值,这个句柄可以在以后用于识别不同的服务。

特性可以通过sd_ble_gatts_characteristic_add()函数进行添加。它有四个参数。第一个是特性要加入的服务的句柄,第二个参数是特性的结构体,它是一个全局变量,它包含了特性可能用到的性质(读,写和通知等)。第3个参数的值属性的描述包含了它的UUID,长度和初始值。第4个参数是返回的特性和描述符的唯一句柄。这个句柄可以在以后用于识别不同的特性。例如识别拿过一个特性被写入。

私有服务的实现需要定义的参数:

1、服务的句柄(用来存放函数的返回值,不需要自己初始化)

2、特性的句柄(用来存放函数的返回值,不需要自己初始化)

3、连接的句柄(在sd_ble_gatts_hvx()中用返回,不用自己初始化)

4、UUID类型(用来存放函数sd_ble_uuid_vs_add()的返回值,不用自己初始化)

5、事件发生的回调函数

3、协议栈如何运作?

  要明白协议栈怎么运作,首先就要理解51822的协议栈是基于100%的事件驱动的。就是说协议栈向app发送的任何数据都是基于事件的。

  比如设备收到手机发来的链接请求,或是手机发过来的数据等等。协议栈首先收到这些数据后做一些处理,然后将这些数据(比如链接请求,或是普通数据等)打包成一个结构体,并附上事件ID,比如BLE_GAP_EVT_CONNECTED或BLE_GATTS_EVT_WRITE来分别告诉上层app这个事件结构体代表的事件。

  比如BLE_GAP_EVT_CONNECTED代表链接事件,那么这个事件结构体中包含的数据就是连接参数等数据。而BLE_GATTS_EVT_WRITE代表写事件,那么结构体中的数据就是对端设备(比如手机)写给板子的数据。

static void ble_evt_dispatch(ble_evt_t * p_ble_evt)

{

ble_conn_params_on_ble_evt(p_ble_evt);

ble_nus_on_ble_evt(&m_nus, p_ble_evt);

on_ble_evt(p_ble_evt);

}

  在任何与BLE相关的事件被协议栈上抛上来给app时,ble_evt_dispatch就会被调用。从而将事件抛给各个服务函数或处理模块,这里是将事件抛给了

  连接参数管理处理函数ble_conn_params_on_ble_evt

  Uart服务的事件处理函数ble_nus_on_ble_evt (nus为Nordicuart server)

  通用的事件处理函数on_ble_evt

不同的事件在事件结构体ble_evt_t中通过id来区别。不同是事件处理函数通常也只是处理自己感兴趣的事件

 蓝牙没有接收函数,蓝牙的数据接收在底层,接收完后会返回事件给上层的 ble_evt_dispatch 分发函数,它将事件分发给各个服务或者事件处理函数。 服 务或处理函数会捕获是否存在写事件case BLE_GATTS_EVT_WRITE: 存在就做 相应的处理。收到的数据都在返回的事件结构体里

  其实看完这三个问题基本上上面的问题其实已经解决差不多了。作为从设备,BLE的发送数据给手机是有API接口的,就是上面问到的sd_ble_gatts_hvx(),可以通过参数来设置是以通知方式发送还是指示方式发送(通知不需要回复确认,指示需要)。但是手机发过来数据却是没有接收函数,为什么?因为协议栈是基于事件驱动的!所以收到数据后协议栈会给上层app一个写事件(指示对端设备写数据过来了),而写过来的数据时在这个事件结构体中。我们只要提取出来就行了。所以没有接收函数API。

关于NRF51822的休眠:

程序中进行休眠的地方是在事件管理中进行休眠的,在on_ble_evt中,如下:

通过case BLE_GAP_EVT_TIMEOUT:中的err_code = sd_power_system_off();

NRF51822 回顾总结相关推荐

  1. 蓝牙nrf51822程序的分析(一)

    蓝牙nrf51822程序的分析(一) 最近继续用NRF51822开发一个东西.无奈之前没接触过蓝牙.连蓝牙串口模块也没有.所以对蓝牙的基础知识不够,后面看了之后接着补充 花了2天时间把提供的NRF51 ...

  2. 回顾 2018,展望 2019

    1. 概述 今天是 2019 年第一天,趁着元旦 3 天假期时间,对即将过去的这一年做个总结回顾,看下这一年得到了什么,失去了什么,并对来年做个新的规划,看下需要采取哪些措施提升自己. 2. 2018 ...

  3. Jeff Dean回顾谷歌2021

    Jeff Dean回顾谷歌2021 新年伊始,谷歌AI掌门人Jeff Dean的年度总结「虽迟但到」,这篇万字长文系统回顾了过去一年来机器学习领域的五大趋势.除了超大AI模型,谷歌去年还做了啥? 20 ...

  4. ❤️Spark的关键技术回顾,持续更新!【推荐收藏加关注】❤️

    目录 前言 Spark的关键技术回顾 一.Spark复习题回顾 1.Spark使用的版本 2.Spark几种部署方式? 3.Spark的提交任务的方式? 4.使用Spark-shell的方式也可以交互 ...

  5. 2021年大数据Spark(四十二):SparkStreaming的Kafka快速回顾与整合说明

    目录 Kafka快速回顾 消息队列: 发布/订阅模式: Kafka 重要概念: 常用命令 整合说明 两种方式 两个版本API 在实际项目中,无论使用Storm还是SparkStreaming与Flin ...

  6. scrum回顾_Scrum和SAFe之间有什么不同

    原文地址:https://www.knowledgehut.com/blog/agile/scrum-vs-safe Scrum是基于敏捷的价值观和原则的框架,而SAFe是在企业级别实施Scrum的框 ...

  7. Java基础知识回顾之六 ----- IO流

    前言 在上一篇文章中,回顾了Java的多线程.而在本篇文章中主要介绍Java IO的相关知识. IO的介绍 什么是IO? IO的名称又来是Input与Output的缩写,也就是输入流和输出流.输入流用 ...

  8. [nRF51822] 8、基础实验代码解析大全 · 实验11 - PPI

    前一篇分析了前十个基础实验的代码,从这里开始分析后十个~ 一.PPI原理: PPI(Programmable Peripheral Interconnect),中文翻译为可编程外设互连. 在nRF51 ...

  9. 12月第三周安全要闻回顾:浏览器安全不容忽视,SSL弱点影响网站安全

    本周(081215至081221)安全方面的新闻众多,主要集中在***与威胁趋势方面.浏览器安全方向波澜起伏,微软推出了针对上周公开的IE7新漏洞的紧急安全补丁,但目前互联网上针对该漏洞的大规模*** ...

最新文章

  1. C语言中字符数组初始化的几种方法
  2. Sqlite c/c++ api 学习
  3. 机器学习之神经网络学习及其模型
  4. c语言单链表原地转置,不带头结点的单链表的插入,删除,原地转置,判断空,清空,统计节点数目等操作...
  5. 网易整合邮箱和博客 可通过邮件更新博客日志
  6. (转载)数据库的三范式:我见过讲的最通俗易懂的三范式!!!
  7. 3S基础知识:MapX应用教程—创建地图对象
  8. Windows系统通过cmd查找结束进程
  9. w ndows键是哪一个,Win10截图快捷键是哪个?Windows10自带截屏快捷键使用方法大全...
  10. Kiwi Syslog日志服务器的安装及配置使用
  11. php 获取北京时间
  12. 网站制作入门指导教程
  13. [ 操作系统 ] 假定在单CPU条件下有下列要执行的作业,用一个执行时间图描述在采用非抢占优先级算法时执行这些作业的情况;对于上述算法,各个作业的周转时间是多少?平均周转时间是多少?
  14. 华为、荣耀笔记本如何开启或关闭虚拟化技术(Virtual Technology)
  15. 使用c3p0数据库连接池连接时出现错误:java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
  16. 关于Tushare库的使用
  17. THUWC2017 在美妙的数学王国中畅游
  18. Arduino ESP8266固件bin升级四种方法
  19. Oculus Rift S 399美元,真香
  20. 从PCB的结构与工艺理解阻焊(Solder mask)与助焊(Paster Mask)

热门文章

  1. sort函数和sorted函数的异同
  2. 【数据压缩】压缩率-图像熵-保真度
  3. Web前端设计与开发课程设计:简易淘宝网页设计
  4. 【ACWing】723. PUM
  5. Sketch掌握常用快捷键提升工作效率
  6. webfreer去广告
  7. php网站整合ck播放器,wordpress整合ckplayer最新版 wp文章短代码调用ck播放器
  8. odroid平台——ASUS Xtion Pro Live + Openni + ROS搭建(Xu4升级版)
  9. OR1200处理器中Wishbone总线接口模块WB_BIU介绍
  10. 关于移动互联网运营的分享总结