提到快充协议会想到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