无线通信与快充协议适配指南

目录

  1. [蓝牙/BLE 无线通信模块](#1-蓝牙 ble 无线通信模块)
  2. [USB/Type-C 接口协议](#2-usbc-type-c 接口协议)
    • 2.1 [USB 2.0/3.0 数据传输](#21-usb-2030 数据传输)
    • 2.2 [Type-C 正反插检测](#22-type-c 正反插检测)
    • 2.3 [PD 功率传输协议](#23-pd 功率传输协议)
  3. 快充协议实现
    • 3.1 [QC 3.0 协议握手流程](#31-qc-30 协议握手流程)
    • 3.2 [PD 2.0 协议握手流程](#32-pd-20 协议握手流程)
    • 3.3 电压电流调节逻辑
    • 3.4 [沁恒 CH224 芯片使用](#34-沁恒-ch224 芯片使用)

1. 蓝牙/BLE 无线通信模块

1.1 模块选型

1.1.1 主流蓝牙/BLE 模块对比
模块型号厂商协议传输距离功耗成本适用场景
NRF52832NordicBLE 5.0100m超低可穿戴设备、传感器
NRF52840NordicBLE 5.0/Thread200m超低高端 IoT 设备
HC-05CSR经典蓝牙10m简单串口透传
HM-10TIBLE 4.030m低功耗应用
ESP32Espressif双模蓝牙+Wi-Fi100m多功能 IoT 设备
1.1.2 选型建议

选择 NRF52 系列的理由:

  • 超低功耗,适合电池供电设备
  • 完善的 SDK 和生态系统
  • 支持 BLE 5.0,传输速率高达 2Mbps
  • 丰富的 GPIO 和外设接口

选择 ESP8266/ESP32 的理由:

  • 集成 Wi-Fi 功能
  • 成本低廉
  • 社区活跃,资料丰富
  • 适合需要云端连接的应用

1.2 NRF52 系列初始化配置

1.2.1 硬件连接说明
NRF52832 最小系统连接:
VCC  → 3.3V
GND  → GND
P0.0 → UART RX
P0.1 → UART TX
P0.2 → LED 指示
P0.3 → 按键输入
1.2.2 工程配置步骤

下面是基于 Nordic SDK 的初始化代码示例:

/**
 * @file main.c
 * @brief NRF52832 BLE 初始化配置示例
 * 
 * 本示例展示如何配置 NRF52832 的 BLE 外设,
 * 包括时钟、GPIO、UART 和 BLE 协议栈的初始化
 */

#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_sdm.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "ble_conn_params.h"
#include "app_timer.h"
#include "app_uart.h"
#include "app_error.h"
#include "nrf_clock.h"

// 定义引脚配置
#define LED_PIN          NRF_GPIO_PIN_MAP(0, 2)      // LED 连接到 P0.2
#define BUTTON_PIN       NRF_GPIO_PIN_MAP(0, 3)      // 按键连接到 P0.3
#define UART_RX_PIN      NRF_GPIO_PIN_MAP(0, 9)      // UART RX 连接到 P0.9
#define UART_TX_PIN      NRF_GPIO_PIN_MAP(0, 10)     // UART TX 连接到 P0.10

// BLE 配置参数
#define APP_BLE_CONN_CFG_TAG            1           // BLE 连接配置标签
#define APP_BLE_OBSERVER_PRIO           3           // BLE 观察者优先级
#define DEVICE_NAME                     "Nordic_Ble" // 设备名称
#define ADV_INTERVAL                    MSEC_TO_UNITS(100, UNIT_0_625_MS) // 广播间隔 100ms

// 创建 BLE 堆栈事件处理函数
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            // 已连接到中央设备
            nrf_gpio_pin_set(LED_PIN);  // 点亮 LED
            break;
            
        case BLE_GAP_EVT_DISCONNECTED:
            // 与中央设备断开连接
            nrf_gpio_pin_clear(LED_PIN); // 熄灭 LED
            // 重新开始广播
            advertising_start();
            break;
            
        default:
            break;
    }
}

/**
 * @brief 初始化 SoftDevice(BLE 协议栈)
 * 
 * SoftDevice 是 Nordic 的 BLE 协议栈固件,
 * 需要在应用运行前加载到芯片中
 */
static void softdevice_init(void)
{
    ret_code_t err_code;
    
    // 使能外部高速时钟
    nrf_clock_external_xtal_enabled_set(true);
    
    // SoftDevice 配置结构体
    nrf_clock_lf_cfg_t clock_config = NRF_CLOCK_LFCLKCONFIG;
    
    // 初始化 SDH (SoftDevice Handler)
    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);
    
    // 配置 BLE 协议栈
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);
    
    // 启用 BLE 协议栈
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);
    
    // 注册 BLE 事件处理回调
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

/**
 * @brief 初始化 GPIO 引脚
 * 
 * 配置 LED 为输出模式,按键为输入模式
 */
static void gpio_init(void)
{
    // 配置 LED 引脚为输出模式
    nrf_gpio_cfg_output(LED_PIN);
    
    // 配置按键引脚为输入模式,带上拉电阻
    nrf_gpio_cfg_sense_input(BUTTON_PIN, 
                             NRF_GPIO_PIN_PULLUP,
                             NRF_GPIO_PIN_SENSE_LOW);
    
    // 初始状态:熄灭 LED
    nrf_gpio_pin_clear(LED_PIN);
}

/**
 * @brief 初始化 UART 串口通信
 * 
 * 用于调试信息输出和 AT 命令交互
 */
static void uart_init(void)
{
    ret_code_t err_code;
    
    // UART 配置结构体
    const app_uart_comm_params_t comm_params =
    {
        .rx_pin_no    = UART_RX_PIN,
        .tx_pin_no    = UART_TX_PIN,
        .rts_pin_no   = NRF_UART_PSEL_DISCONNECTED,
        .cts_pin_no   = NRF_UART_PSEL_DISCONNECTED,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity   = false,
        .baud_rate    = NRF_UART_BAUDRATE_115200
    };
    
    // 初始化 UART
    APP_UART_FIFO_INIT(&comm_params,
                       APP_UART_DRIVER_INSTANCE,
                       uart_event_handle,
                       APP_SCHEDULER_EVENT_SIZE,
                       APP_TIMER_QUEUES_SIZE,
                       err_code);
    APP_ERROR_CHECK(err_code);
}

/**
 * @brief 初始化 BLE 广播
 * 
 * 配置广播数据包,让其他设备能够发现本设备
 */
static void advertising_init(void)
{
    ret_code_t err_code;
    ble_advertising_init_t init;
    memset(&init, 0, sizeof(init));
    
    // 配置广播类型
    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false;
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
    // 配置广播参数
    init.config.interval_sec        = 0;
    init.config.timeout_sec         = 0;
    init.mode_first                 = BLE_ADV_MODE_FAST;
    init.fast_interval              = ADV_INTERVAL;
    
    // 初始化广播模块
    err_code = ble_advertising_init(&init);
    APP_ERROR_CHECK(err_code);
}

/**
 * @brief 开始 BLE 广播
 */
static void advertising_start(void)
{
    ret_code_t err_code;
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
}

/**
 * @brief 主函数
 * 
 * 程序入口点,依次初始化各个模块
 */
int main(void)
{
    // 1. 初始化 GPIO
    gpio_init();
    
    // 2. 初始化定时器
    app_timer_init();
    
    // 3. 初始化 UART
    uart_init();
    
    // 4. 初始化 SoftDevice(BLE 协议栈)
    softdevice_init();
    
    // 5. 初始化 BLE 广播
    advertising_init();
    
    // 6. 开始广播
    advertising_start();
    
    printf("NRF52832 BLE 初始化完成\r\n");
    
    // 主循环
    while (true)
    {
        // 进入低功耗模式,等待事件唤醒
        __WFE();
    }
}

代码说明:

上述代码完成了 NRF52832 的完整初始化流程:

  1. softdevice_init(): 初始化 BLE 协议栈,这是 Nordic 芯片特有的设计。SoftDevice 是一个预编译的 BLE 协议栈二进制文件,运行在独立的内核空间,应用程序通过 API 与之通信。

  2. gpio_init(): 配置 GPIO 引脚的工作模式。LED 配置为推挽输出模式,按键配置为上拉输入模式,这样可以检测按键按下 (低电平)。

  3. uart_init(): 初始化 UART 串口通信,用于打印调试信息和接收 AT 命令。这里使用 115200 波特率,无流控。

  4. advertising_init(): 配置 BLE 广播参数。广播是让其他 BLE 中央设备 (如手机) 能够发现本设备的过程。

  5. advertising_start(): 启动广播,设备开始对外发送广播包。

1.3 ESP8266 Wi-Fi 模块配置

1.3.1 硬件连接
ESP8266 NodeMCU 引脚定义:
VIN  → 5V (或 3.3V)
GND  → GND
D1   → I2C SCL
D2   → I2C SDA
D5   → SPI SCK
D6   → SPI MISO
D7   → SPI MOSI
TX   → UART 连接到 MCU RX
RX   → UART 连接到 MCU TX
1.3.2 Arduino IDE 环境配置
/**
 * @file esp8266_wifi.ino
 * @brief ESP8266 Wi-Fi 客户端配置示例
 * 
 * 实现 ESP8266 连接 Wi-Fi 网络并通过 TCP 发送数据
 */

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

// Wi-Fi 配置
const char* ssid = "YourWiFi_SSID";
const char* password = "YourWiFi_Password";

// 服务器配置
const char* server_host = "192.168.1.100";
const int server_port = 8080;

// LED 指示灯
#define LED_PIN 2  // ESP8266 板载 LED 连接到 GPIO2

/**
 * @brief Wi-Fi 连接函数
 * 
 * 尝试连接到指定的 Wi-Fi 网络,
 * 连接成功后会通过串口打印 IP 地址
 */
void connectWiFi() {
  Serial.println("开始连接 Wi-Fi...");
  WiFi.begin(ssid, password);
  
  // 等待连接,最多尝试 20 次
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    delay(500);
    Serial.print(".");
    attempts++;
  }
  
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWi-Fi 连接成功!");
    Serial.print("IP 地址:");
    Serial.println(WiFi.localIP());
    
    // 快速闪烁 3 次表示成功
    for(int i = 0; i < 3; i++) {
      digitalWrite(LED_PIN, HIGH);
      delay(100);
      digitalWrite(LED_PIN, LOW);
      delay(100);
    }
  } else {
    Serial.println("\nWi-Fi 连接失败!");
    // 慢速闪烁表示失败
    while(true) {
      digitalWrite(LED_PIN, HIGH);
      delay(500);
      digitalWrite(LED_PIN, LOW);
      delay(500);
    }
  }
}

/**
 * @brief 发送 HTTP GET 请求
 * 
 * 向指定服务器发送 HTTP GET 请求并获取响应
 */
void sendHttpRequest() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    
    // 构建 URL
    String url = "http://" + String(server_host) + ":" + String(server_port) + "/api/data";
    
    Serial.println("发送 HTTP 请求:" + url);
    
    // 发起 HTTP GET 请求
    http.begin(url);
    int httpCode = http.GET();
    
    // 检查响应码
    if (httpCode > 0) {
      Serial.printf("HTTP 响应码:%d\n", httpCode);
      
      if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        Serial.println("响应内容:");
        Serial.println(payload);
      }
    } else {
      Serial.printf("HTTP 请求失败,错误码:%d\n", httpCode);
    }
    
    http.end();  // 关闭连接
  } else {
    Serial.println("Wi-Fi 未连接,无法发送 HTTP 请求");
  }
}

