当前位置:   article > 正文

蓝牙nRF52832开发板

nrf52832

1 概念

蓝牙芯片:系统级芯片(System on chip)是一种集成多功能模块到单一芯片的集成电路。蓝牙芯片就是一种系统级芯片,蓝牙芯片集成MCU(MicroControlUnit,微型控制单元)和RF(RadioFrequence,射频)两个功能,其中MCU负责蓝牙协议栈处理,RF负责无线数据收发。

Nordic:蓝牙系统级芯片生产公司。

nRF52832:Nordic公司生产的系统级芯片型号,参数如下表所示:

CPU运算器Flash闪存RAM随机存储器
64 MHz Arm Cortex-M4 with FPU512/256 KB64/32 KB
TWI/SPI/UART PWM, PDM, I2SADC, Comparator
2xTWI/SPI, SPI, UARTYesYes
Operating temperatureSupply voltage rangePackages
-40 to 85 °C1.7 to 3.6 V

6x6 mm QFN48
 (32 GPIOs)

3.0x3.2 mm WLCSP50
 (32 GPIOs)

TWI/I2C:两线串行接口,一根SCL,一根SDA,半双工通信;

SPI:同步串行总线,SDI(输入)、SDO(输出)、SCK(串行移位时钟)、CS(信号);

UART:串口,RX(接收)、TX(发送)和GND;

I2S:将两路音频信号变成单一的数据队列,比PCM更适合于立体声系统;

PDM:脉冲密度调制;

PWM:脉冲宽度调制;

ADC:模拟数字转换器;

Comparator:比较器,接受两路模拟信号输入,比较输入产生一路二进制输出信号;

Packages:封装方式。

BLE协议栈:实现低功耗蓝牙协议的代码,分为控制层、主协议层、应用层。

应用层:包括公有服务和私有服务等;

协议层:包括GAP、GATT、L2CAP、SMP、ATT等;

控制层:包括主机控制器HCI、链路层LL、物理层PHY等。

通用访问规范GAP:定义了蓝牙设备的广播、连接、发现和身份识别等基本行为的协议,主要功能包括:广播和扫描、连接和断开、安全性和身份识别;

通用属性配置文件GATT:定义设备之间数据通信的协议框架,主要包括服务、特性及描述符的定义,设备之间通过这些属性的读取和写入来交换数据。

服务配置列表:包含一个或多个服务的文件。

服务:蓝牙BLE中组织数据传输和接收的最小单位,包含一个或多个特性。

特性:包括特性参数和GATT属性;特性参数包括空中属性(写;没有回应的写;读;通知;指示)和描述符;GATT属性包括一个128位的UUID、属性参数和属性特征值。

服务UUID与特性UUID:用于标识一个服务/特性的唯一标识符,128位,通常表示为十六进制字符串。在 GATT 协议中,通过使用服务 UUID 和特性 UUID,蓝牙设备可以组织和交换数据。中央设备(如智能手机)可以通过读取和写入特性来与外围设备(如传感器)进行通信。这种基于 UUID 的标识机制确保了设备之间的互操作性。

MAC地址(Media Access Control Address):媒体存取控制位地址,蓝牙BLE的MAC地址可分为两种,分别为Public Device Address(公共设备地址)和Random Device Address(随机设备地址)。公共设备地址由企业向IEEE购买以保证唯一性;设置随机设备地址:静态设备地址11开头、不可解析私有地址00开头、可解析私有地址。

DFU(Device Firmware Update):设备固件升级,可以通过无线方式(OTA),重新烧录app到蓝牙芯片中,也可以通过有线方式(UART、USB及SPI)。

SWD(Serial Wire Debug):一种用于在嵌入式系统中进行调试和编程的通信接口。它是一种串行单线调试接口,用于连接调试工具(如调试器)与目标芯片,以进行调试、烧录和监控操作。

2 开发软件

keil MDK:C语言编写微控制器系统的软件。

nRFgo Studio:由 Nordic Semiconductor 开发的集成开发环境(IDE),配置和管理Nordic Semiconductor芯片相关的参数,可将程序烧录至芯片。

