本帖最后由 Liuhl1998 于 2023-3-22 10:54 编辑
鸽了这么久,PowerXXXX2.0终于来了!!话不多说,直接展示。
新款PowerX支持BC1.2检测、QC2.0检测调压、QC3.0检测调压、PD2.0/3.0以及PPS检测调压,因为华为FCP和三星的AFC属于厂商私有协议,暂不公开。另外Apple2.4也被我屏蔽了,狗头保命!
目前公开的版本仅支持BC1.2、QC2.0/3.0、PD2.0/3.0、PPS。
好了好了,不啰嗦了,效果演示图如下:
1:操作显示界面(左右选择需要请求的协议,确认进入)
2:BC1.2检测界面(成功会显示成功和BC1.2协议标志,如果失败会显示失败并且输出接口类型SDP、CDP)
3:QC2.0检测调压界面(会显示触发成功标志,以及需要调压的档位)
4:QC3.0检测调压界面(左右进行调压,显示功能和QC2.0差不多)
5:PD检测调压界面(成功会读取PD版本号、PD支持的档位信息:电压电流)
6:PPS调压检测界面(显示PPS支持的电压范围,请求的电压幅值、精准请求电压20mv)
显示界面如上,使用的是三档拨轮开关,屏幕TFT(占用空间太大了,PowerXXXX3.0版本就给换了)
以上是利用CH543设计的简易版电路原理图,可通过DM、DP、CC来实现主要的诱骗功能,通过DM、DP来触发QC、AFC、FCP等协议,通过CC触发PD协议。屏幕显示采用SPI驱动的TFT:ST7735S。设计中还使用了Power Z一样的三档拨轮开关,用来选择档位和功能操作等。整体电路设计下来参考价格在15元左右,主要是TFT比较贵。 原理图如下:
PCB如下:
!!!主程序代码:
#include "System.H"
void main() {
System_Init(); //系统初始化操作界面
while(1)
{
LCD_Fill(1,1,LCD_W-1,LCD_H-1,BLACK);
switch(System_Select_Mode)
{
case System_Init_Mode: //系统初始化操作界面
Init_Mian_Proc();
break;
case System_BC_Mode: //系统PD触发操作界面
BC_Mian_Proc();
break;
case System_QC2_Mode: //系统PD触发操作界面
QC_Mian_Proc();
break;
case System_QC3_Mode : //系统QC触发操作界面
QC_Mian_Proc();
break;
case System_Apple_Mode : //系统APPle2.4触发操作界面
// Apple_Mian_Proc();
break;
case System_PD_Mode : //系统PD触发操作界面
PD_Mian_Proc();
break;
case System_AFC_Mode : //系统AFC触发操作界面
// AFC_Mian_Proc();
break;
case System_FCP_Mode : //系统FCP触发操作界面
// FCP_Mian_Proc();
break;
default:
System_Select_Mode = System_Init_Mode;
break;
}
}
}
!!!BC1.2触发函数:
UINT8 BC1_2Check(void)
{
bit BC_Check_Flag = 0;
UINT8 CheckCount =0;
USB_DP_OUT_0v6();
CheckCount = 40;
while(CheckCount)
{
if(Check_ADC(bDM_Aisle) >= 372)
{
BC_Check_Flag = 1;
}else{
BC_Check_Flag = 0;
}
CheckCount--;
mDelaymS(1);
}
if(BC_Check_Flag) //DCP,CDP
{
USB_DM_OUT_0v6();
CheckCount = 40;
while(CheckCount)
{
if(Check_ADC(bDP_Aisle) >= 372)
{
BC_Check_Flag = 1;
}else{
BC_Check_Flag = 0;
}
CheckCount--;
mDelaymS(1);
}
if(BC_Check_Flag) //DCP
{
USB_DP_OUT_0v6();
CheckCount = 135;
while(CheckCount>=1)
{
if(Check_ADC(bDM_Aisle) <= 372){return 4;}
CheckCount -= 1;
mDelaymS(10);
}
}else{
printf("This is CDP\r\n");
return 2;
}
}else{
printf("This is SDP\r\n");
return 1;
}
printf("BC1.2\r\n");
return 3;
}
!!!QC触发函数:
#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 USB_DMDP_OUT_0v0() { SET_DP_Push_Pull();SET_DM_Push_Pull();DP = 0;DM = 0;}
#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() { SET_DP_Push_Pull();SET_DM_Push_Pull();DP = 1;DM = 1;}
#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();}
!!!PD触发函数:
/*******************************************************************************
* Function Name : PD_PHY_ISR(void)
* Description : PD中断处理函数
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void PD_PHY_ISR(void) interrupt INT_NO_USBPD
{
/*接收到复位信息中断*/
if(PIF_RX_RST){
PIF_RX_RST = 0;
PD_PHY_HRST_ISR();
}
/*数据包接受完成中断*/
if(PIF_RX_ACT )
{
PIF_RX_ACT = 0;
if((UPD_INT_FG & MASK_PD_STAT) == PD_RX_SOP0)
{
Union_Header = (_Union_Header *)PD_RX_BUF;
if (PD_PHY_STAT.WaitingGoodCRC)
{
if(Union_Header->HeaderStruct.MsgType == GoodCRC)//判断收到的消息是否为GOODCRC
{
PD_PHY_STAT.WaitingGoodCRC = 0;
PD_PHY_Clear_Flag();
PD_PROT_ISR();
}
}else{
Data_Versions = Union_Header->HeaderStruct.SpecRev; //获取PD版本号
switch(Union_Header->HeaderStruct.MsgType)
{
case SourceCap:
Bit_Recv_SrcCap = 1;
Data_MsgID++;
PD_PHY_STAT.SendingRequest = 1;
memcpy(PD_SrcCap_BUF,PD_RX_BUF,sizeof(PD_RX_BUF));
Bit_Recv_PSRDY = 0;
break;
case Accept:
break;
case Reject:
Data_MsgID++;
PD_PHY_STAT.SendingRequest = 1;
break;
case PS_RDY:
Bit_Recv_PSRDY = 1;
break;
case GetSinkCap:
Data_MsgID++;
PD_PHY_STAT.SendingSinkCap = 1;
break;
case SrcCap_VDM:
Data_MsgID++;
PD_PHY_STAT.SendingNAK = 1;
break;
}
mDelayuS(15);
PD_PHY_STAT.SendingGoodCRC = 1; //置发送GoodCRC标志位
PD_PHY_TX_GoodCRC(); //回复GoodCRC
}
}else{
PD_PHY_RX_INIT();
}
}
/*数据包发送完成中断 */
if(PIF_TX_END)
{
PIF_TX_END = 0;
CC1_CTRL &= ~bCC_LVO; /*CC2数据包发送完成 */
CC2_CTRL &= ~bCC_LVO;
if(PD_PHY_STAT.SendingGoodCRC){
PD_PHY_STAT.SendingGoodCRC = 0;
PD_PROT_ISR();
}else{
PD_PHY_STAT.WaitingGoodCRC = 1;
Timer_Counter = Save_Counter;
PD_PHY_RX_INIT();
}
}
}
!!!PPS触发处理函数:
void PD_Request_PPS(UINT8 GearTemp,UINT16 PD_PPS_Value)
{
UPD_T_SOP = UPD_SOP0;
UPD_T_LEN = 6;
Data_MsgID++;
if(Data_MsgID>7){ Data_MsgID =0;}
PD_TX_BUF[5] =((GearTemp<<4) | 0x01);
PD_TX_BUF[4] =(PD_PPS_Value >> 7);
PD_TX_BUF[3] = ((PD_PPS_Value<<1) & 0xFE);
PD_TX_BUF[2] = PD_SrcCap_BUF[2+((GearTemp - 1)*4)];
PD_TX_BUF[1] = (0x10 | (Data_MsgID << 1));
PD_TX_BUF[0] =(0x02 | (Data_Versions<<6));
PD_PHY_TX_INIT();
}
好了好了,今天全是硬菜,大家先好好消化一下!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|