赞
踩
蓝牙芯片:系统级芯片(System on chip)是一种集成多功能模块到单一芯片的集成电路。蓝牙芯片就是一种系统级芯片,蓝牙芯片集成MCU(MicroControlUnit,微型控制单元)和RF(RadioFrequence,射频)两个功能,其中MCU负责蓝牙协议栈处理,RF负责无线数据收发。
Nordic:蓝牙系统级芯片生产公司。
nRF52832:Nordic公司生产的系统级芯片型号,参数如下表所示:
CPU运算器 | Flash闪存 | RAM随机存储器 |
64 MHz Arm Cortex-M4 with FPU | 512/256 KB | 64/32 KB |
TWI/SPI/UART | PWM, PDM, I2S | ADC, Comparator |
2xTWI/SPI, SPI, UART | Yes | Yes |
Operating temperature | Supply voltage range | Packages |
-40 to 85 °C | 1.7 to 3.6 V | 6x6 mm QFN48 3.0x3.2 mm WLCSP50 |
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):一种用于在嵌入式系统中进行调试和编程的通信接口。它是一种串行单线调试接口,用于连接调试工具(如调试器)与目标芯片,以进行调试、烧录和监控操作。
keil MDK:C语言编写微控制器系统的软件。
nRFgo Studio:由 Nordic Semiconductor 开发的集成开发环境(IDE),配置和管理Nordic Semiconductor芯片相关的参数,可将程序烧录至芯片。
nRFconnect:由 Nordic Semiconductor 开发的一组工具和应用程序,用于开发、测试和调试基于 Nordic Semiconductor 射频(RF)芯片的无线应用。Program模块可烧录程序至芯片。
JLink:将在keil mdk等软件上编写的程序烧录至ARM、Cortex等芯片上的硬件。
nRF52832:Nordic公司生产的蓝牙芯片型号。
蓝牙芯片pinout通过杜邦线连接JLink仿真器,JLink仿真器通过USB连接电脑,安装驱动,重启电脑,打开Keil、nRFStudio和nRFconnect软件可连接并识别到设备。
如上图所示,传感器因电阻变化引起电压变化,通过数模转化器(HX711模块)将模拟信号转为数字信号,并通过(GND、VCC、RX和TX,即接地、电压、接收端和发送端)4个引脚将数据传输给蓝牙模块(HC-08)。该图中所用蓝牙芯片为TI厂家。
如上图所示,JLink仿真器通过USB连接至电脑,通过杜邦线连接至蓝牙芯片的程序烧录端口(对应蓝牙芯片的25、26号引脚),蓝牙芯片(7、8、9、10号引脚)通过CH340芯片(串口转USB)串口转为USB,再通过USB线连接电脑端串口小程序。
电脑端通过软件Keil将蓝牙程序烧录至蓝牙芯片,手机连接蓝牙后,可以发送指令让蓝牙芯片问串口要数据。
上图所示为nordic 厂家的nRF52832型号的蓝牙芯片引脚图。
上图所示为SWD接口及传感器与蓝牙芯片引脚对应图。
上图所示为串口与蓝牙芯片引脚对应图。
连接流程:从机广播-》主机扫描-》发起连接-》连接建立-》数据交换。
蓝牙BLE基础工程搭建流程:打印输出LOG实现;板级设备初始化;内存管理初始化;协议栈初始化;GAP与GATT初始化;广播初始化;服务初始化;连接参数初始化。
该部分主要功能为使蓝牙能用。主要配置内容包括:时钟设置(内部RC时钟、外部晶振时钟、合成时钟)、广播事件、主从机设置、MTU、Gatt服务特性、注册蓝牙事件等。
外部晶振时钟:对电流消耗最低;
内部RC时钟:多消耗电流,节省成本;
内部高速时钟合成:消耗电流最多。
该部分主要功能为使蓝牙被发现和连接。主要配置内容包括:设备名称设置;连接参数设置(最小/最大连接间隔;从机延迟;连接超时监督时间)等。
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()来添加主服务
- // Add Main Service
- err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle);
第一个参数:服务类型为主服务
第二个参数:用于服务的基础UUID
- ble_uuid128_t base_uuid = {LBS_UUID_BASE};
- err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type);
- VERIFY_SUCCESS(err_code);
-
- ble_uuid.type = p_lbs->uuid_type;
- ble_uuid.uuid = LBS_UUID_SERVICE;
第三个参数:唯一的服务句柄,作为服务的回调
4)添加特性
如果该服务不是SIG定义的服务,那么就需要自己根据GATT框架定义服务的特性。
- // Add HT characteristic
- memset(&add_char_params, 0, sizeof(add_char_params));
- // GATT
- add_char_params.uuid = LBS_UUID_HT_CHAR; //
- add_char_params.uuid_type = p_lbs->uuid_type;
- add_char_params.init_len = 2;
- add_char_params.max_len = 2;
- // characteristic
- add_char_params.char_props.read = 1;
- add_char_params.char_props.write = 1;
- add_char_params.char_props.notify = 1;
-
- add_char_params.read_access = SEC_OPEN;
- add_char_params.write_access = SEC_OPEN;
- add_char_params.cccd_write_access = SEC_OPEN;
-
- err_code = characteristic_add(p_lbs->service_handle,
- &add_char_params,
- &p_lbs->ht_char_handles);
- if (err_code != NRF_SUCCESS)
- {
- return err_code;
- }
该部分主要功能为广播发包及回包内容设置。主要配置内容包括:设备全称类型、图标、服务UUID、广播模式设置等。
广播初始配置结构体:
- typedef struct
- {
- ble_advdata_t advdata; /**< Advertising data: name, appearance, discovery flags, and more. ¹ã²¥°ü*/
- ble_advdata_t srdata; /**< Scan response data: Supplement to advertising data. »Ø°ü*/
- ble_adv_modes_config_t config; /**< Select which advertising modes and intervals will be utilized.*/
- ble_adv_evt_handler_t evt_handler; /**< Event handler that will be called upon advertising events. */
- ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
- } ble_advertising_init_t;
广播发包和回收包结构体:
- 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. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */
- 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.*/
- 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.*/
- 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.*/
- } ble_advdata_t;
广播模式配置结构体:
- typedef struct
- {
- bool ble_adv_on_disconnect_disabled; /**< Enable or disable automatic return to advertising upon disconnecting.*/
- bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
- bool ble_adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. Can not be used together with extended advertising. */
- bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
- bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
- bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
- uint32_t ble_adv_directed_interval; /**< Advertising interval for directed advertising. */
- uint32_t ble_adv_directed_timeout; /**< Time-out (number of tries) for direct advertising. */
- uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
- uint32_t ble_adv_fast_timeout; /**< Time-out (in units of 10ms) for fast advertising. */
- uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
- uint32_t ble_adv_slow_timeout; /**< Time-out (in units of 10ms) for slow advertising. */
- bool ble_adv_extended_enabled; /**< Enable or disable extended advertising. */
- 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). */
- 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). */
- } ble_adv_modes_config_t;
入口文件中定义广播观察函数,连接发生变化后调用:
- BLE_ADVERTISING_DEF(m_advertising);
-
-
- #define BLE_ADVERTISING_DEF(_name)
- static ble_advertising_t _name;
- NRF_SDH_BLE_OBSERVER(_name ## _ble_obs,
- BLE_ADV_BLE_OBSERVER_PRIO,
- ble_advertising_on_ble_evt, &_name)
-
- void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
- {
- ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
-
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_CONNECTED:
- on_connected(p_advertising, p_ble_evt);
- break;
-
- // Upon disconnection, whitelist will be activated and direct advertising is started.
- case BLE_GAP_EVT_DISCONNECTED:
- on_disconnected(p_advertising, p_ble_evt);
- break;
-
- // 广播超时后,开始下一个广播模式
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- on_terminated(p_advertising, p_ble_evt);
- break;
-
- default:
- break;
- }
- }
-
- static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
- {
- ret_code_t ret;
-
- if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
- {
- // Nothing to do.
- return;
- }
-
- if ( p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT//¹ã²¥³¬Ê±
- ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)´ïµ½ÏÞÖƵĹ㲥ʼþ
- {
- //开始广播下一个广播模式
- ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));
-
- if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
- {
- p_advertising->error_handler(ret);
- }
- }
- }
advertising_start(erase_bonds):启动广播;
ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params):设置为快速广播;
主函数BLE_ADVERTISING_DEF(m_advertising):广播观察函数,设置时间内未连接切换为慢速广播,最终切换为无效广播,设备进入休眠状态。
采用观察者模型,即事先在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)串口通道AT指令:将蓝牙设置为串口,通过串口协议进行通信,暂未调研。
2)私有任务通道:通过配置的服务和特性进行数据传输,即5.4节服务配置。
通过引脚直接获取数据,按照官方文件修改。
串口:串行通讯端口,9针或25针。
CH340T:USB转串口的硬件板。从机上配置CH340T可将串口转为USB接口。
传感器主推数据,蓝牙从缓存中获取数据app_uart_get(),app_uart_fifo.c库文件
- static void uart_loopback_test()
- {
-
- while (true)
- {
- uint8_t cr;
- while(app_uart_get(&cr) != NRF_SUCCESS);
- while(app_uart_put(cr) != NRF_SUCCESS);
-
- if (cr == 'q' || cr == 'Q')
- {
- printf(" \n\rExit!\n\r");
-
- while (true)
- {
- // Do nothing.
- }
- }
- }
-
- }
可从存储器中获取数据,暂未调研。
1)fstorage;
2)fds。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。