/**
 * @brief 建立 TCP 连接并发送数据
 * 
 * 使用 WiFiClient 直接建立 TCP 连接发送原始数据
 */
void sendTcpData(const char* data) {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Wi-Fi 未连接");
    return;
  }
  
  WiFiClient client;
  
  Serial.print("连接到服务器 ");
  Serial.print(server_host);
  Serial.print(":");
  Serial.println(server_port);
  
  // 尝试连接服务器
  if (!client.connect(server_host, server_port)) {
    Serial.println("连接服务器失败");
    return;
  }
  
  Serial.println("服务器连接成功");
  
  // 发送数据
  client.print(data);
  Serial.print("已发送数据:");
  Serial.println(data);
  
  // 等待服务器响应
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println("服务器响应超时");
      client.stop();
      return;
    }
  }
  
  // 读取响应
  while (client.available()) {
    String response = client.readStringUntil('\r');
    Serial.print(response);
  }
  
  Serial.println("\n连接关闭");
  client.stop();
}

void setup() {
  // 初始化串口
  Serial.begin(115200);
  delay(100);
  
  // 配置 LED
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  
  Serial.println("\n=== ESP8266 Wi-Fi 配置示例 ===");
  
  // 连接 Wi-Fi
  connectWiFi();
}

void loop() {
  // 每 5 秒发送一次 HTTP 请求
  sendHttpRequest();
  delay(5000);
}