nRFconnect:由 Nordic Semiconductor 开发的一组工具和应用程序,用于开发、测试和调试基于 Nordic Semiconductor 射频(RF)芯片的无线应用。Program模块可烧录程序至芯片。

3 开发硬件

JLink:将在keil mdk等软件上编写的程序烧录至ARM、Cortex等芯片上的硬件。

nRF52832:Nordic公司生产的蓝牙芯片型号。

蓝牙芯片pinout通过杜邦线连接JLink仿真器,JLink仿真器通过USB连接电脑,安装驱动,重启电脑,打开Keil、nRFStudio和nRFconnect软件可连接并识别到设备。

4 硬件连接

4.1 实物连接方式(一)

如上图所示,传感器因电阻变化引起电压变化,通过数模转化器(HX711模块)将模拟信号转为数字信号,并通过(GND、VCC、RX和TX,即接地、电压、接收端和发送端)4个引脚将数据传输给蓝牙模块(HC-08)。该图中所用蓝牙芯片为TI厂家。

4.2 实物连接方式(二)

如上图所示,JLink仿真器通过USB连接至电脑,通过杜邦线连接至蓝牙芯片的程序烧录端口(对应蓝牙芯片的25、26号引脚),蓝牙芯片(7、8、9、10号引脚)通过CH340芯片(串口转USB)串口转为USB,再通过USB线连接电脑端串口小程序。

电脑端通过软件Keil将蓝牙程序烧录至蓝牙芯片,手机连接蓝牙后,可以发送指令让蓝牙芯片问串口要数据。

4.3 逻辑连接方式

上图所示为nordic 厂家的nRF52832型号的蓝牙芯片引脚图。

 上图所示为SWD接口及传感器与蓝牙芯片引脚对应图。

  上图所示为串口与蓝牙芯片引脚对应图。

5 程序从机设计

5.1 总体流程

连接流程:从机广播-》主机扫描-》发起连接-》连接建立-》数据交换。

蓝牙BLE基础工程搭建流程:打印输出LOG实现;板级设备初始化;内存管理初始化;协议栈初始化;GAP与GATT初始化;广播初始化;服务初始化;连接参数初始化。

5.2 协议栈初始化

该部分主要功能为使蓝牙能用。主要配置内容包括:时钟设置(内部RC时钟、外部晶振时钟、合成时钟)、广播事件、主从机设置、MTU、Gatt服务特性、注册蓝牙事件等。

外部晶振时钟:对电流消耗最低;

内部RC时钟:多消耗电流,节省成本;

内部高速时钟合成:消耗电流最多。

5.3 GAP设置

该部分主要功能为使蓝牙被发现和连接。主要配置内容包括:设备名称设置;连接参数设置(最小/最大连接间隔;从机延迟;连接超时监督时间)等。

5.4 添加服务

1)加入服务配置文件

创建services文件夹->引用官方xxx.c文件->在options for taret的C++中添加路径->在main.c文件中声明xxx.h文件,并声明xxx.h中的观察者函数名称

2)修改sdk_config.h服务配置

修改sdk_config.h文件中的NRF_SDH_BLE_VS_UUID_COUNT的数量,(因为该xx.c服务为官方提供服务)在配置文件中将BLE_LBS_C_ENABLED-ble_lbs_c-NordicLEDButtonServiceClient勾上

3)添加服务

main.c文件中services_init()方法调用xxx.c文件中声明的xxx_init()服务初始化函数,该函数的2个入参分别是该函数的观察者函数和初始化函数,在这个函数中调用sd_ble_gatts_service_add()来添加主服务

  1. // Add Main Service
  2. err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle);

第一个参数:服务类型为主服务

第二个参数:用于服务的基础UUID

  1. ble_uuid128_t base_uuid = {LBS_UUID_BASE};
  2. err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type);
  3. VERIFY_SUCCESS(err_code);
  4. ble_uuid.type = p_lbs->uuid_type;
  5. ble_uuid.uuid = LBS_UUID_SERVICE;

第三个参数:唯一的服务句柄,作为服务的回调

4)添加特性

