BC1.2、QC2.0/3.0快充协议讲解(CH543D实例演示:开源)

发布于:2022-11-29 ⋅ 阅读:(2953) ⋅ 点赞:(3)

 前言:

  目前快充协议主要划分为: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写的测试代码如下:

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档位

代码如下:

#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();}

至于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 

本文含有隐藏内容,请 开通VIP 后查看