很久之前做了一个便携式的电烙铁,有坛友想了解代码和QC3.0的诱骗原理,今天正好有时间,大概讲解一下实现原理。
由于时间过去很久了,可能有些东西已经给忘记了,讲解不周还望见谅。
具体的实现思路就是
1:先找一个支持QC3.0快充协议的充电器,别的不知道,但是小米的充电器是支持QC3.0协议的。
2:将充电器的电压上升至一定的电压(根据所需要的温度来设定,电压越高,温度约高,不清楚的可以看我之前的帖子,电烙铁发热芯的原理)。
3:单片机采集当前温度,每种发热芯的测温方式都不一样,有两线的发热芯,也有三线的发热芯和四线的发热芯,这里不多说,因为具体分析起来情况比较多,测温方式也要考虑,就拿最简单的,四线的发热芯来举例子
红色的为供电的两个引脚,内部应该是一个发热丝,所以不分正负极,随便接,蓝色的两根线是测温的,具体的测温我也给忘了,可以自行百度,温度越高两根蓝色的线之间的电压约大,可以后面接一个运放来采集当前电压,得出当前发热芯的温度,如果选择了两线或者三线的发热芯,一定要搞清楚测温原理,切记切记,在之前的帖子中,原理图里面有mos管,理论上来说是调节电流和电压的,但是在烙铁测温的过程中,如果mos管处于导通状态,发热芯两端的电压是输入电压施加在发热芯两端的电压,这个时候测出来的温度是不准确的,所以测温的时候是要断开mos管,然后再测量发热芯两端的电压,此时测出来的温度才是正确的,所以在设计的过程中,电路是要根据自己所选的发热芯来确定自己的硬件电路的。
4:根据采集的温度和设定的温度进行对比,然后去调节输入电压或者调节mos管来控制发热芯的温度,具体怎么实现要看设计者的思路,两种方式都可以实现,也可以调节输入电压+mos管,两者配合来调节温度。
5:使用 PID来调节温度,这个没啥可说的,简单地把公式套进去,然后调节P和I就行了,自己玩,想凑合用或者做到极致,要看设计者自己的行动。
6:好了,废话不说了,看多了大家也烦。直接讲诱骗功能吧。
1、手机在d+上加0.6v电压,这时充电器内部d+和d-是联通的,d-也是0.6v。
2、在1.35秒后,充电器断开d+和d-的联通,d-电压降到0,这时表示充电器支持协议。
3、接下来就是手机请求电压,并保持:
在d+加0.6v,d-加0v时,输出5v;
在d+加3.3v,d-加0.6v时,输出9v;
在d+加0.6v,d-加0.6v时,输出12v;
在d+加3.3v,d-加3.3v时,输出20v;
在d+加0.6v,d-加3.3v时,充电器进入continuous mode 也就是我们称的qc3.0模式。
Portable Device | HVDCP Class A | HVDCP Class B
D+ | D- | Adapate Voltage| Adapter Voltage
0.6V | 0.6V | 12V | 12V
3.3V | 0.6V | 9V | 9V
0.6V | 3.3V | Continuous mode| Continuous mode
3.3V | 3.3V | Previous voltage| 20V
0.6V | GND | 5V | 5V
上电---> D+0.6V D-浮空 ---> 延时1.5S ---> D-3.3V ---> 进入QC3.0模式 --->
主函数
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
MX_I2C1_Init();
USB_GPIO_Init(); //gpio init
HAL_Delay(1000);
Continuous_Mode(); //qc3.0 mode
OLED_Init();
OLED_Display_On(); //oled init
OLED_ShowMenu(DISABLE); //
for(i = 0; i < 30; i++) //set output pwr
{
PWR_Add();
HAL_Delay(200);
}
while (1)
{
if(BTN_A == GPIO_PIN_RESET)
{
HAL_Delay(10);
if(BTN_A == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(MOS_CTRL_GPIO_Port,MOS_CTRL_Pin,GPIO_PIN_SET);
}
}
if(BTN_B == GPIO_PIN_RESET)
{
HAL_Delay(10);
if(BTN_B == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(MOS_CTRL_GPIO_Port,MOS_CTRL_Pin,GPIO_PIN_RESET);
}
}
if(BTN_C == GPIO_PIN_RESET)
{
HAL_Delay(10);
if(BTN_C == GPIO_PIN_RESET)
{
while(!BTN_C);
for(i = 0; i < 10; i++) //set output pwr
{
PWR_Add();
HAL_Delay(10);
}
}
}
// Output_ON();
// HAL_GPIO_WritePin(MOS_CTRL_GPIO_Port,MOS_CTRL_Pin,GPIO_PIN_SET);
}
}
USB D+,D-初始化
//初始化USB GPIO 的引脚
void USB_GPIO_Init(void)
{
//D-浮空输入模式
//D+0.6V
HAL_GPIO_DeInit(USB_UP_L_GPIO_Port,USB_UP_L_Pin);
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = USB_UP_H_Pin; //D+ H
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, USB_UP_H_Pin,GPIO_PIN_SET);
HAL_Delay(500);
// GPIO_InitStruct.Pin = USB_DW_H_Pin; //D- H
// GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
// HAL_GPIO_Init(USB_DW_H_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USB_DW_L_Pin | USB_UP_L_Pin; //D+ L D- L
GPIO_InitStruct.Pin = USB_UP_L_Pin; //D+ L D- L
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_Delay(500);
}
握手,进入QC3.0模式
// 握手协议,进入QC3.0 模式
void Continuous_Mode(void)
{
//D+在初始化的时候已经是0.6V了,若要进入QC3.0模式,则需要使D-3.3V
HAL_GPIO_DeInit(USB_DW_L_GPIO_Port,USB_DW_L_Pin);
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(USB_DW_H_GPIO_Port, USB_DW_H_Pin,GPIO_PIN_SET);
GPIO_InitStruct.Pin = USB_DW_L_Pin; //D- H
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_DW_L_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(USB_DW_L_GPIO_Port, USB_DW_L_Pin,GPIO_PIN_SET);
HAL_Delay(500);
//此时D-3.3V D+0.6V
}
电压增加0.2V
void PWR_Add(void)
{
//D+ L 配置为输出模式,并且输出3.3V后,在切换为输入模式
HAL_GPIO_DeInit(USB_UP_L_GPIO_Port,USB_UP_L_Pin);
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = USB_UP_L_Pin; //D+ L
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_UP_L_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(USB_UP_L_GPIO_Port, USB_UP_L_Pin,GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_DeInit(USB_UP_L_GPIO_Port,USB_UP_L_Pin);
GPIO_InitStruct.Pin = USB_UP_L_Pin; //D+ L
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_UP_L_GPIO_Port, &GPIO_InitStruct);
HAL_Delay(100);
}
电压减小0.2V
void PWR_Sub(void)
{
//D- 为3.3V,将D-电压设置为0.6V时,电压下降200mV
HAL_GPIO_DeInit(USB_DW_L_GPIO_Port,USB_DW_L_Pin);
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_DeInit(USB_DW_L_GPIO_Port,USB_DW_L_Pin);
GPIO_InitStruct.Pin = USB_DW_L_Pin; //D- L
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_DW_L_GPIO_Port, &GPIO_InitStruct);
HAL_Delay(100);
HAL_GPIO_DeInit(USB_DW_L_GPIO_Port,USB_DW_L_Pin);
GPIO_InitStruct.Pin = USB_DW_L_Pin; //D- L
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_UP_L_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(USB_UP_L_GPIO_Port, USB_UP_L_Pin,GPIO_PIN_SET);
HAL_Delay(100);
}
快充协议就那么多点,如果说查看整个文档的话,估计要啃一个礼拜,我们这里只是知道能实现的过程就行了。
文章末//
万恶的资源连接放进去
不过不建议下载。
不建议下载的链接