如果该服务不是SIG定义的服务,那么就需要自己根据GATT框架定义服务的特性。

  1. // Add HT characteristic
  2. memset(&add_char_params, 0, sizeof(add_char_params));
  3. // GATT
  4. add_char_params.uuid = LBS_UUID_HT_CHAR; //
  5. add_char_params.uuid_type = p_lbs->uuid_type;
  6. add_char_params.init_len = 2;
  7. add_char_params.max_len = 2;
  8. // characteristic
  9. add_char_params.char_props.read = 1;
  10. add_char_params.char_props.write = 1;
  11. add_char_params.char_props.notify = 1;
  12. add_char_params.read_access = SEC_OPEN;
  13. add_char_params.write_access = SEC_OPEN;
  14. add_char_params.cccd_write_access = SEC_OPEN;
  15. err_code = characteristic_add(p_lbs->service_handle,
  16. &add_char_params,
  17. &p_lbs->ht_char_handles);
  18. if (err_code != NRF_SUCCESS)
  19. {
  20. return err_code;
  21. }

5.5 广播设置

该部分主要功能为广播发包及回包内容设置。主要配置内容包括:设备全称类型、图标、服务UUID、广播模式设置等。

 广播初始配置结构体:

  1. typedef struct
  2. {
  3. ble_advdata_t advdata; /**< Advertising data: name, appearance, discovery flags, and more. ¹ã²¥°ü*/
  4. ble_advdata_t srdata; /**< Scan response data: Supplement to advertising data. »Ø°ü*/
  5. ble_adv_modes_config_t config; /**< Select which advertising modes and intervals will be utilized.*/
  6. ble_adv_evt_handler_t evt_handler; /**< Event handler that will be called upon advertising events. */
  7. ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
  8. } ble_advertising_init_t;

