基于STM32G4系列MCU的3kW数字LLC电源控制代码
一、硬件配置与资源分配
1. MCU选型与外设配置
c
// 使用STM32G474RBT6芯片
#define HRTIM_INSTANCE TIM1 // 高分辨率定时器
#define ADC_INSTANCE ADC1 // 高精度ADC
#define PWM_FREQ 250000 // 250kHz开关频率
#define RESONANT_FREQ 175000 // 175kHz谐振频率
// 外设初始化
void Peripherals_Init(void) {
__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
// HRTIM配置(用于PWM生成)
TIM_HandleTypeDef htim1;
htim1.Instance = HRTIM_INSTANCE;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim1);
// ADC配置(同步采样)
ADC_HandleTypeDef hadc1;
hadc1.Instance = ADC_INSTANCE;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
HAL_ADC_Init(&hadc1);
}
二、核心控制算法实现
1. 非线性PID控制器
c
typedef struct {
float Kp, Ki, Kd;
float prev_error;
float integral;
} PID_Controller;
float Nonlinear_PID(PID_Controller *pid, float error) {
// 分段式增益调整(根据负载区间)
if(error > 10.0f) {
pid->Kp = 1.2f; pid->Ki = 0.001f; pid->Kd = 0.5f;
} else if(error > 5.0f) {
pid->Kp = 0.8f; pid->Ki = 0.0005f; pid->Kd = 0.3f;
} else {
pid->Kp = 0.5f; pid->Ki = 0.0001f; pid->Kd = 0.1f;
}
float P = pid->Kp * error;
pid->integral += error;
float I = pid->Ki * pid->integral;
float D = pid->Kd * (error - pid->prev_error);
pid->prev_error = error;
return P + I + D;
}
2. 谐振腔状态观测器
c
// 基于龙贝格观测器的谐振电流重构
float Resonant_Current_Observer(float Vcr, float Lr, float Cr) {
static float x_hat = 0.0f;
static float P[2][2] = {{1.0f, 0.0f}, {0.0f, 1.0f}};
// 状态方程
float dxdt = (Vcr - x_hat) / (Lr * Cr);
x_hat += dxdt * 1e-6f; // 1μs时间步长
// 协方差更新
P[0][0] += 1e-12f;
return x_hat;
}
三、中断服务程序设计
1. HRTIM中断(10μs周期)
c
void HRTIM_TIM1_IRQHandler(void) {
if(__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE)) {
// 1. 同步ADC采样
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buffer, 2);
// 2. 计算开关频率
float Vout = adc_buffer[0] * 3.3f / 4095.0f;
float error = Vout_ref - Vout;
float freq_adj = Nonlinear_PID(&pid_controller, error);
// 3. 动态调整死区时间
uint32_t deadtime = Calculate_DeadTime(freq_adj);
__HAL_TIM_SET_DEADTIME(&htim1, deadtime);
// 4. 触发PWM更新
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, pwm_buffer, 2);
}
}
四、关键外设配置代码
1. PWM初始化(半桥拓扑)
c
void PWM_Init(void) {
TIM_OC_InitTypeDef sConfigOC = {0};
// 主通道配置
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500; // 初始占空比50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim1, TIM_CHANNEL_1, &sConfigOC);
// 死区时间配置
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
sBreakDeadTimeConfig.DeadTime = 480; // 480ns死区
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
}
2. ADC同步采样配置
c
void ADC_DMA_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
// 配置通道1(输出电压采样)
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
HAL_ADC_ConfigChannelAttenuation(&hadc1, ADC_CHANNEL_0, ADC_ATTENUATION_11DB);
// 配置通道2(谐振电流采样)
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
HAL_ADC_ConfigChannelAttenuation(&hadc1, ADC_CHANNEL_1, ADC_ATTENUATION_11DB);
// 启动DMA传输
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buffer, 2);
}
五、调试与优化技巧
1. 波形捕获与分析
使用STM32的探针功能捕获关键信号:
c
// 在调试器中启用探针
__HAL_DBGMCU_FREEZE_TIM1();
HAL_Delay(100); // 捕获100ms波形
__HAL_DBGMCU_UNFREEZE_TIM1();
2. 动态参数调整
通过串口接收实时参数:
c
void USART1_IRQHandler(void) {
if(USART_GetITStatus(USART1, USART_IT_RXNE)) {
char cmd = USART_ReceiveData(USART1);
switch(cmd) {
case 'P': pid_controller.Kp = USART_ReceiveData(USART1)/10.0f; break;
case 'I': pid_controller.Ki = USART_ReceiveData(USART1)/1000.0f; break;
case 'D': pid_controller.Kd = USART_ReceiveData(USART1)/100.0f; break;
}
}
}
六、完整工程结构
LLC_Control/
├── Src/
│ ├── main.c
│ ├── hrtim.c // HRTIM驱动
│ ├── adc.c // ADC采样管理
│ └── pid.c // 非线性PID实现
├── Inc/
│ ├── stm32g4xx_hal_conf.h
│ └── main.h
├── Middlewares/
│ └── USB_Device/ // 调试接口
└── Startup/
└── startup_stm32g474xx.s
参考代码 3KW数字LLC源代码 www.youwenfan.com/contentcsj/70066.html
七、性能优化建议
-
代码优化:
c// 使用查表法替代浮点运算 const uint16_t PID_LUT[100] = {0x1000, 0x1200, ...}; // 预计算参数表
-
编译优化:
c# Makefile配置 CFLAGS += -O3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
-
硬件加速: 启用STM32的FPU单元 使用DMA进行ADC数据搬运
八、调试注意事项
-
硬件连接: 确保谐振电容与电感阻抗匹配 添加RC缓冲电路抑制电压尖峰
-
保护机制:
c// 过流保护逻辑 if(adc_buffer[1] > 3.5f) { HAL_TIM_PWM_Stop(&htim1); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, SET); // 关闭使能信号 }