基于 USB PD DRP的充电宝原理解析

基于 USB PD DRP的充电宝原理解析,第1张

  市面上很多充电宝基于USB PD协议具备DRP功能(可以做Source/Sink)。


拥有DRP功能的充电宝只需要一个Type-C口就能满足充电/放电的功能,在产品的实际生产中可降低成本的投入并且实际使用中能够符合安全规范。



DRP功能实际就是PD芯片在Source/Sink之间进行角色切换,将PD DRP功能应用到充电宝的使用中需要注意电源角色需要以Source功能为主,这样才能保证在给DRP设备(例:手机、电脑)充电的时候能够正确输出。



(注:充电宝的电源角色之所以需要以Source为主,是为了避免给DRP设备充电时反向索取电量。


例如在给手机充电过程中,充电宝的电源角色没有做Source为主的处理时,会出现手机反过来给充电宝充电。



如下图Source时间为:200ms,Sink时间为:100ms。



 

 代码如下:

UINT8 DRP_Set_Source(void)
{
	UINT16 Count = 200;
	UINT8 Connect_Count = 0;
	CC1_CTRL = 0x84;
	CC2_CTRL = 0x84;
	printf("Set Source\r\n");
	while(Count > 1)
	{
		ADC_CHAN = 0x00;
		ADC_CTRL |= bADC_START;
		while( (ADC_CTRL & bADC_IF) == 0 )  ;                                  /* 等待转换完成 */
		ADC_CTRL |= bADC_IF; 
	//printf("Source CC =%d\n",(UINT16)ADC_DAT );                    /* 输出ADC采样值 */		/* 清标志 */
    if((UINT16)ADC_DAT < Power3_0AMax)
		{
			Connect_Count++;
			if(Connect_Count >= 50){
				CCSel = 1;
				printf("CC1 Connect!\r\n");
				UPD_CTRL &= ~(bPD_CC_SEL);
				PowerRole = 1;
				return 1;
			}
		}else{
					ADC_CHAN =0x01;
					ADC_CTRL |= bADC_START;
					while( (ADC_CTRL & bADC_IF) == 0 )  ;                                  /* 等待转换完成 */
					ADC_CTRL |= bADC_IF;                                                /* 清标志 */
	//		printf("Source CC =%d\n",(UINT16)ADC_DAT );                    /* 输出ADC采样值 */		/* 清标志 */
					if((UINT16)ADC_DAT < Power3_0AMax)
		      {
							Connect_Count++;
						if(Connect_Count >= 50){
							CCSel = 2;
							printf("CC2 Connect! \r\n");
							UPD_CTRL |= bPD_CC_SEL;
						  PowerRole = 1;
							return 1;
						}
					}	
				}
		mDelaymS(1);
		Count --;
	}
	return 0;
}

UINT8 DRP_Set_Sink(void)
{
	UINT16 Count = 100;
	UINT8 Connect_Count = 0;
	CC1_CTRL = 0x82;
	CC2_CTRL = 0x82;
	printf("Set Sink\r\n");
//	mDelaymS(100);
	while(Count > 1)
	{
		ADC_CHAN =0x00;
		ADC_CTRL |= bADC_START;
		while( (ADC_CTRL & bADC_IF) == 0 )  ;                                  /* 等待转换完成 */
		ADC_CTRL |= bADC_IF;                                                /* 清标志 */
	//	printf("Sink CC =%d\n",(UINT16)ADC_DAT );                    /* 输出ADC采样值 */
    if((UINT16)ADC_DAT > DufaultPowerMax)
		{
				Connect_Count++;
				if(Connect_Count >= 50){
					
				CCSel = 1;
				UPD_CTRL &= ~(bPD_CC_SEL);
				printf("CC1 Connect! \r\n");
				PowerRole = 0;
				return 1;
				}
		}else {
					ADC_CHAN =0x01;
					ADC_CTRL |= bADC_START;
					while( (ADC_CTRL & bADC_IF) == 0 )  ;                                  /* 等待转换完成 */
					ADC_CTRL |= bADC_IF;                                                /* 清标志 */
	//		printf("Sink CC =%d\n",(UINT16)ADC_DAT );                    /* 输出ADC采样值 */
					if((UINT16)ADC_DAT > DufaultPowerMax)
					{
							Connect_Count++;
							if(Connect_Count >= 50){
							CCSel = 2;
							UPD_CTRL |= bPD_CC_SEL;
							printf("CC2  Connect!\r\n");
							PowerRole = 0;
							return 1;
						}
				 }
	 }
			mDelaymS(1);
		Count --;
	}
	return 0;
}

现在市面上存在的产品就三种:Source(供电端例如:充电器)、Sink(受电端例如:手电筒)、DRP(供电/受电端例如:手机电脑)。



本次将使用CH543 Demo板模拟充电宝的DRP功能,会分别和充电器(Source)、设备(Sink)、手机(DRP)进行PD通讯,模拟真实应用场景下的使用。



(1)充电宝在给设备Sink充电时电源角色将切换为Source,电流方向由充电宝流入受电设备。



(2)充电宝自身电量不足时需要接充电器Source充电,此时充电宝的电源角色将切换为Sink,电流方向由外部流入充电宝内部。



(3)充电宝的主要功能就是给设备Sink充电,所以在遇到和DRP(手机电脑)连接时应多次进行判断设备的电源角色为DRP,充电宝在遇到DRP时应果断将自身电源角色转变为Source向外部供电,避免反向充电吸收外部设备的电量。



以下为三种情况下的判断代码:
 

PD_Init:
		Src_Connect = 0;
		Sik_Connect = 0;
    Src_Connect = DRP_Set_Source();  //Source 
	  Sik_Connect = DRP_Set_Sink();   //SInk  
	
	//	printf("Src_Connect = %d   Sik_Connect = %d \r\n",(UINT16)Src_Connect,(UINT16)Sik_Connect);
		if((Src_Connect == 0)&&(Sik_Connect == 0))
		{		
			goto PD_Init;	
		}
PD_Start:	
	if(Src_Connect == 1)
	{
        //设置成Source
    DRP_Set_Source();
    IE_USBPD = 1;
		PD_PHY_TX_SourCap();
		while(State)
		{
			 State = Check_Remove_Src();
			 mDelaymS(200);
		}
		State = 1;
		printf("DEV Remove\r\n");
		goto PD_Init;
	}
	if((Src_Connect == 0)&&(Sik_Connect == 1))
		{
			Src_Connect = DRP_Set_Source();  //Source 400ms
			if(Src_Connect == 0)
			{
				//设置成Sink
				DRP_Set_Sink();
				
				PD_PHY_RX_INIT();
				IE_USBPD = 1;
				while(State)
				{
					 State = Check_Remove_Sik();
					 mDelaymS(200);
				}
				State = 1;
				printf("DEV Remove\r\n");
			  goto PD_Init;
			}	else{
				Sik_Connect = DRP_Set_Sink();
				if((Sik_Connect == 1)&&(Src_Connect == 1))
				{
					goto PD_Start;
					
				}
			}
}

之所以选用CH543是因为此款芯片内置上拉电流和下拉电阻,可以软件进行切换电源角色。


另外ISINK引脚具有控制FB的功能,在充电宝电源角色做主机Source时可以通过ISINK进行电压调节,下图为CH543 Demo板。


1、    CH543 Demo与充电器(Source)进行通讯。



充电器(Source)未接入Type-C口时CH543 会在Source/Sink之间来回切换。


当充电器(Source)接入Type-C口, CH543电源角色处于Sink阶段的时候,才会进行PD通讯补充自身的电量。



下图为CH543与充电器(Source)协议包图,前端CC电平周期翻转是充电器(Source)未接入时CH543的电源角色在进行Source/Sink切换。


后端无电平翻转是充电器(Source)介入后进行的PD通讯过程。



 

2、CH543 Demo与受电端(Sink)进行通讯。



在没有设备(Sink)接入时CH543 会Source/Sink之间来回切换。


当设备(Sink)和CH543连接时,CH543处于Source阶段会检测到Sink端接入,进行判断后会进行PD通讯,实现向外部设备供电的功能。


 

 

3、CH543 Demo与DRP设备进行通讯。



本次选用的DRP设备为手机,在手机没有接入时CH543 会Source/Sink之间来回切换。


当手机和CH543连接时,CH543会检测到手机为DRP设备(CH543和手机都会在Source/Sink切换角色),然后CH543会强制转换电源角色为Source后进行PD通讯,给手机进行充电。


(若不强制CH543切换成Source会存在手机反向给CH543充电的可能性,此时CH543电源角色将为Sink吸收手机电量)

 

 

本次只是基本探究充电宝的工作原理,并未做出相实物。


通过上述三种验证下,基本清楚了充电宝在工作时的基本原理。


有兴趣的可以在此基础上继续完善,DRP的代码处理可自行下载。



 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/634473.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-16
下一篇 2022-04-16

发表评论

登录后才能评论

评论列表(0条)

保存