资讯详情

PD等多协议快充诱骗触发器SINK(“Power Z 弟弟 Power Low”)DIY

提到快充协议会想到USB PD事实上,市场上有许多主流的快速充电协议,如华为FCP、SCP,三星的AFC,OPPO的VOOC,高通的QC,VIVO的Flash Charge等……,如何区分这么多快充协议?相信很多电粉及相关开发人员都应该知道PowerZ这款强大的诱惑产品支持QC2.0、QC3.0、VOOC、SCP、SSCP、PD触发协议等。本期将使用CH543制作简单版的诱骗器Power Low。

以上是利用CH543设计的简单电路原理图可以通过DM、DP、CC通过实现主要的诱骗功能,通过DM、DP来触发QC、AFC、FCP等协议,通过CC触发PD协议。使用屏幕显示SPI驱动的TFT:ST7735S(占用片外和片内资源,后续将更换为I2C驱动屏)。也用于设计Power Z三档拨轮开关相同,用于选择档位和功能操作。整体电路设计参考价格在15元左右,主要是TFT比较贵,否则成本可以降到10元以内。 由于一些快速充电协议属于私人协议,处于不公开状态,第三方需要授权才能使用,因此这次将集中在USB PD快充诱惑触发解释。首先,诱骗器的定位是Sink因此,受电端CC必须有5个引脚.1K只有这样拉电阻Source识别供电端的供电。默认系统要求5V电压可通过三档拨轮开关选择Fixed或者PPS,选择不同的电压可以同时调整。具体实物效果如下:

很Power Low Low Low Low Low ……

以下为PD使用通信协商过程PD中断来解析Source收到发送的协议包SourceCap包时,具体内容将缓存PDO_BUF中:

/******************************************************************************* * Function Name  : PD_PHY_ISR(void) * Description    : PD中断处理函数 * Input          : None * Output         : None * Return         : None *******************************************************************************/ void PD_PHY_ISR(void) interrupt INT_NO_USBPD using 1 { /*接收复位信息中断*/  if ( PIF_RX_RST ) {   PD_PHY_HRST_ISR();  //收到HRST   PD_PHY_RX_INIT();  } /*接受完成中断的数据包*/  if ( PIF_RX_ACT ){    PIF_RX_ACT = 0;   if ( (UPD_INT_FG & MASK_PD_STAT) == PD_RX_SOP0 ) {      //收到HRST或SOP数据      Union_Header = (_Union_Header *)PD_RX_BUF;          //强制转化       if ( PD_PHY_STAT.WaitingGoodCRC ) {                   //是否在等待GoodCRC     if(Union_Header->HeaderStruct.MsgType == GoodCRC){  ///判断收到的消息是否为GOODCRC      PD_PHY_STAT.WaitingGoodCRC = 0;           PD_PHY_Clear_Flag();                              ///清除标志函数      PD_PROT_ISR();                }    }else {        switch(Union_Header->HeaderStruct.MsgType)      {              case SourceCap:            memcpy(PDO_BUF,PD_RX_BUF,sizeof(PD_RX_BUF));             Versions = Union_Header->HeaderStruct.SpecRev;             SourceCapNDO = Union_Header->HeaderStruct.NDO;                   RecvPDOFlag = 1;              //修改RecvPDOFlag = 1 开启解析PDO,如果打开后回复为0,则关闭。GOODCRC时间会适当延长,默里默认开启           PD_PHY_STAT.SendingRequest = 1;          break;       case Accept:                          break;       case Reject:          break;       case PS_RDY:           RecvPS_RDYFlag = 1;          break;         case GetSinkCap:          MsgID  ;          PD_PHY_STAT.SendingSinkCap = 1;             break;           case SourceCap_VDM:             MsgID  ;            PD_PHY_STAT.SendingNotSup = 1;          break;        default :       break;       }       mDelayuS(10);        PD_PHY_STAT.SendingGoodCRC = 1; //置发送GoodCRC标志位       PD_PHY_TX_GoodCRC();        //回复GoodCRC     }   }else PD_PHY_RX_INIT(); } /*数据包发送完成中断 */  if ( PIF_TX_END ) {       PIF_TX_END = 0;    if(CCSel == 1){  ///发送后关闭低压     CC1_CTRL &= ~bCC_LVO;     }else if(CCSel == 2){     CC2_CTRL &= ~bCC_LVO;     }   if ( PD_PHY_STAT.SendingGoodCRC ==1 ) {                           PD_PHY_STAT.SendingGoodCRC = 0;    PD_PROT_ISR(); //GoodCRC发送完成,向Prot转交数据   }else {   /*开始接收GoodCRC*/      PD_PHY_STAT.WaitingGoodCRC = 1;       Timer_Counter = Save_Counter;      PD_PHY_RX_INIT();    }  } }

本段用于分析Source支持PD协议的具体档位一次发生PD谈判结束时,此时RecvPS_RDYFlag = 1.分析上述缓存PDO_BUF中的SourceCap包,并显示在屏幕(后续会精简优化代码):

 /******************************************************************************* * Function Name  : Analysis_PDO(void) * Description    : 解析PDO、PPS函数 * Input          : None * Output         : None * Return         : None *******************************************************************************/ void Analysis_PDO(void) {  UINT8 Temp;  UINT16 PDO_Value = 0;  if(RecvPDOFlag == 1){     LCD_Fill(0,0,159,12,CYAN);   LCD_DrawLine(0,0,159,0,CYAN);   LCD_DrawLine(0,0,0,127,CYAN);   LCD_DrawLine(159,0,159,127,CYAN);   LCD_DrawLine(0,127,159,127,CYAN);   if(Versions == 2) //判断PD版本   {    LCD_ShowString(3,0,"Power Delivery 3.0",BLACK,CYAN,12,0);   }else{    LCD_ShowString(3,0,"Power Delivery 2.0",BLACK,CYAN,12,0);   }        Union_Header = (_Union_Header *)PDO_BUF;  //解析SourceCap   for(Temp=0;Temp<SourceCapNDO;Temp  )//pdo的档位   {    Union_SrcCap = (_Union_SrcCap*)(&PDO_BUF[2 (Temp*4)]);    if((Union_SrcCap->SrcCapStruct.DataH8>>6)== 0x00)  //表示固定档    {     PDO_Value =((((Union_SrcCap->SrcCapStruct.VoltH4<<6) ( Union_SrcCap->SrcCapStruct.VoltL6))*50)/100);     if( PDO_Value/10 >= 10) //电压     {       LCD_ShowFloatNum1(108-7*6,(Temp 1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);     }else{      LCD_ShowFloatNum1(108-6*6,(Temp 1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);     }      PDO_Value=((((Union_SrcCap->SrcCapStruct.CurrentH2<<8) ( Union_SrcCap->SrcCpStruct.CurrentL8))*10)/10); //电流
			  LCD_ShowFloatNum1(120,(Temp+1)*12,(float)PDO_Value/100,3,CYAN,BLACK,12);
			 
			    LCD_ShowString(108,(Temp+1)*12,"@",CYAN,BLACK,12,0);
				 	LCD_ShowString(3,(Temp+1)*12,"< > Fix",CYAN,BLACK,12,0);
				  LCD_ShowIntNum(10,(Temp+1)*12,Temp+1,1,CYAN,BLACK,12);
				  LCD_ShowString(108-2*6,(Temp+1)*12,"V",CYAN,BLACK,12,0);
				  LCD_ShowString(145,(Temp+1)*12,"A",CYAN,BLACK,12,0);
			 
		 }else if((Union_SrcCap->SrcCapStruct.DataH8>>6)== 0x03){//表示PPS
				Union_PPS_SrcCap = (_Union_PPS_SrcCap*)(&PDO_BUF[2+(Temp*4)]);  //转换为PPS                         
		       
					PDO_Value = (Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMin);  
          if(PDO_Value/10 >= 10)
					{
						 LCD_ShowFloatNum1(111-10*6,(Temp+1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);
						
					}else{
						LCD_ShowFloatNum1(111-9*6,(Temp+1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);
					}
			 
          PDO_Value = ((Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMaxH1<<7) + (Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMaxL7));
					LCD_ShowString(75,(Temp+1)*12,"-",CYAN,BLACK,12,0);
					if(PDO_Value/10 >= 10)
					{
						 LCD_ShowFloatNum1(108-4*6,(Temp+1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);
					}else{
						LCD_ShowFloatNum1(108-3*6,(Temp+1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);
					}
					PDO_Value = ((Union_PPS_SrcCap->SRC_Cap_PPS_Struct.Current)*50)/10;
					LCD_ShowFloatNum1(120,(Temp+1)*12,(float)PDO_Value/100,3,CYAN,BLACK,12);
				 	LCD_ShowString(3,(Temp+1)*12,"< > PPS",CYAN,BLACK,12,0);
				  LCD_ShowIntNum(10,(Temp+1)*12,Temp+1,1,CYAN,BLACK,12);
				  LCD_ShowString(108,(Temp+1)*12,"V",CYAN,BLACK,12,0);
				  LCD_ShowString(145,(Temp+1)*12,"A",CYAN,BLACK,12,0); 
			 }
		 }

		 	LCD_ShowString(44,(Temp+2)*12-6,"Fixed",BLACK,CYAN,12,0);
		  LCD_ShowString(92,(Temp+2)*12-6,"PPS",CYAN,BLACK,12,0);
 	RecvPDOFlag = 0;
	 }
}

因A口协议属于未公开状态,本次将不进行讲解。有兴趣的小伙伴可以多了解一下,附送一张QC2.0的协议规范。    

 后续会上传附件,在此处公开资料代码和PCB等,开源。触发器Power Low(可多快充协议PD、QC等) - 电源论坛_电源技术论坛 - 21ic电子技术开发论坛">多协议电源诱骗触发器Power Low(可多快充协议PD、QC等) - 电源论坛_电源技术论坛 - 21ic电子技术开发论坛https://bbs.21ic.com/icview-3232588-1-1.html

标签: diy如何调电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台