# 安信可蓝牙遥控器 **Repository Path**: ljc2025/pb03f ## Basic Information - **Project Name**: 安信可蓝牙遥控器 - **Description**: 基于PHY6222 BLE 5.1芯片的中心设备摇杆控制器项目。采用OSAL事件驱动架构,通过ADC中断采集双轴模拟摇杆方向,经滤波、校准和防抖处理后,自动连接BLE从设备并发送方向控制指令(上/下/左/右/停止/按下)。支持按键输入、自动重连和重试机制,适用于无线遥控场景。 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-08 - **Last Updated**: 2026-10-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MysimpleBleCentral - BLE 中心设备摇杆控制器 基于 PHY62XX SDK 3.1.5 的 BLE Central(中心/主设备)应用示例。该项目使用模拟摇杆(Joystick)作为输入,通过 BLE 无线连接向从设备发送方向控制指令。 ## 硬件平台 | 项目 | 说明 | |------|------| | 芯片 | PHY6222(Cortex-M0,BLE 5.1) | | 时钟 | 主频 48MHz DLL,32KHz RCOSC | | Flash | 256KB | | RAM | 64KB | | 封装 | QFN32(23 IO)/ TSOP6252(10 IO) | ## 功能概述 本项目实现了一个 **BLE 中心设备(Central/Master)**,核心功能如下: 1. **摇杆 ADC 采集**:通过 ADC 中断模式实时采集双轴模拟摇杆的 X 轴(P14)和 Y 轴(P20)电压值,经过滤波、动态中心校准和防抖状态机处理后,输出稳定的方向状态(上/下/左/右/停止)。 2. **按键输入**:P11 引脚配置为 GPIO 中断输入(下降沿触发),支持摇杆按下事件,带 20ms 硬件防抖。 3. **BLE 中心设备**:自动扫描并连接目标 BLE 从设备,发现 `0xFFE0` 服务及特征,将摇杆方向和按键事件通过 GATT Write 写入到从设备的 `0xFFE1` 特征中。 4. **任务间通信**:ADC 任务与 BLE 任务之间通过 OSAL 消息机制实现异步数据传递。BLE 任务内部维护"最新待发送方向"状态(`pending_dir`/`pending_valid`),新方向覆盖旧方向,过期方向不再保留。STOP 具有最高优先级,发送失败时自动重试。 ### 方向映射表 | 摇杆方向 | 发送字符 | dir_t 枚举值 | |----------|----------|--------------| | 上(UP) | `A` | `DIR_W` | | 下(DOWN) | `E` | `DIR_S` | | 左(LEFT) | `B` | `DIR_A` | | 右(RIGHT) | `F` | `DIR_D` | | 按下(PRESS) | `p` | `DIR_PRESS` | | 停止(STOP) | `Z` | `DIR_STOP` | > 非法方向值统一映射为 `Z`(STOP),确保安全。 ## 项目结构 ``` MysimpleBleCentral/ ├── .gitignore.txt # Git 忽略规则 ├── .vscode/ # VSCode 配置 ├── Source/ # 应用层源代码 │ ├── main.c # 系统入口,硬件初始化,BLE 内存配置 │ ├── simpleBLECentral.c # BLE 中心设备核心逻辑(扫描/连接/服务发现/GATT写入/重连同步) │ ├── simpleBLECentral.h # BLE 中心设备事件定义与接口声明 │ ├── OSAL_simpleBLECentral.c # OSAL 任务注册表(任务初始化顺序) │ ├── app_common.c # 通用模块:方向到字符映射函数 │ ├── app_common.h # 通用定义:方向枚举、自定义消息类型 │ ├── adc_demo.c # ADC 摇杆采集任务(中断模式,含滤波、状态机、重试) │ ├── adc_demo.h # ADC 任务接口声明(含方向状态重置) │ └── adc_config.h # ADC 运行模式配置 ├── components/ # SDK 组件 │ ├── adc/ # ADC 驱动 │ ├── clock/ # 时钟管理 │ ├── flash/ # Flash 驱动 │ ├── gpio/ # GPIO 驱动 │ ├── key/ # 按键驱动 │ ├── log/ # 日志模块 │ ├── osal_snv/ # OSAL 非易失存储 │ ├── profile/ # BLE Profile 层 │ ├── pwrmgr/ # 电源管理 │ ├── timer/ # 定时器 │ ├── uart/ # UART 驱动 │ └── voice/ # 语音模块 ├── simpleBleCentral.uvprojx # Keil uVision5 工程文件 ├── simpleBleCentral.uvoptx # Keil 工程选项 ├── scatter_load.sct # 链接脚本(分散加载文件) ├── ram.ini # RAM 调试初始化脚本 ├── ram_xip.ini # XIP 模式调试脚本 ├── Objects/ # 编译输出(.o, .axf 等) ├── Listings/ # 编译列表文件 └── bin/ # 最终二进制输出(.bin, .hex) ``` ## 硬件接线 ### 摇杆模块 | 摇杆引脚 | PHY6222 引脚 | 功能 | |----------|-------------|------| | VRx(X轴) | P14 | ADC_CH2P,模拟输入 | | VRy(Y轴) | P20 | ADC_CH3P,模拟输入 | | SW(按键) | P11 | GPIO 输入,内部上拉,下降沿中断 | | VCC | 3.3V | 供电 | | GND | GND | 地线 | ### UART 调试串口 | 功能 | PHY6222 引脚 | |------|-------------| | TX | P09 | | RX | P10 | | 波特率 | 115200 | ## 软件架构 ### OSAL 任务层次 系统基于 OSAL(操作系统抽象层)事件驱动架构,任务注册顺序如下: | 任务 ID | 任务名称 | 说明 | |---------|----------|------| | 0 | LL_ProcessEvent | 链路层 | | 1 | HCI_ProcessEvent | HCI 接口层 | | 2 | OSAL Callback Timer | 回调定时器 | | 3 | L2CAP_ProcessEvent | 逻辑链路控制 | | 4 | GAP_ProcessEvent | 通用访问配置 | | 5 | GATT_ProcessEvent | 通用属性协议 | | 6 | SM_ProcessEvent | 安全管理 | | 7 | GAPCentralRole_ProcessEvent | GAP 中心角色 | | 8 | GAPBondMgr_ProcessEvent | 绑定管理 | | 9 | GATTServApp_ProcessEvent | GATT 服务应用 | | 10 | SimpleBLECentral_ProcessEvent | **BLE 中心设备应用** | | 11 | adc_ProcessEvent | **ADC 摇杆采集** | > ADC 任务通过 `SimpleBLECentral_GetTaskId()` 显式获取 BLE 任务 ID,不再依赖 `task_id - 1` 推导。 ### BLE 连接流程 ``` 系统上电 │ ├─ hal_rfphy_init() ── RF 射频初始化 ├─ hal_init() ── GPIO / Flash / 电源管理初始化 ├─ LOG_INIT() ── 串口日志初始化 └─ app_main() │ └─ SimpleBLECentral_Init() │ ├─ 读取 Flash 中的目标地址 (0x11004008) │ ├─ 地址为 0xFF... → 按名称 "XLBLE" 扫描 │ └─ 有效地址 → 按 MAC 白名单直连 │ └─ GAPCentralRole_StartDevice() │ ├─ GAP_DEVICE_INIT_DONE_EVENT → 开始扫描/直连 ├─ GAP_DEVICE_INFO_EVENT → 收集广播数据 ├─ GAP_DEVICE_DISCOVERY_EVENT → 扫描完成,选择目标设备 ├─ GAP_LINK_ESTABLISHED_EVENT → 连接建立 │ ├─ MTU 协商 (247) │ ├─ DLE 数据长度扩展 (251 bytes) │ ├─ PHY 更新 (BLE 2M 可选) │ └─ 启动服务发现 (0xFFE0) │ └─ 服务/特征发现完成 ├─ 设置 targetCharHandle (0xFFE1 value handle) ├─ 重连同步:强制发送一次 STOP(resync_pending) └─ 进入数据通信阶段 ``` ### 断线与重连 ``` GAP_LINK_TERMINATED_EVENT(断线) │ ├─ targetCharHandle = 0 # 清除旧句柄,避免向无效句柄写入 ├─ pending_valid = FALSE # 清除待发送方向 ├─ last_sent_dir = DIR_STOP # 重置已发送方向 ├─ resync_pending = FALSE # 清除重连同步标志 └─ adc_reset_dir_state() # 重置 ADC 侧方向状态 └─ 使下一采样周期重新发送当前方向 重连后 FFE1 发现完成 │ ├─ resync_pending = TRUE # 标记需要强制同步 ├─ pending_dir = DIR_STOP # 先发送 STOP 确保远端安全 └─ pending_valid = TRUE # 触发 GATT 写入 ``` ### ADC 摇杆数据流 ``` ADC 中断回调 (adc_evt) │ ├─ 原始值平均滤波(uint32_t 累加,防溢出) ├─ 低通滤波 (filt = filt*7/10 + raw*3/10) ├─ 动态中心校准 ├─ 阈值判断 → joystick_calc_state() ├─ 防抖状态机 (stable_cnt >= 2) │ └─ 方向变化或 stop_pending 时 ├─ osal_msg_send() → BLE 任务 │ ├─ 成功:更新 last_stable_dir │ └─ 失败:保留 last_stable_dir,下周期重试 │ └─ STOP 失败额外设置 stop_pending │ └─ BLE 任务收到 ADC_DIR_MSG_EVT ├─ pending_dir = 最新方向(覆盖旧值) ├─ pending_valid = TRUE └─ 触发 START_CHAR_DATA_TEST (50ms) └─ simpleBLECentral_ReadWriteNotifyTest() ├─ osal_mem_alloc 判空 ├─ GATT_WriteNoRsp() 写入 0xFFE1 │ ├─ 成功:更新 last_sent_dir,清除 pending │ └─ 失败:保留 pending,定时重试 └─ 分配失败:限频日志,定时重试 ``` ## 关键配置参数 ### BLE 连接参数 | 参数 | 值 | 说明 | |------|-----|------| | `BLE_MAX_ALLOW_CONNECTION` | 1 | 最大连接数 | | `DEFAULT_MAX_SCAN_RES` | 30 | 最大扫描结果数 | | `DEFAULT_SCAN_DURATION` | 10000ms | 扫描持续时间 | | `DEFAULT_DISCOVERY_ACTIVE_SCAN` | TRUE | 主动扫描 | | `mtu` | 247 | ATT MTU 大小 | | `dleTxOctets` | 251 | DLE 发送字节数 | | `phyModeCtrl` | 0x01 (BLE 1M) | PHY 模式 | | `DEFAULT_PASSCODE` | 123456 | 配对密码 | ### ADC 配置 | 参数 | 值 | 说明 | |------|-----|------| | `ADC_MEASURE_INTERVAL_MS` | 50ms | 采集间隔 | | `JOYSTICK_THRESHOLD` | 80 | 方向判断 ADC 阈值 | | `STABLE_REQUIRED` | 2 | 防抖连续一致次数 | | `OUTPUT_THROTTLE_COUNT` | 4 | 输出节拍计数 | | `ADC_CONFIG_MAX_RETRIES` | 3 | ADC 配置失败最大重试次数 | | `ADC_CONFIG_RETRY_DELAY` | 100ms | 配置失败后重试间隔 | | 采集模式 | 中断模式 | `ADC_RUNMODE_INTERRUPT` | | X轴通道 | ADC_CH2P_P14 | 单端,高分辨率 | | Y轴通道 | ADC_CH3P_P20 | 单端,高分辨率 | ### 可靠性与重试参数 | 参数 | 值 | 说明 | |------|-----|------| | `GATT_WRITE_RETRY_INTERVAL_MS` | 50ms | GATT 写入失败后重试间隔 | | `MAX_SAMPLE_POINT` | 64 | ADC 单次最大采样点数(越界保护) | | `stop_pending` | 模块级标志 | STOP 发送失败时置位,下周期强制重试 | | `resync_pending` | 模块级标志 | 重连后强制发送一次 STOP | | `pending_dir`/`pending_valid` | 模块级变量 | BLE 任务内最新待发送方向状态 | ### 内存布局 | 区域 | 地址范围 | 大小 | 说明 | |------|----------|------|------| | Jump Table | 0x1FFF0000 | 1KB | ROM 跳转表 | | Global Config | 0x1FFF0400 | 1KB | 全局配置 | | 代码 (RAM) | 0x1FFF1838 | ~58KB | 应用代码 | | XIP 代码 | 0x11020000 | 192KB | Flash XIP 执行(GATT/GAP 等协议栈) | | Large Heap | - | 4KB | OSAL 动态内存 | | LL Link Heap | - | 动态 | BLE 链路层缓冲 | ## 开发环境 - **IDE**: Keil uVision 5(ARMCC V5.06) - **SDK**: PHY62XX SDK 3.1.5 - **调试器**: J-Link / DAP-Link(通过 `ram.ini` 配置) - **串口工具**: 115200 baud, 8N1 ## 编译与烧录 1. 使用 Keil uVision 5 打开 `simpleBleCentral.uvprojx` 2. 编译工程(F7) 3. 编译产物自动输出到 `bin/` 目录: - `simpleBleCentral.bin` — 二进制固件 - `simpleBleCentral.hex` — Intel HEX 格式 4. 通过烧录工具将固件下载到 PHY6222 ## 目标设备配置 中心设备连接的目标从设备地址存储在 Flash 地址 `0x11004008`: - 若地址首字节为 `0xFF`,则按设备名称 `"XLBLE"` 进行扫描匹配 - 若为有效 MAC 地址,则直接加入白名单并建立连接 目标 BLE 服务 UUID 为 `0xFFE0`,写入特征 UUID 为 `0xFFE1`。 ## 许可证 本项目代码基于 Phyplus Microelectronics Limited 的 PHY62XX SDK,受其许可协议约束。SDK 组件版权归属 Phyplus Microelectronics Limited。