【WCH蓝牙系列芯片】-基于CH592开发板—2.4G方式接收BLE广播数据

------------------------------------------------------------------------------------------------------------------------------------ 

  在之前讲述一次,利用2.4G模拟BLE的广播包格式,这样不需要走标准的蓝牙协议去实现,而是利用2.4G模拟发送蓝牙广播数据,在这个基础上,在讲述一下如果利用2.4G 射频底层(RF_PHY)方式接收BLE的广播数据,并且解析出现蓝牙广播包数据的内容信息。

  在RF_PHY-非标准无线收发例程的基础上进行修改,在射频初始化 (RF_Init)中,配置BLE广播的固定接入地址0x8E89BED6,通信信道设置为37,但是由于BLE 规定了 3 个专门用来发广播的信道,分别是 37 (2402MHz)、38 (2426MHz)、39 (2480MHz)。标准的BLE设备会在这三个信道轮询发包,这次只是针对37单个信道进行被动扫描。再将CRC校验初始值设置为0x555555。

image

  再初始化之后,上电开启触发接收事件,启动监听扫描,

image

  在RF_ProcessEvent的RF事件处理中,处理接收RF接收的任务事件,调用RF_Rx开启只接收模式,RF_Rx(NULL, 0, 0xFF, 0xFF); 这个里面第一个参数改为NULL,是为了在接收模式下不进行发送数据处理。

image

  在RF_2G4StatusCallBack的RF 状态回调中,在接收模式中接收数据中,当CH592抓到了空中匹配 0x8E89BED6 的数据包,会立刻打断主程序,进入这个硬件中断回调函数,数据全部存放在 rxBuf 指针指向的内存中。

        // 接收模式:接收到数据
        case RX_MODE_RX_DATA:
        {
            if (!crc) {  // CRC校验通过,说明抓到了一个合法的包
                int8_t rssi = (int8_t)rxBuf[0];
                // 【RSSI 过滤】
                // 比如设置为 -40,就只解析大于或等于 -40 dBm 的设备广播包
                if (rssi >= -40) {
                    printf("**********************************************\r\n");
                    PRINT("\r\n--- Receive BLE data---\r\n");
                    PRINT("RSSI: %d dBm\n", rssi);
                    PRINT("PDU Len: %d\n", rxBuf[1]);

                    if(rxBuf[1] >= 6) {
                        // 倒序打印 MAC 地址
                        PRINT("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
                                rxBuf[7], rxBuf[6], rxBuf[5], rxBuf[4], rxBuf[3], rxBuf[2]);
                    }

                    // 【解析并打印蓝牙名称】
                    // 广播数据从 rxBuf[8] 开始,长度为总长度 rxBuf[1] 减去 6 字节的 MAC
                    uint8_t adv_len = rxBuf[1] - 6;
                    uint8_t *adv_data = &rxBuf[8];
                    uint8_t index = 0;
                    uint8_t name_found = 0;

                    PRINT("BLE Name: ");
                    // 遍历 广播数据
                    while (index < adv_len) {
                        uint8_t ad_len = adv_data[index]; // 当前数据块长度
                        //如果长度为0或者越界,立刻跳出防止死循环
                        if (ad_len == 0 || (index + 1 + ad_len > adv_len)) {
                            break;
                        }

                        uint8_t ad_type = adv_data[index + 1]; // 当前数据块类型
                        // 0x08: 简写本地名称 (Shortened Local Name)
                        // 0x09: 完整本地名称 (Complete Local Name)
                        if (ad_type == 0x08 || ad_type == 0x09) {
                            uint8_t name_len = ad_len - 1; // 减去 1 字节的 Type
                            for (uint8_t j = 0; j < name_len; j++) {
                                PRINT("%c", adv_data[index + 2 + j]); // 打印 ASCII 字符
                            }
                            name_found = 1;
                            break; // 找到名字后就可以结束解析循环了
                        }
                        // 索引跳到下一个 数据块:当前索引 + Length字节本身(1字节) + ad_len
                        index += (1 + ad_len);
                    }

                    if (!name_found) {
                        PRINT("N/A (No Name or Hidden)");
                    }
                    PRINT("\n");

                    // 打印原始数据
                    PRINT("Raw Data ( MAC+ LEN + AdvData): ");
                    for (uint8_t i = 0; i < rxBuf[1]; i++) {
                        PRINT("%02X ", rxBuf[i + 2]);
                    }
                    PRINT("\n");
                }
            }
            // 处理完当前包后,再次开启接收事件,让芯片继续回到接收模式
            tmos_set_event(taskID, SBP_RF_RF_RX_EVT);
            break;
        }

在底层协议中,已经将接收的数据放在rxBuf中,

rxBuf[0]设备的 RSSI 信号强度。可以通过这个数据进行过滤处理,减少无效的广播包数据。

rxBuf[1]数据总长度(包含 MAC 地址和广播内容)。

rxBuf[2] ~ rxBuf[7]设备的 6 字节 MAC 地址(注意:大小端处理,BLE 规定低位在前,需要倒序读取!)。

rxBuf[8] ~ 末尾BLE的广播数据。在这个广播数据中,可以根据数据类型来判断数据是什么含义。

  利用上次写的2.4G模拟BLE广播包的程序,作为蓝牙广播发送的,将这个蓝牙发送的广播包数据进行扫描,并将广播包的数据解析打印,从打印中可以看到设备的MAC地址,还有设置的蓝牙广播名字,还有厂商自定义的数据(数据类型是0xFF)。

image

  在使用时,需要注意一下,蓝牙广播中其实包含蓝牙广播包和扫描应答包,但是这个在扫描时,我们不发生扫描请求,一般是拿不到扫描请求包的,只能拿到蓝牙的广播包数据

 

posted on 2026-04-02 16:58  凡仕  阅读(0)  评论(0)    收藏  举报