代码说明:

这段 Arduino 代码展示了 ESP8266 的 Wi-Fi 客户端功能:

  1. connectWiFi(): 实现 Wi-Fi 连接的完整流程,包含重试机制和状态指示。

  2. sendHttpRequest(): 使用 HTTPClient 库发送 HTTP GET 请求,适用于 RESTful API 调用。

  3. sendTcpData(): 使用底层的 WiFiClient 直接建立 TCP 连接,适合自定义协议通信。

1.4 数据透传实现

1.4.1 蓝牙串口透传 (SPP over BLE)

BLE 串口透传允许设备与手机之间进行双向串口数据传输,类似于传统蓝牙的 SPP 协议。

实现要点:

  • 使用 Nordic UART Service (NUS) 或类似服务
  • 定义 RX/TX 两个特征
  • RX 特征用于接收数据 (写操作)
  • TX 特征用于发送数据 (通知)
1.4.2 Wi-Fi TCP 透传

Wi-Fi TCP 透传实现设备与服务器之间的长连接双向通信。

实现要点:

  • 建立稳定的 TCP 连接
  • 实现自动重连机制
  • 处理数据缓冲和流量控制
  • 支持心跳包保持连接

2. USB/Type-C 接口协议

2.1 USB 2.0/3.0 数据传输

