基于51单片机的PD协议移动电源控制程序
基于51单片机的PD协议移动电源控制程序
含PD协议通信、电池管理、充电控制和状态显示等功能。
#include <reg52.h>
#include <intrins.h>
// 硬件引脚定义
sbit USB_CC1 = P1^0; // Type-C CC1检测引脚
sbit USB_CC2 = P1^1; // Type-C CC2检测引脚
sbit USB_DM = P1^2; // USB D- 引脚
sbit USB_DP = P1^3; // USB D+ 引脚
sbit LED_RED = P2^0; // 红色LED指示灯
sbit LED_GREEN = P2^1; // 绿色LED指示灯
sbit LED_BLUE = P2^2; // 蓝色LED指示灯
sbit CHG_EN = P3^0; // 充电使能控制
sbit DIS_EN = P3^1; // 放电使能控制
sbit KEY = P3^2; // 功能按键
// ADC通道定义
#define ADC_BAT_VOLT 0 // 电池电压检测通道
#define ADC_BAT_TEMP 1 // 电池温度检测通道
#define ADC_OUT_VOLT 2 // 输出电压检测通道
#define ADC_OUT_CURR 3 // 输出电流检测通道
// PD协议相关定义
#define PD_SOURCE_CAPABILITIES 0x01
#define PD_REQUEST 0x02
#define PD_ACCEPT 0x03
#define PD_REJECT 0x04
#define PD_PS_RDY 0x05
// 电压档位定义 (单位: 0.1V)
#define VOLT_5V 50
#define VOLT_9V 90
#define VOLT_12V 120
#define VOLT_15V 150
#define VOLT_20V 200
// 全局变量
unsigned char pd_voltage = VOLT_5V; // 当前输出电压档位
unsigned char battery_level = 0; // 电池电量百分比
unsigned char pd_connected = 0; // PD设备连接状态
unsigned char charging_state = 0; // 充电状态
// 函数声明
void System_Init(void);
void Timer0_Init(void);
void ADC_Init(void);
void PD_Protocol_Handler(void);
void Battery_Management(void);
void Charging_Control(void);
void LED_Display(void);
unsigned int Read_ADC(unsigned char channel);
void Delay_ms(unsigned int ms);
void UART_Send_Byte(unsigned char dat);
void UART_Send_String(char *s);
// 主函数
void main(void)
{
System_Init(); // 系统初始化
Timer0_Init(); // 定时器初始化
ADC_Init(); // ADC初始化
EA = 1; // 开启总中断
UART_Send_String("PD Power Bank Started\r\n");
while(1)
{
PD_Protocol_Handler(); // PD协议处理
Battery_Management(); // 电池管理
Charging_Control(); // 充放电控制
LED_Display(); // LED状态显示
}
}
// 系统初始化
void System_Init(void)
{
// 设置IO方向
P1 = 0xFF; // P1口输入
P2 = 0x00; // P2口输出
P3 = 0x04; // P3.2为输入,其他输出
// 初始状态
CHG_EN = 0; // 充电禁用
DIS_EN = 0; // 放电禁用
LED_RED = 0;
LED_GREEN = 0;
LED_BLUE = 0;
}
// 定时器0初始化 (用于1ms定时)
void Timer0_Init(void)
{
TMOD |= 0x01; // 定时器0,模式1
TH0 = 0xFC; // 1ms定时
TL0 = 0x66;
ET0 = 1; // 允许定时器0中断
TR0 = 1; // 启动定时器0
}
// ADC初始化
void ADC_Init(void)
{
P1ASF = 0x0F; // 设置P1.0-P1.3为模拟输入
ADC_RES = 0;
ADC_CONTR = 0x80; // 开启ADC电源,ADC转换速度设为最慢
}
// 定时器0中断服务函数
void Timer0_ISR() interrupt 1
{
static unsigned int timer_count = 0;
TH0 = 0xFC; // 重装初值
TL0 = 0x66;
timer_count++;
// 每100ms执行一次
if(timer_count >= 100)
{
timer_count = 0;
// 检测按键
if(KEY == 0)
{
Delay_ms(20); // 消抖
if(KEY == 0)
{
// 循环切换电压档位
if(pd_voltage == VOLT_5V) pd_voltage = VOLT_9V;
else if(pd_voltage == VOLT_9V) pd_voltage = VOLT_12V;
else if(pd_voltage == VOLT_12V) pd_voltage = VOLT_15V;
else if(pd_voltage == VOLT_15V) pd_voltage = VOLT_20V;
else pd_voltage = VOLT_5V;
UART_Send_String("Voltage Changed: ");
UART_Send_Byte(pd_voltage/10 + '0');
UART_Send_Byte('.');
UART_Send_Byte(pd_voltage%10 + '0');
UART_Send_String("V\r\n");
// 等待按键释放
while(KEY == 0);
}
}
}
}
// PD协议处理
void PD_Protocol_Handler(void)
{
static unsigned char last_cc1, last_cc2;
unsigned char current_cc1, current_cc2;
// 读取CC引脚状态
current_cc1 = USB_CC1;
current_cc2 = USB_CC2;
// 检测连接状态变化
if((current_cc1 != last_cc1) || (current_cc2 != last_cc2))
{
last_cc1 = current_cc1;
last_cc2 = current_cc2;
// 判断连接状态
if((current_cc1 == 0) || (current_cc2 == 0))
{
pd_connected = 1;
UART_Send_String("PD Device Connected\r\n");
// 发送电源能力信息
PD_Send_Source_Capabilities();
}
else
{
pd_connected = 0;
DIS_EN = 0; // 禁用放电
UART_Send_String("PD Device Disconnected\r\n");
}
}
// 如果已连接,处理PD通信
if(pd_connected)
{
// 模拟PD通信(实际应用中需使用专用PD芯片或软件实现)
if(PD_Receive_Message())
{
// 处理接收到的PD消息
PD_Process_Message();
}
}
}
// 发送电源能力信息
void PD_Send_Source_Capabilities(void)
{
// 实际应用中需通过USB PD物理层发送
UART_Send_String("Sending Source Capabilities\r\n");
UART_Send_String("5V/3A, 9V/3A, 12V/3A, 15V/3A, 20V/3A\r\n");
}
// 接收PD消息(模拟)
unsigned char PD_Receive_Message(void)
{
// 简化的模拟接收
static unsigned char counter = 0;
if(counter++ > 100)
{
counter = 0;
return 1; // 模拟接收到消息
}
return 0;
}
// 处理PD消息
void PD_Process_Message(void)
{
// 模拟处理PD消息
UART_Send_String("Received PD Request\r\n");
// 发送接受响应
UART_Send_String("Sending PD Accept\r\n");
// 发送电源准备好消息
UART_Send_String("Sending Power Ready\r\n");
// 使能放电
DIS_EN = 1;
UART_Send_String("Output Enabled\r\n");
}
// 电池管理
void Battery_Management(void)
{
unsigned int bat_voltage, bat_temp;
static unsigned char bat_counter = 0;
// 每100ms读取一次电池参数
if(bat_counter++ >= 10)
{
bat_counter = 0;
// 读取电池电压 (单位: mV)
bat_voltage = Read_ADC(ADC_BAT_VOLT) * 10; // 假设ADC值对应mV
// 读取电池温度 (单位: 0.1℃)
bat_temp = Read_ADC(ADC_BAT_TEMP);
// 计算电池电量 (简化算法)
if(bat_voltage > 4200) battery_level = 100;
else if(bat_voltage > 4100) battery_level = 90;
else if(bat_voltage > 4000) battery_level = 80;
else if(bat_voltage > 3900) battery_level = 70;
else if(bat_voltage > 3800) battery_level = 60;
else if(bat_voltage > 3700) battery_level = 50;
else if(bat_voltage > 3600) battery_level = 40;
else if(bat_voltage > 3500) battery_level = 30;
else if(bat_voltage > 3400) battery_level = 20;
else if(bat_voltage > 3300) battery_level = 10;
else battery_level = 0;
// 电池保护
if(bat_voltage < 3200) // 过放保护
{
DIS_EN = 0; // 禁用放电
CHG_EN = 1; // 强制充电
UART_Send_String("Battery Under Voltage! Charging Enabled\r\n");
}
if(bat_temp > 500) // 温度过高 (50℃)
{
DIS_EN = 0; // 禁用放电
CHG_EN = 0; // 禁用充电
UART_Send_String("Battery Over Temperature! Charging/Discharging Disabled\r\n");
}
}
}
// 充放电控制
void Charging_Control(void)
{
unsigned int out_voltage, out_current;
static unsigned char charge_counter = 0;
// 每200ms读取一次输出参数
if(charge_counter++ >= 20)
{
charge_counter = 0;
// 读取输出电压 (单位: mV)
out_voltage = Read_ADC(ADC_OUT_VOLT) * 10;
// 读取输出电流 (单位: mA)
out_current = Read_ADC(ADC_OUT_CURR) * 10;
// 过压保护
if(out_voltage > (pd_voltage * 100 + 500)) // 超过设定值0.5V
{
DIS_EN = 0; // 禁用放电
UART_Send_String("Output Over Voltage! Discharging Disabled\r\n");
}
// 过流保护
if(out_current > 3500) // 超过3.5A
{
DIS_EN = 0; // 禁用放电
UART_Send_String("Output Over Current! Discharging Disabled\r\n");
}
// 短路保护
if(out_voltage < 1000 && out_current > 3000) // 电压低于1V且电流大于3A
{
DIS_EN = 0; // 禁用放电
UART_Send_String("Short Circuit Detected! Discharging Disabled\r\n");
}
}
}
// LED状态显示
void LED_Display(void)
{
static unsigned char led_counter = 0;
// LED显示状态
if(led_counter++ >= 50) // 每500ms更新一次
{
led_counter = 0;
// 充电状态
if(charging_state)
{
// 充电中 - 呼吸灯效果
static unsigned char pwm_val = 0;
static bit dir = 0;
if(dir == 0)
{
if(++pwm_val == 100) dir = 1;
}
else
{
if(--pwm_val == 0) dir = 0;
}
// 红色LED呼吸效果
if(led_counter < pwm_val) LED_RED = 1;
else LED_RED = 0;
LED_GREEN = 0;
LED_BLUE = 0;
}
else
{
// 电量显示
if(battery_level > 70)
{
LED_RED = 0;
LED_GREEN = 1; // 绿色 - 电量充足
LED_BLUE = 0;
}
else if(battery_level > 30)
{
LED_RED = 0;
LED_GREEN = 0;
LED_BLUE = 1; // 蓝色 - 电量中等
}
else
{
LED_RED = 1; // 红色 - 电量低
LED_GREEN = 0;
LED_BLUE = 0;
}
}
// PD输出状态
if(pd_connected && DIS_EN)
{
// 输出中 - 蓝色LED闪烁
static bit blink = 0;
blink = !blink;
LED_BLUE = blink;
}
}
}
// 读取ADC值
unsigned int Read_ADC(unsigned char channel)
{
unsigned int result;
ADC_CONTR = 0x80 | (channel & 0x07); // 选择通道并启动转换
_nop_(); _nop_(); _nop_(); // 等待转换完成
while(!(ADC_CONTR & 0x10)); // 等待转换完成
ADC_CONTR &= ~0x10; // 清除完成标志
result = ADC_RES;
result = (result << 2) | (ADC_RESL & 0x03); // 10位ADC
return result;
}
// 延时函数
void Delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i=0; i<ms; i++)
for(j=0; j<120; j++);
}
// UART发送一个字节
void UART_Send_Byte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
// UART发送字符串
void UART_Send_String(char *s)
{
while(*s)
{
UART_Send_Byte(*s++);
}
}
程序功能说明
1. PD协议处理
void PD_Protocol_Handler(void)
{
// 检测CC引脚状态变化
// 发送电源能力信息
// 处理PD请求和响应
// 控制输出使能
}
2. 电池管理
void Battery_Management(void)
{
// 监测电池电压和温度
// 计算电池电量百分比
// 实现过放保护和过温保护
}
3. 充放电控制
void Charging_Control(void)
{
// 监测输出电压和电流
// 实现过压、过流和短路保护
// 控制充放电状态
}
4. LED状态显示
void LED_Display(void)
{
// 显示电池电量状态
// 充电状态呼吸灯效果
// PD输出状态指示
}
参考源码 针对PD协议移动电源进行开发的51单片机控制程序 youwenfan.com/contentcna/70937.html
硬件连接说明
1. 电源部分
电池组 + --------[MOSFET]-----+------ USB-C VBUS
| |
电池组 - --------+ |
| |
+--[升降压电路]--+
2. 控制部分
STC89C52RC/STC12C5A60S2
P1.0 ---- USB CC1
P1.1 ---- USB CC2
P1.2 ---- USB D-
P1.3 ---- USB D+
P1.4 ---- ADC 电池电压检测
P1.5 ---- ADC 电池温度检测
P1.6 ---- ADC 输出电压检测
P1.7 ---- ADC 输出电流检测
P2.0 ---- LED_RED
P2.1 ---- LED_GREEN
P2.2 ---- LED_BLUE
P3.0 ---- CHG_EN (充电使能)
P3.1 ---- DIS_EN (放电使能)
P3.2 ---- KEY (功能按键)
3. PD协议实现方案
由于51单片机本身不支持USB PD协议,本设计采用以下两种方案之一:
方案1:软件模拟PD协议(简化版)
- 通过CC引脚检测连接状态
- 使用UART模拟PD通信
- 支持基本电压档位切换
方案2:专用PD协议芯片
+-----------------+ +-----------------+
| 51 单片机 | I2C | PD协议芯片 |
| |<-------->| (如CH236D) |
| | | |
+--------+--------+ +--------+--------+
| |
| |
| |
+--------+--------+ +--------+--------+
| 电池管理电路 | | USB-C接口 |
| 升降压电路 | | |
| | | |
+-----------------+ +-----------------+
关键算法详解
1. 电池电量计算
// 基于电压的简化电量计算
if(bat_voltage > 4200) battery_level = 100;
else if(bat_voltage > 4100) battery_level = 90;
...
2. 充电状态呼吸灯
// 呼吸灯效果实现
if(dir == 0) {
if(++pwm_val == 100) dir = 1;
} else {
if(--pwm_val == 0) dir = 0;
}
if(led_counter < pwm_val) LED_RED = 1;
else LED_RED = 0;
3. 保护机制
// 过压保护
if(out_voltage > (pd_voltage * 100 + 500)) {
DIS_EN = 0;
}
// 过流保护
if(out_current > 3500) {
DIS_EN = 0;
}
// 短路保护
if(out_voltage < 1000 && out_current > 3000) {
DIS_EN = 0;
}
系统工作流程
-
初始状态
- 所有LED熄灭
- 充放电均禁用
- 检测USB连接
-
设备连接
- 检测CC引脚状态变化
- 发送电源能力信息
- 协商输出电压
-
放电模式
- 使能放电电路
- 监测输出电压电流
- 显示电池电量
-
充电模式
- 检测输入电源
- 使能充电电路
- 实现恒流/恒压充电
-
保护机制
- 电池过放/过温保护
- 输出过压/过流保护
- 短路保护
优化建议
1. 增加快充协议支持
// 添加QC协议支持
void QC_Protocol_Handler(void)
{
// 检测D+/D-电压
// 发送QC电压请求
// 切换升降压电路输出
}
2. 增加电量计功能
// 库仑计实现
void Coulomb_Counter(void)
{
// 测量充放电电流
// 积分计算电量
// 更新剩余容量
}
3. 添加OLED显示
// OLED显示函数
void OLED_Display(void)
{
// 显示输出电压电流
// 显示电池电量
// 显示温度信息
// 显示工作状态
}
4. 低功耗优化
// 休眠模式
void Enter_Sleep_Mode(void)
{
// 禁用不需要的外设
// 设置IO状态
// 进入空闲/掉电模式
// 定时唤醒检测
}
测试与调试
1. PD协议测试
- 连接PD充电器,验证5V输出
- 按键切换电压档位,验证9V/12V/15V/20V输出
- 断开连接,验证自动关闭输出
2. 保护功能测试
- 输出端短路,验证短路保护
- 连接大功率负载,验证过流保护
- 电池过放测试,验证充电强制启用
3. 性能测试
- 测量转换效率(输入功率 vs 输出功率)
- 测试输出电压纹波
- 测量不同负载下的电压稳定性
完整系统框架
+------------------+
| 51单片机 |
| +-----------+ |
| | PD协议处理 | |
| +-----------+ |
| +-----------+ |
| | 电池管理 | |
| +-----------+ |
| +-----------+ |
| | 充放电控制 | |
| +-----------+ |
| +-----------+ |
| | 状态显示 | |
| +-----------+ |
+------------------+
|
| 控制信号
|
+------------------+
| 电源管理电路 |
| +-------------+ |
| | 升降压电路 | |
| +-------------+ |
| +-------------+ |
| | 保护电路 | |
| +-------------+ |
+------------------+
|
| USB-C
|
+------------------+
| 外部设备 |
+------------------+
这个程序实现了基于51单片机的PD协议移动电源核心控制功能,包括PD协议处理、电池管理、充放电控制和状态显示。程序采用模块化设计,可根据实际硬件进行调整和扩展。

浙公网安备 33010602011771号