一、环境与简介
1 本次笔记介绍了 低功耗 ®蓝牙 (LE) 部分 SimpleLink™ CC13xx 和 CC26xx 软件开发套件 (SDK)。在官方
simple_central模版上完成
2 软件需要安装CCS
3 安装
CC13xx 和 CC26xx的SDK包
首先打开CCS,再打开 Resource Explorer 通过 View → Resource Explorer ,找到 要安装的 SDK。
在右侧,会看到 3 个点。单击此按钮可打开下拉菜单。 然后,单击“下载”以安装 SDK 及其所有依赖项。
二、GAP层
1 通用访问配置文件(GAP)层是主机协议栈中的顶层, 定义了BLE设备在待机和连接状态下的行为。
GAP角色 在gap.h
中定义:
GAP角色 | 描述 |
---|---|
broadcaster的 | 仅发送广告事件的设备。 |
观察员 | 一种只接收广告事件的设备。 |
外围 | 使用连接建立过程接受LE物理链路的建立的设备。 |
中央 | 支持中心角色的设备发起物理连接的建立。 |
差距层API提供了对设备行为的非常细粒度的控制。
三、扫描模式
1.导入simple_central模版
2.扫描设备包括两种类型:
主动和被动,主动扫描器可以发送扫描请求, 被动扫描器只能接收来自广告商的数据。
3.扫描参数
当涉及到扫描的时间,有几个参数扫描间隔,扫描窗口,扫描持续时间。
扫描参数 | 描述 | 范围 |
---|---|---|
扫描间隔 | 两个连续扫描窗口开始之间的间隔 | 10ms至10.24s |
扫描窗口 | 链路层的持续时间(链路层是控制器中的一个层,请参见背景部分中的图。)在一个通道上扫描 | 10ms至10.24s |
扫描持续时间 | 设备处于扫描状态的持续时间 | 10 ms至无穷大(最大值为65534 ms,但如果此值设置为0,则器械将无限期扫描) |
下图直观显示了扫描参数:
请注意,扫描通道的顺序是不可配置的。设备 将在通道37(2402 MHz)上扫描,然后在通道38(2426 MHz)上扫描,然后在通道38(2426 MHz)上扫描, 39(2480 MHz),并在每个扫描间隔上依次进行 扫描窗口定义的时间长度。
扫描数据包
辅助广告信道上的可扫描广告分组还可以 引发扫描请求和扫描响应。它们被称为AUX_SCAN_SCAN, AUX_SCAN_RSP。所有与扫描相关的数据包总结如下 表:
正在扫描PDU | 发送设备 | 有效载荷 |
---|---|---|
扫描_浏览 | 扫描仪 | 扫描仪地址+广告商地址 |
扫描_RSP | 广告商 | 广告商地址+ 0-31字节扫描响应数据 |
AUX_SCAN_REQ(英文) | 扫描仪 | 扫描仪地址+广告商地址 |
AUX_SCAN_RSP: | 广告商 | 报头(通用扩展广告有效载荷格式报头)+0—254字节数据 |
4 ccs上配置simple_central模版
ccs打开模版,系统配置打开simple_central.syscfg
并向下滚动到观察者部分 BLE配置选项卡。以下是默认扫描的屏幕截图设置.
在此任务中,我们将使用以下扫描参数连续扫描:
-
扫描间隔:150 ms
-
扫描窗口: 150 Ms
-
扫描持续时间:5 s
-
扫描类型: 被动
-
扫描PHY: LE 1M PHY(传统扫描)
一旦你改变了上述设置,打开显示生成的 文件视图(查找SysConfig窗口右上角的“ 查看#1中的更改。
-
在
gap_scanner.h
中,您可以找到有关可以为差距Scanner模块配置的所有参数的完整描述。
5 打印扫描结果
在扫描期间接收的用于发现设备广告的信息封装在GapScan_Evt_AdvRpt_t
结构中:
gap_scanner.h::GapScan_Evt_AdvRpt_t
gap_scanner.h::GapScan_Evt_AdvRpt_t
typedef struct {
uint8_t evtType; // Bits 0 to 4 indicate connectable, scannable, directed, scan rsp, and legacy respectively
GAP_Addr_Types_t addrType; // Public, random, public ID, random ID, or anonymous
uint8_t addr[B_ADDR_LEN]; // Address of the advertising device
GapScan_ScannedPhy_t primPhy; // PHY of the primary advertising channel
GapScan_ScannedPhy_t secPhy; // PHY of the secondary advertising channel
uint8_t advSid; // SID(0x00-0x0f) of the advertising PDU
int8_t txPower; // -127 dBm <= TX power <= 126 dBm
int8_t rssi; // -127 dBm <= RSSI <= 20 dBm
GAP_Addr_Types_t directAddrType; // Type of TargetA address in the directed advertising PDU
uint8_t directAddr[B_ADDR_LEN]; // TargetA address
uint16_t periodicAdvInt; // Periodic advertising interval. 0 means no periodic advertising.
uint16_t dataLen; // Length of the data
uint8_t *pData; // Pointer to advertising or scan response data
} GapScan_Evt_AdvRpt_t
打印接收到的广告数据。 首先,创建一个名为Util_convertBytes2Str()
的函数,将字节转换为 string.在util.c
中创建此函数。
util.c - 添加一个函数将字节转换为字符串。
char *Util_convertBytes2Str(uint8_t *pData, uint8_t length)
{
uint8_t charCnt;
char hex[] = "0123456789ABCDEF";
static char str[(3*31)+1];
char *pStr = str;
for (charCnt = 0; charCnt < length; charCnt++)
{
*pStr++ = hex[*pData >> 4];
*pStr++ = hex[*pData++ & 0x0F];
if(!((charCnt+1) >= length))
{
*pStr++ = ':';
}
}
str[(3*length)-1] = '\0';
pStr = NULL;
return str;
}
util.h —添加一个函数原型来将字节转换为字符串。
extern char *Util_convertBytes2Str(uint8_t *pData, uint8_t length);
然后将以下代码添加到SimpleCentral_processAppMsg()::SC_EVT_ADV_REPORT
case语句来打印接收到的广告和扫描响应分组。
simple_central.c::SimpleCentral_processAppMsg()::SC_EVT_ADV_REPORT —打印接收到的广告并扫描响应数据包。
case SC_EVT_ADV_REPORT:
{
GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
// === SOLUTION [Print scan results] ===
//Print scan response data or advertising data
if (pAdvRpt->evtType &= ADV_RPT_EVT_TYPE_SCAN_RSP)
{
Display_print1(dispHandle, 4, 0, "ScanResponseAddr: %s",
Util_convertBdAddr2Str(pAdvRpt->addr));
Display_print1(dispHandle, 5, 0, "ScanResponseData: %s",
Util_convertBytes2Str(pAdvRpt->pData, pAdvRpt->dataLen));
}
else
{
Display_print2(dispHandle, 6, 0, "Advertising Addr: %s RSSI: %d",
Util_convertBdAddr2Str(pAdvRpt->addr), pAdvRpt->rssi);
Display_print1(dispHandle, 7, 0, "Advertising Data: %s",
Util_convertBytes2Str(pAdvRpt->pData, pAdvRpt->dataLen));
}
// === END SOLUTION [Print scan results] ===
//Auto connect is enabled
if (autoConnect)
// ...
6.持续扫描
当应用程序需要始终扫描附近的设备时,即始终 如果处于扫描状态,则将DEFAULT_SCAN_DURATION
设置为0。 这将设置 设备连续扫描。或者,我们可以设置设备扫描 持续一段时间,然后定期休息。我们将通过 设置扫描持续时间和扫描周期如下:
-
扫描持续时间:1 s
-
扫描周期:5 s
-
当应用程序需要始终扫描附近的设备时,即始终 如果处于扫描状态,则将
DEFAULT_SCAN_DURATION
设置为0。 这将设置 设备连续扫描。或者,我们可以设置设备扫描 持续一段时间,然后定期休息。我们将通过 设置扫描持续时间和扫描周期如下: -
扫描持续时间:1 s
-
扫描周期:5 s
-
扫描持续时间可以在SysConfig中设置,但扫描周期必须在 应用程序.
扫描持续时间可以在SysConfig中设置,但扫描周期必须在 应用程序.
simple_central.c::SimpleCentral_doDiscoverDevices() - 将扫描持续时间和扫描周期配置为无限期扫描。
// === SOLUTION [Scan indefinitely] ===
//Scan period. Ignored if duration is zero. 1.28 sec unit
uint16_t scanPeriod = 4; // 4 * 1.28 s = 5.12 s.
GapScan_enable(scanPeriod, DEFAULT_SCAN_DURATION, 0);
// ==== END SOLUTION ====
DEFAULT_MAX_SCAN_RES
是 设置为0。如果为零,则忽略此参数。
7 过滤重复广告
默认情况下,扫描设备将 过滤广告数据。您可以通过导航到Observer来关闭此功能 "配置"选项卡并将"重复过滤器"设置为禁用。这将使控制器能够接收它看到的所有广告数据包 并将其发送到应用程序进行进一步处理。