广播发包和回收包结构体:

  1. typedef struct
  2. {
  3. ble_advdata_name_type_t name_type; /**< Type of device name. */
  4. uint8_t short_name_len; /**< Length of short device name (if short type is specified). */
  5. bool include_appearance; /**< Determines if Appearance shall be included. */
  6. uint8_t flags; /**< Advertising data Flags field. */
  7. int8_t * p_tx_power_level; /**< TX Power Level field. */
  8. ble_advdata_uuid_list_t uuids_more_available; /**< List of UUIDs in the 'More Available' list. */
  9. ble_advdata_uuid_list_t uuids_complete; /**< List of UUIDs in the 'Complete' list. */
  10. ble_advdata_uuid_list_t uuids_solicited; /**< List of solicited UUIDs. */
  11. ble_advdata_conn_int_t * p_slave_conn_int; /**< Slave Connection Interval Range. */
  12. ble_advdata_manuf_data_t * p_manuf_specific_data; /**< Manufacturer specific data. */
  13. ble_advdata_service_data_t * p_service_data_array; /**< Array of Service data structures. */
  14. uint8_t service_data_count; /**< Number of Service data structures. */
  15. bool include_ble_device_addr; /**< Determines if LE Bluetooth Device Address shall be included. */
  16. ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */
  17. ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
  18. uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
  19. ble_gap_lesc_oob_data_t * p_lesc_data; /**< LE Secure Connections OOB data. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
  20. } ble_advdata_t;

广播模式配置结构体:

  1. typedef struct
  2. {
  3. bool ble_adv_on_disconnect_disabled; /**< Enable or disable automatic return to advertising upon disconnecting.*/
  4. bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
  5. bool ble_adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. Can not be used together with extended advertising. */
  6. bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
  7. bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
  8. bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
  9. uint32_t ble_adv_directed_interval; /**< Advertising interval for directed advertising. */
  10. uint32_t ble_adv_directed_timeout; /**< Time-out (number of tries) for direct advertising. */
  11. uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
  12. uint32_t ble_adv_fast_timeout; /**< Time-out (in units of 10ms) for fast advertising. */
  13. uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
  14. uint32_t ble_adv_slow_timeout; /**< Time-out (in units of 10ms) for slow advertising. */
  15. bool ble_adv_extended_enabled; /**< Enable or disable extended advertising. */
  16. uint32_t ble_adv_secondary_phy; /**< PHY for the secondary (extended) advertising @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
  17. uint32_t ble_adv_primary_phy; /**< PHY for the primary advertising. @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
  18. } ble_adv_modes_config_t;

入口文件中定义广播观察函数,连接发生变化后调用:

  1. BLE_ADVERTISING_DEF(m_advertising);
  2. #define BLE_ADVERTISING_DEF(_name)
  3. static ble_advertising_t _name;
  4. NRF_SDH_BLE_OBSERVER(_name ## _ble_obs,
  5. BLE_ADV_BLE_OBSERVER_PRIO,
  6. ble_advertising_on_ble_evt, &_name)
  7. void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
  8. {
  9. ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
  10. switch (p_ble_evt->header.evt_id)
  11. {
  12. case BLE_GAP_EVT_CONNECTED:
  13. on_connected(p_advertising, p_ble_evt);
  14. break;
  15. // Upon disconnection, whitelist will be activated and direct advertising is started.
  16. case BLE_GAP_EVT_DISCONNECTED:
  17. on_disconnected(p_advertising, p_ble_evt);
  18. break;
  19. // 广播超时后,开始下一个广播模式
  20. case BLE_GAP_EVT_ADV_SET_TERMINATED:
  21. on_terminated(p_advertising, p_ble_evt);
  22. break;
  23. default:
  24. break;
  25. }
  26. }
  27. static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
  28. {
  29. ret_code_t ret;
  30. if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
  31. {
  32. // Nothing to do.
  33. return;
  34. }
  35. if ( p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT//¹ã²¥³¬Ê±
  36. ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)´ïµ½ÏÞÖƵĹ㲥ʼþ
  37. {
  38. //开始广播下一个广播模式
  39. ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));
  40. if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
  41. {
  42. p_advertising->error_handler(ret);
  43. }
  44. }
  45. }

5.6 启动广播

advertising_start(erase_bonds):启动广播;

ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params):设置为快速广播;

主函数BLE_ADVERTISING_DEF(m_advertising):广播观察函数,设置时间内未连接切换为慢速广播,最终切换为无效广播,设备进入休眠状态。

5.7 数据传输

采用观察者模型,即事先在main.c文件中定义监听函数,一旦收到主机消息即可调用:

NRF_SDH_BLE_OBSERVER(_name ## _obs,=BLE_LBS_BLE_OBSERVER_PRIO,ble_lbs_on_ble_evt, &_name)

服务建立后,主机通过服务中的写属性写一个数据给从机,从机接收到数据后,从协议栈上产生一个BLE_GATTS_EVT_WRITE事件,此时可调度服务处理事件。调度事件派发函数ble_lbs_on_ble_evt,该函数使用简单的switch-case语句通过回调事件头部的id区分不同的事件,并进行不同的处理。

(1)主从机通信方式

1)串口通道AT指令:将蓝牙设置为串口,通过串口协议进行通信,暂未调研。

2)私有任务通道:通过配置的服务和特性进行数据传输,即5.4节服务配置。

(2)从机获取数据方式

1)传感器数据通信

通过引脚直接获取数据,按照官方文件修改。

2)蓝牙串口通信

串口:串行通讯端口,9针或25针。

CH340T:USB转串口的硬件板。从机上配置CH340T可将串口转为USB接口。

 传感器主推数据,蓝牙从缓存中获取数据app_uart_get(),app_uart_fifo.c库文件

  1. static void uart_loopback_test()
  2. {
  3. while (true)
  4. {
  5. uint8_t cr;
  6. while(app_uart_get(&cr) != NRF_SUCCESS);
  7. while(app_uart_put(cr) != NRF_SUCCESS);
  8. if (cr == 'q' || cr == 'Q')
  9. {
  10. printf(" \n\rExit!\n\r");
  11. while (true)
  12. {
  13. // Do nothing.
  14. }
  15. }
  16. }
  17. }

3)Flash存储

可从存储器中获取数据,暂未调研。

1)fstorage;

2)fds。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/194271
推荐阅读
相关标签
  

闽ICP备14008679号