根据您的需求,以下是禁用 PD 充电同时避免影响其他 MCU 功能的最佳实践:
分步解决方案:
动态修改 PDO(电源数据对象)而非完全停止 DPM
调用 dpm_stop() 可能会中断 PD 协议栈的底层状态机,导致意外行为(如端口复位)。建议通过以下方式实现:
条件触发时:移除所有 PDO(包括 5V),使端口无法协商供电。
// 获取当前 PDO 配置
cy_stc_pd_pdo_t *pdo_list;
uint8_t pdo_count = Cy_PD_Stack_Dpm_GetSourcePdos(port, &pdo_list);
// 清空 PDO 列表(禁用所有电源输出)
Cy_PD_Stack_Dpm_SetSourcePdos(port, 0, NULL);
// 可选:立即关闭 VBUS(若硬件支持)
Cy_PD_Stack_Dpm_DisableVbus(port);
- 条件解除时:恢复原始 PDO 配置。
Cy_PD_Stack_Dpm_SetSourcePdos(port, original_pdo_count, original_pdo_list);
Cy_PD_Stack_Dpm_EnableVbus(port); // 重新启用 VBUS
使用 GPIO 中断而非轮询
避免阻塞其他任务:
// 配置 GPIO 中断
Cy_GPIO_SetInterruptEdge(GPIO_PORT, GPIO_NUM, CY_GPIO_INTR_FALLING);
Cy_GPIO_SetInterruptMask(GPIO_PORT, GPIO_NUM, 1);
Cy_GPIO_ClearInterrupt(GPIO_PORT, GPIO_NUM);
在中断中设置标志,在主循环处理逻辑
保持中断处理轻量:
volatile bool disable_charge = false;
// GPIO 中断服务例程
void gpio_isr(void) {
disable_charge = (Cy_GPIO_Read(GPIO_PORT, GPIO_NUM) == condition);
Cy_GPIO_ClearInterrupt(GPIO_PORT, GPIO_NUM);
}
// 主循环
while(1) {
if (disable_charge) {
Cy_PD_Stack_Dpm_SetSourcePdos(port, 0, NULL);
} else {
Cy_PD_Stack_Dpm_SetSourcePdos(port, original_pdo_count, original_pdo_list);
}
}
关键注意事项:
- VBUS 控制:确保在禁用 PDO 后调用
Cy_PD_Stack_Dpm_DisableVbus() 以关闭物理电源输出。
- PD 协议兼容性:修改 PDO 会触发 PD 重新协商,确保设备端正确处理
Reject 或 Wait 状态。
- 硬件依赖:某些 CCG3PA 实现可能需要通过
Cy_PD_Stack_Dpm_UpdateSrcCap 通知协议栈更新电源能力。
验证方法:
- 使用协议分析仪(如 Total Phase)监控 PD 通信,确认禁用时无 Source Capabilities 广播。
- 测量 VBUS 电压,确保在条件触发时降至 0V。
- 测试其他 MCU 功能(如 UART、ADC)是否在禁用充电时正常运行。
此方法在保留 PD 协议栈运行的同时精准控制供电,避免全局状态机复位带来的副作用。
根据您的需求,以下是禁用 PD 充电同时避免影响其他 MCU 功能的最佳实践:
分步解决方案:
动态修改 PDO(电源数据对象)而非完全停止 DPM
调用 dpm_stop() 可能会中断 PD 协议栈的底层状态机,导致意外行为(如端口复位)。建议通过以下方式实现:
条件触发时:移除所有 PDO(包括 5V),使端口无法协商供电。
// 获取当前 PDO 配置
cy_stc_pd_pdo_t *pdo_list;
uint8_t pdo_count = Cy_PD_Stack_Dpm_GetSourcePdos(port, &pdo_list);
// 清空 PDO 列表(禁用所有电源输出)
Cy_PD_Stack_Dpm_SetSourcePdos(port, 0, NULL);
// 可选:立即关闭 VBUS(若硬件支持)
Cy_PD_Stack_Dpm_DisableVbus(port);
- 条件解除时:恢复原始 PDO 配置。
Cy_PD_Stack_Dpm_SetSourcePdos(port, original_pdo_count, original_pdo_list);
Cy_PD_Stack_Dpm_EnableVbus(port); // 重新启用 VBUS
使用 GPIO 中断而非轮询
避免阻塞其他任务:
// 配置 GPIO 中断
Cy_GPIO_SetInterruptEdge(GPIO_PORT, GPIO_NUM, CY_GPIO_INTR_FALLING);
Cy_GPIO_SetInterruptMask(GPIO_PORT, GPIO_NUM, 1);
Cy_GPIO_ClearInterrupt(GPIO_PORT, GPIO_NUM);
在中断中设置标志,在主循环处理逻辑
保持中断处理轻量:
volatile bool disable_charge = false;
// GPIO 中断服务例程
void gpio_isr(void) {
disable_charge = (Cy_GPIO_Read(GPIO_PORT, GPIO_NUM) == condition);
Cy_GPIO_ClearInterrupt(GPIO_PORT, GPIO_NUM);
}
// 主循环
while(1) {
if (disable_charge) {
Cy_PD_Stack_Dpm_SetSourcePdos(port, 0, NULL);
} else {
Cy_PD_Stack_Dpm_SetSourcePdos(port, original_pdo_count, original_pdo_list);
}
}
关键注意事项:
- VBUS 控制:确保在禁用 PDO 后调用
Cy_PD_Stack_Dpm_DisableVbus() 以关闭物理电源输出。
- PD 协议兼容性:修改 PDO 会触发 PD 重新协商,确保设备端正确处理
Reject 或 Wait 状态。
- 硬件依赖:某些 CCG3PA 实现可能需要通过
Cy_PD_Stack_Dpm_UpdateSrcCap 通知协议栈更新电源能力。
验证方法:
- 使用协议分析仪(如 Total Phase)监控 PD 通信,确认禁用时无 Source Capabilities 广播。
- 测量 VBUS 电压,确保在条件触发时降至 0V。
- 测试其他 MCU 功能(如 UART、ADC)是否在禁用充电时正常运行。
此方法在保留 PD 协议栈运行的同时精准控制供电,避免全局状态机复位带来的副作用。
举报