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

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

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

在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)。

浙公网安备 33010602011771号