2.1.1 USB 通信基础

USB (Universal Serial Bus) 是一种通用的串行总线标准,支持即插即用和热插拔功能。

USB 2.0 vs USB 3.0 对比:

特性USB 2.0USB 3.0
最大传输速率480 Mbps5 Gbps
数据线数量2 (D+, D-)5 (D+, D-, Tx+, Tx-, Rx+, Rx-)
供电能力5V/0.5A (2.5W)5V/0.9A (4.5W)
连接器类型Type-A, Type-B, Mini, MicroType-A, Type-B, Type-C
全双工通信否 (半双工)是 (全双工)
2.1.2 STM32 USB 设备实现

STM32 微控制器内置 USB 外设,可以配置为 USB 设备、主机或 OTG 模式。

配置步骤:

  1. 使用 STM32CubeMX 配置 USB 外设
  2. 选择 USB Device 模式
  3. 选择 CDC (虚拟串口) 类
  4. 生成代码并添加应用逻辑

2.2 Type-C 正反插检测

2.2.1 Type-C 接口电气特性

Type-C 接口的关键特性:

  • 支持正反插拔
  • 通过 CC (Configuration Channel) 引脚检测连接方向
  • 支持 USB PD 功率传输协议
  • 最大支持 20V/5A (100W) 功率传输
2.2.2 CC 引脚检测原理

Type-C 插头内部在 CC 引脚上有上拉电阻 (源端) 或下拉电阻 (设备端)。通过检测 CC 引脚的电压可以判断:

  • 是否有设备连接
  • 插头的方向 (正向或反向)
  • 附件类型

电压判断逻辑:

  • 未连接: CC1 和 CC2 都接近 0V
  • 正向插入: CC1 高电平 (约 5V),CC2 低电平
  • 反向插入: CC2 高电平,CC1 低电平
  • 调试附件: CC1 和 CC2 都高电平

2.3 PD 功率传输协议

2.3.1 USB PD 协议基础

USB Power Delivery (PD) 是一种智能功率传输协议,允许设备之间协商电压和电流。

PD 协议关键特性:

  • 支持电压:5V, 9V, 15V, 20V
  • 支持电流:最高 5A
  • 最大功率:100W (20V×5A)
  • 通信方式:通过 CC 引脚使用 BMC 编码
2.3.2 PD 通信物理层

BMC 编码 (Biphase Mark Code) 是 PD 协议的物理层编码方式:

  • 每个位周期中间都有跳变
  • 逻辑 1 在位周期开始时有额外跳变
  • 逻辑 0 在位周期开始时无跳变
  • 位时间:1μs

3. 快充协议实现

3.1 QC 3.0 协议握手流程

3.1.1 QC 协议概述

Quick Charge (QC) 是高通公司开发的快充协议,QC 3.0 支持 3.6V-20V 范围内的动态电压调节。

QC 3.0 关键特性:

  • 电压范围:3.6V - 20V (以 200mV 步进)
  • 最大电流:3A
  • 向下兼容:QC 2.0、普通 USB
  • 通信方式:通过 D+ 线电压脉冲调制
3.1.2 QC 3.0 握手流程

步骤 1:检测 QC 充电器

  • 检测设备是否连接到 QC 充电器
  • D+ 电压特征识别

步骤 2:握手请求

  • 发送连续脉冲序列
  • 告知充电器设备支持 QC 协议

步骤 3:电压请求

  • 发送特定数量的脉冲
  • 每个脉冲代表一个电压等级

