自制QC2.0诱骗器

实际上,安卓手机的快充头就是一个可以更改副边反馈比的可调压开关电源。拥有一个快充头,对我们来说,就是拥有了一个可以调整输出电压的电源。我们只需要模拟手机与快充头进行握手,就可以激活高电压快充协议,进而将快充头变成一个DC电源。

快充协议的握手部分在副边部分,当快充头和手机握手成功时,副边的快充控制芯片就会调整反馈给原边的反馈比,使原边的开关电源占空比升高,进而提高副边的输出电压。对于QC2.0来说,我们总共可以得到5V9V12V20V四挡电压,但是一般的充电头都只支持前三档电压。对于QC3.0来说,我们可以获得3.6V-20V的可调电压,以0.2V为步进。一般的手机充电头能做到4V-12V的可调范围。这一次为了简单起见,我们先尝试制作QC2.0的快充诱骗器。

废话不多说,要激活快充协议,我们首先要知道快充协议握手的过程。好在,QC2.0的握手协议并不复杂,大致可以分为以下几个步骤。

  • QC快充头在默认情况下,充电器内部的mos管短接D-和D+并输出5V电压。这样,对于普通的手机或者不支持QC快充协议的手机,识别到此充电器是支持DCP(BC1.2)协议的充电头,对于安卓手机来说激活5V1.5A充电,iPhone激活5V1A充电。
  • 设备端(也就是我们的诱骗器)在D+上输出0.6V电压,此时由于充电头内部mos管导通,D-上也会出现0.6V的电压。维持D+上的0.6V超过1.25秒以后,充电头内部mos断开,D-电压变为0V,此时可以向D-加载电压。
  • 在检测到D-电压变为0V以后,设备即可确定充电头支持QC协议。此时设备端通过设置D+、D-的电压值,即可向充电头申请对应档位的电压。具体的对应值如下:
  • 只需要将D+、D-两引脚均断开,即可关闭快充模式,快充头重新回到DCP模式,输出5V。
档位 5V 9V 12V 20V
D+电压 0.6V 3.3V 0.6V 3.3V
D-电压 0V 0.6V 0.6V 3.3V

通过上面的操作,相信大家已经了解到了如何握手QC2.0协议了。接下来我们考虑一下,如何使用单片机去模拟这个握手过程。最大的问题就是如何产生0.6V3.3V的电压。我们首先想到的是DAC。但是如此小的一个制作,我们根本不需要也没必要去使用昂贵的带DAC的单片机。那么,我们的思路就限定在了使用普通单片机的普通IO口上。3.3V电压直接使用3.3V供电的单片机输出高电平即可,而0.6V也可以通过电阻分压3.3V得到。于是,我设计了如下这样的电路,电路中,D+PUD+D-PUD-PD四个网络连接到了3.3V单片机的普通IO上。

https://img.yuanze.wang/posts/qc2-0-adapter/sch.png
诱骗器原理图

乍一看可能有点懵,我们慢慢分析。根据上面的表格,我们若不考虑充电头给我们的反馈和20V电压档位,我们总共需要

  • D+输出0.6V(握手、5V档位与12V档位)
  • D+输出3.3V(9V档位)
  • D-输出0.6V(9V档位、12V档位)
  • D-断开连接(握手与5V档位)

四种状态。因此,每一根数据线只需要完成两种电平状态的切换即可。因此,对应上面四个状态,我们总共也有四种输出模式:

  • D+PU输出3.3V,D+高阻,在D+上即可得到0.6V电压
  • D+PU高阻,D+输出3.3V,在D+上即可得到3.3V电压
  • D-PU输出3.3V,D-PD输出0V(均为推挽输出),在D-上即可得到0.6V电压
  • D-PU、D-PD均高阻,即可使D-断开连接

这样,我们就用4个IO口实现了握手和三个档位的切换。使用一个8脚STC单片机,即可完成这项工作,剩下两个IO口分别连接一个LED和一个按键。设计中使用HT7533,这是一款最高支持24V输入的高压LDO,对于这种只有十几ma的小单片机来说绰绰有余。注意单片机一定要选STC15W104而不能选STC15F104E,因为后者不能工作在3.3V下。 电路设计完了,接下来就是程序了。程序无非就是对IO口的操作,操作IO口的部分代码如下:

//配置IO口为推挽
#define IO_PP_CONF(IO,PIN) do { \
    IO##M0|=(1<<PIN);\
    IO##M1&=~(1<<PIN);\
    }while(0)\
//配置IO口为高阻
#define IO_HR_CONF(IO,PIN) do { \
    IO##M0&=~(1<<PIN);\
    IO##M1|=(1<<PIN);\
    }while(0)\
#define IO_OUT_HIGH(IO,PIN) IO|=(1<<PIN)
#define IO_OUT_LOW(IO,PIN) IO&=~(1<<PIN)
//配置IO口为推挽
void USBDP_HIGH(void) { //USBD+输出3.3V
  IO_OUT_HIGH(P3,USBDP);//USBDP先输出高
  IO_PP_CONF(P3,USBDP);//推挽输出
  IO_HR_CONF(P3,USBDP_PU);//USBDP_PU为高阻
}
void USBDP_LOW(void) { //USBD+输出0.6V
  IO_HR_CONF(P3,USBDP);//USBDP为高阻
  IO_OUT_HIGH(P3,USBDP_PU);
  IO_PP_CONF(P3,USBDP_PU);//USBDP_PU推挽输出
}
void USBDM_LOW(void) { //USBD-输出0.6V
  IO_OUT_HIGH(P3,USBDM_PU);
  IO_OUT_LOW(P3,USBDM_PD);
  IO_PP_CONF(P3,USBDM_PU);//USBDM_PU推挽输出
  IO_PP_CONF(P3,USBDM_PD);//USBDM_PD推挽输出
}
void USBDM_DISCONN(void) { //USBD-断开
  IO_HR_CONF(P3,USBDM_PD);//USBDM为高阻
  IO_HR_CONF(P3,USBDM_PU);//USBDM_PU为高阻
}

剩下的程序比较简单,不在此赘述,有兴趣的朋友可以到文末下载代码查看。程序实现的功能主要是,上电后默认输出上一次保存在EEPROM中的电压值,LED灯单闪为5V,双闪为9V,三闪为12V,短按按键可以切换档位,长按按键可以保存当前档位为默认值,下次上电自动读取此电压值。

下面为诱骗器的实物图。

https://img.yuanze.wang/posts/qc2-0-adapter/pcb1.jpg
诱骗器正面

https://img.yuanze.wang/posts/qc2-0-adapter/pcb2.jpg
诱骗器背面

可以看到体积还是很小的。下面是用小米充电宝诱骗9V和12V的效果:

https://img.yuanze.wang/posts/qc2-0-adapter/test3.jpg
使用小米充电宝诱骗9V

https://img.yuanze.wang/posts/qc2-0-adapter/test2.jpg
使用小米充电宝诱骗12V

 开源程序与PCB