本帖最后由 Liuhl1998 于 2022-10-12 17:30 编辑
前言:
目前快充协议主要划分为:Type-C口PD协议 和 USB-A口BC/QC/AFC/FCP等协议。PD协议可以翻阅之前的帖子,今天主要来讲解BC1.2 和QC2.0/3.0。
BC1.2 协议:
现阶段几乎所有的A口协议都需要在BC1.2的基础上运行,只有等BC协议握手成功后,才能进行请求高电压。所以BC1.2是大多协议的基础,占据比较重要的地位。
此文讲解受电端(Sink)如何请求运行BC1.2,只要了解Sink端运行的流程,就很容易反推出供电端(Source)该如何操作。
首先需要知道BC1.2的供电端(Source)有以下几种名词:SDP、CDP、DCP。一般电脑的接口为SDP用于数据通讯和小电流供电,我们平常使用的充电器一般为DCP,BC1.2的握手主要就是区分供电端(Source)为SDP、DCP还是CDP。
供电端(Source)连接受电端(Sink)设备后,会为Sink提供5V电压运行使用。
1:Sink 先在DP(D+)数据线上输出0.6V左右的电压,然后检测DM(D-)的电平状态,如果DM电平呈现0状态,则说明供电端(Source)的DMDP没有短接,可以判定Source为SDP。否则Source为DCP 或者 CDP。
2:此时可以断定Source为DCP 或者 CDP,就需要二次检测具体区分,Sink将会在DM数据线上输出0.6V左右的电压,然后检测DP的电平状态,如果DP呈现出0状态,则说明Source为虚短状态,判断Source为CDP,否则Source为DCP。
3:经过以上两次检测可以确认Source为DCP,那么此时需要在DP上输出0.6V左右的电压,等待DMDP的短接释放,现象为DP电平为0.6V,DM下降到0V。此时说明BC1.2运行成功。
注:简便操作一般是在DP上输出0.6V电压持续1.25S左右,如果DM不释放BC失败,否则成功。
利用CH543写的测试代码如下:/*******************************************************************************
* Function Name : void BC1_2Check(void)
* Description : BC1.2检测
*******************************************************************************/
bit BC1_2Check(void)
{
UINT8 Temp = 150;
UINT8 CheckCount;
USB_DP_OUT_0v6();
CheckCount = 40;
while(CheckCount)
{
if(Check_ADC(DMAisle) >= Volt0_3){BCSDP = 0;}
else{BCSDP = 1;}
CheckCount--;
mDelaymS(1);
}
if(BCSDP == 0) //DCP,CDP
{
USB_DM_OUT_0v6();
CheckCount = 40;
while(CheckCount)
{
if(Check_ADC(DPAisle) >= Volt0_3){BCCDP = 0;}
else{BCCDP = 1;}
CheckCount--;
mDelaymS(1);
}
if(BCCDP == 0) //DCP
{
BCDCP = 1;
USB_DP_OUT_0v6();
while(Temp>=1)
{
if(Check_ADC(DMAisle) <= Volt0_3){return 1;}
Temp -= 1;
mDelaymS(30);
}
}else{
printf("This is CDP\r\n");
return 0;
}
}else{
printf("This is SDP\r\n");
return 0;
}
printf("BC1.2 Failed\r\n");
return 0;
}
QC2.0/3.0协议:
BC1.2检测成功后,DP为0.6V,DM为0V,刚好对应QC2.0的5V档位,至于QC2.0就简单很多,只需要改变DMDP分别呈现不同的电平状态,就可以请求出不同的电压(一般QC2.0都只支持12V,很少一部分充电器能够支持20V)
DM:0V 、 DP:0.6V -----5V档位
DM:0.6V 、 DP:3.3V -----9V档位
DM:0.6V 、 DP:0.6V -----12V档位
DM:3.3V 、 DP:3.3V -----20V档位
至于QC3.0也是在BC1.2的基础上进行,将DP设置0.6V,DM设置成3.3V,则可以进入QC3.0。此时DP从0.6V变成3.3V后回到0.6V,则QC3.0请求+20mV,DM从3.3V变成0.6V后回到3.3V,则QC3.0请求-20mV。
代码如下:
#define SET_DM_Push_Pull() {P3_MOD_OC &= ~bDM; P3_DIR_PU |= bDM;}
#define SET_DP_Push_Pull() {P3_MOD_OC &= ~bDP; P3_DIR_PU |= bDP;}
#define SET_DM_Float_in() {P3_MOD_OC &= ~bDM; P3_DIR_PU &= ~bDM;}
#define SET_DP_Float_in() {P3_MOD_OC &= ~bDP; P3_DIR_PU &= ~bDP;}
#define SET_DMDP_Float_in() {SET_DM_Float_in(); SET_DP_Float_in();}
#define USB_DP_OUT_0v6() { USB_PULL &= ~bUDP_PDE; USB_PULL |= bUDM_PDE; P3_ANA_PIN |= (MASK_USB_OUT_VOL & 0x01);}
#define USB_DM_OUT_0v6() { USB_PULL |= bUDP_PDE; USB_PULL &= ~bUDM_PDE; P3_ANA_PIN |= (MASK_USB_OUT_VOL & 0x01);}
#define USB_DP_OUT_0v0() { USB_PULL |= bUDP_PDE; USB_PULL &= ~bUDM_PDE; P3_ANA_PIN &= ~(MASK_USB_OUT_VOL);}
#define USB_DM_OUT_0v0() { USB_PULL &= ~bUDP_PDE; USB_PULL |= bUDM_PDE; P3_ANA_PIN &= ~(MASK_USB_OUT_VOL);}
#define USB_DP_OUT_3v3() { SET_DP_Push_Pull(); SET_DM_Float_in();DP = 1;}
#define USB_DM_OUT_3v3() { SET_DM_Push_Pull(); SET_DP_Float_in();DM = 1;}
#define QC_Get_Request5V() { SET_DMDP_Float_in(); USB_DM_OUT_0v0(); USB_DP_OUT_0v6();}
#define QC_Get_Request9V() { SET_DMDP_Float_in(); USB_DM_OUT_0v6(); USB_DP_OUT_3v3();}
#define QC_Get_Request12V() { SET_DMDP_Float_in(); USB_PULL |= bUDP_PDE; USB_PULL |= bUDM_PDE; P3_ANA_PIN |= (MASK_USB_OUT_VOL & 0x01);}
#define QC_Get_Request20V() { USB_DM_OUT_3v3(); USB_DP_OUT_3v3();}
#define QC3_Init() { SET_DMDP_Float_in(); USB_DP_OUT_0v6(); USB_DM_OUT_3v3();}
#define QC3_Plus_Volt() { SET_DP_Push_Pull();DP = 1;mDelaymS(10); QC3_Init();}
#define QC3_SUB_Volt() { QC_Get_Request12V(); mDelaymS(10); QC3_Init();}
大家有兴趣可以留下邮箱,将提供源码给大家,至于使用的Demo板,可以跟沁恒申请: www.wch.cn
|