nRF connect SDK 获取蓝牙address

目录

概述

1. 获取设备的默认蓝牙地址

1.1 读取 NRF_FICR->DEVICEADDR

1.2  使用 bt_id_get() 获取当前使用的地址

2 获取对端设备的蓝牙地址

2.1 在连接建立后获取对端地址

2.2 在扫描时获取广播设备的地址

3. 使用 Shell 命令获取地址

4 总结

4.1 获取ADD方法

 4.2 注意事项


概述

在 nRF Connect SDK(基于 Zephyr RTOS)中,获取蓝牙设备的 MAC 地址(Bluetooth Address) 可以通过以下几种方式实现:

1. 获取设备的默认蓝牙地址

1.1 读取 NRF_FICR->DEVICEADDR

该方法仅适合于如下这些类型的芯片: nRF52/nRF53 系列

Nordic 芯片的 Factory Information Configuration Registers (FICR) 存储了默认的蓝牙地址(Public 或 Random Static):

#include <hal/nrf_ficr.h>

void print_default_ble_address(void) {
    uint32_t addr_low = NRF_FICR->DEVICEADDR[0];  // 低 4 字节
    uint32_t addr_high = NRF_FICR->DEVICEADDR[1]; // 高 2 字节

    uint8_t ble_addr[6] = {
        (addr_low >> 0) & 0xFF,   // 字节 0
        (addr_low >> 8) & 0xFF,    // 字节 1
        (addr_low >> 16) & 0xFF,   // 字节 2
        (addr_low >> 24) & 0xFF,   // 字节 3
        (addr_high >> 0) & 0xFF,   // 字节 4
        (addr_high >> 8) & 0xFF,   // 字节 5
    };

    printk("Factory BLE Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
           ble_addr[5], ble_addr[4], ble_addr[3],  // 高位在前
           ble_addr[2], ble_addr[1], ble_addr[0]);
}

⚠️ 注意

  • 某些芯片(如 nRF52840)的 FICR 地址是 只读 的。

  • 如果未烧录地址,可能返回 FF:FF:FF:FF:FF:FF 或随机值。

1.2  使用 bt_id_get() 获取当前使用的地址

#include <bluetooth/bluetooth.h>

void print_current_ble_address(void) {
    bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
    size_t count = CONFIG_BT_ID_MAX;

    // 获取所有已注册的蓝牙地址
    bt_id_get(addrs, &count);

    for (size_t i = 0; i < count; i++) {
        printk("BLE Address %d: %02X:%02X:%02X:%02X:%02X:%02X (type: %s)\n",
               i,
               addrs[i].a.val[5], addrs[i].a.val[4], addrs[i].a.val[3],
               addrs[i].a.val[2], addrs[i].a.val[1], addrs[i].a.val[0],
               addrs[i].type == BT_ADDR_LE_PUBLIC ? "Public" : "Random");
    }
}

输出示例

BLE Address 0: AA:BB:CC:DD:EE:FF (type: Random)

获取对端设备的蓝牙地址

2.1 在连接建立后获取对端地址

#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>

static void connected(struct bt_conn *conn, uint8_t err) {
    if (err) {
        printk("Connection failed (err %u)\n", err);
        return;
    }

    // 获取对端设备的蓝牙地址
    const bt_addr_le_t *addr = bt_conn_get_dst(conn);
    printk("Connected to: %02X:%02X:%02X:%02X:%02X:%02X (type: %s)\n",
           addr->a.val[5], addr->a.val[4], addr->a.val[3],
           addr->a.val[2], addr->a.val[1], addr->a.val[0],
           addr->type == BT_ADDR_LE_PUBLIC ? "Public" : "Random");
}

static struct bt_conn_cb conn_callbacks = {
    .connected = connected,
};

void main(void) {
    bt_conn_cb_register(&conn_callbacks);
}

2.2 在扫描时获取广播设备的地址

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>

static void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
                    struct net_buf_simple *buf) {
    printk("Device found: %02X:%02X:%02X:%02X:%02X:%02X (RSSI: %d)\n",
           addr->a.val[5], addr->a.val[4], addr->a.val[3],
           addr->a.val[2], addr->a.val[1], addr->a.val[0], rssi);
}

void start_scan(void) {
    struct bt_le_scan_param scan_param = {
        .type = BT_LE_SCAN_TYPE_PASSIVE,
        .options = BT_LE_SCAN_OPT_NONE,
        .interval = BT_GAP_SCAN_FAST_INTERVAL,
        .window = BT_GAP_SCAN_FAST_WINDOW,
    };

    bt_le_scan_start(&scan_param, scan_cb);
}

3. 使用 Shell 命令获取地址

如果启用了 Bluetooth Shell,可以直接通过终端命令获取地址:

# 查看本机地址
bt id-show

# 扫描周围设备
bt scan on

输出示例

[bt] [ID] 0: AA:BB:CC:DD:EE:FF (random static)

4 总结

4.1 获取ADD方法

方法适用场景代码示例
NRF_FICR->DEVICEADDR读取芯片出厂地址NRF_FICR->DEVICEADDR[0/1]
bt_id_get()获取当前使用的地址bt_id_get(addrs, &count)
bt_conn_get_dst()获取对端设备地址bt_conn_get_dst(conn)
扫描回调 scan_cb获取广播设备地址bt_le_scan_start()
Shell 命令快速调试bt id-show

 4.2 注意事项

  1. Public vs Random 地址

    • Public 地址需向 IEEE 申请,通常由芯片厂商预烧录。

    • Random Static 地址最高 2 位应为 11(如 0xCF:...)。

  2. 隐私模式(Privacy)

    • 如果启用了 CONFIG_BT_PRIVACY=y,设备会使用 Resolvable Private Address (RPA),此时 bt_id_get() 可能返回临时地址。

如果需要进一步处理地址(如转换为字符串),可以使用 bt_addr_le_to_str()

char addr_str[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
printk("Address: %s\n", addr_str);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值