步骤 4:电压确认

  • 充电器调整输出电压
  • 设备检测确认电压正确

3.2 PD 2.0 协议握手流程

3.2.1 PD 通信消息类型

PD 协议定义了多种消息类型:

  1. Source_Capabilities: 电源提供能力
  2. Request: 电源请求
  3. Accept: 接受请求
  4. PS_RDY: 电源就绪
  5. Get_Status: 获取状态
3.2.2 完整握手流程
设备                      充电器
 |                          |
 |←-- Source_Capabilities --|  (充电器发送支持的能力)
 |                          |
 |------- Request --------->|  (设备请求特定电压电流)
 |                          |
 |←------- Accept ----------|  (充电器接受请求)
 |                          |
 |←------- PS_RDY ---------|  (充电器准备就绪,开始输出)
 |                          |
 |-- GoodCRC -------------->|  (确认收到)
 |                          |

3.3 电压电流调节逻辑

3.3.1 闭环反馈控制

为保证输出电压稳定,需要使用闭环反馈控制:

  1. ADC 采样: 实时采集输出电压
  2. 误差计算: 与目标电压比较得到误差
  3. PID 调节: 通过 PID 算法调节 PWM 占空比
  4. PWM 输出: 控制 DC-DC 变换器
3.3.2 PID 控制算法
// PID 控制结构体
typedef struct {
    float Kp;          // 比例系数
    float Ki;          // 积分系数
    float Kd;          // 微分系数
    float setpoint;    // 设定值
    float integral;    // 积分项
    float prev_error;  // 上次误差
    float output_max;  // 输出限幅
} PID_Controller_t;

// PID 计算函数
float PID_Calculate(PID_Controller_t* pid, float measured_value)
{
    float error = pid->setpoint - measured_value;
    
    // 比例项
    float proportional = pid->Kp * error;
    
    // 积分项 (带抗饱和)
    pid->integral += error;
    if (pid->integral > pid->output_max) {
        pid->integral = pid->output_max;
    }
    float integral_term = pid->Ki * pid->integral;
    
    // 微分项
    float derivative = pid->Kd * (error - pid->prev_error);
    
    pid->prev_error = error;
    
    // 计算总输出
    float output = proportional + integral_term + derivative;
    
    // 输出限幅
    if (output > pid->output_max) {
        output = pid->output_max;
    }
    if (output < -pid->output_max) {
        output = -pid->output_max;
    }
    
    return output;
}

3.4 沁恒 CH224 芯片使用

3.4.1 CH224K 简介

CH224K 是沁恒微电子推出的 USB PD 受电端协议芯片,支持:

  • USB PD 2.0/3.0协议
  • QC 2.0/3.0协议
  • 支持 5V/9V/12V/15V/20V 电压请求
  • 内置 VBUS 放电电路
  • SOP 物理层集成
3.4.2 硬件连接
CH224K 典型应用电路:
VBUS → 电源输入 (5-20V)
GND  → 地
D+   → USB D+ 数据线
D-   → USB D- 数据线
CC   → Type-C CC 引脚
OUT  → 协议请求输出 (控制 DC-DC)
3.4.3 配置方法

CH224K 通过外围电阻配置请求电压:

请求电压R1 阻值R2 阻值
5V不焊接200kΩ
9V51kΩ200kΩ
12V100kΩ200kΩ
15V150kΩ200kΩ
20V200kΩ200kΩ
3.4.4 应用电路示例
Type-C 接口 ──→ CH224K ──→ DC-DC 变换器 ──→ 负载
                │
                ├─→ VBUS 检测
                ├─→ CC 通信
                └─→ OUT 控制信号

工作原理:

  1. CH224K 通过 CC 引脚与充电器进行 PD 通信
  2. 根据配置的电阻值请求相应电压
  3. 握手成功后,OUT 引脚输出控制信号
  4. DC-DC 变换器将 VBUS 转换为设备所需电压

总结

本指南详细介绍了无线通信 (蓝牙/BLE/Wi-Fi) 和快充协议 (QC/PD) 的实现方法,包括:

  1. 模块选型与初始化: NRF52、ESP8266等主流模块的配置
  2. 数据透传: BLE 串口和 Wi-Fi TCP 的双向通信实现
  3. USB/Type-C: 接口检测、PD 协议物理层
  4. 快充协议: QC 3.0、PD 2.0 的完整握手流程和电压调节
  5. 实用芯片: CH224K 等协议芯片的使用方法
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