STM32F103 DCDC 数控开关电源方案

一、系统总体设计

拓扑:同步 / 非同步 Buck(降压)
控制核心:STM32F103C8T6 / CBT6
控制方式数字 PID + PWM + ADC 反馈
设定方式:电位器 / 按键 / 串口
显示:OLED / LCD / 串口打印

        ┌──────────┐
        │  STM32   │
        │  PWM OUT ├────► MOSFET Driver ──► BUCK
        │  ADC IN  │◄──── 电压反馈(分压)
        │  ADC IN  │◄──── 电流采样
        └──────────┘

二、硬件关键参数

项目推荐
MCUSTM32F103C8T6
PWM 定时器TIM1(高级定时器)
PWM 频率20–65 kHz(常用 40kHz)
ADCADC1
电压采样电阻分压(到 0–3.3V)
电流采样运放 + 采样电阻
MOS 驱动IR2104 / TC4427 / AO3400
输出电感33–100 µH
输出电容220–470 µF

三、核心控制

目标电压 − 实际电压 → PID → 改变 PWM 占空比


四、关键源码

1、PWM 初始化(TIM1_CH1)

void PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);

    // PA8 -> TIM1_CH1
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period = 999;        // 72MHz / (999+1) = 72kHz
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    TIM_Cmd(TIM1, ENABLE);
}

2、ADC 初始化(电压 + 电流)

void ADC_Init_Buck(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // PA0:电压 PA1:电流
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);

    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
}
uint16_t ADC_Read(uint8_t ch)
{
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
    return ADC_GetConversionValue(ADC1);
}

3、PID 控制器

typedef struct
{
    float Kp;
    float Ki;
    float Kd;

    float err;
    float last_err;
    float integral;
    float out;
} PID_TypeDef;

void PID_Init(PID_TypeDef *pid)
{
    pid->Kp = 0.8f;
    pid->Ki = 0.05f;
    pid->Kd = 0.01f;

    pid->err = 0;
    pid->last_err = 0;
    pid->integral = 0;
}

float PID_Calc(PID_TypeDef *pid, float target, float feedback)
{
    pid->err = target - feedback;

    pid->integral += pid->err;
    if(pid->integral > 500) pid->integral = 500;
    if(pid->integral < -500) pid->integral = -500;

    pid->out = pid->Kp * pid->err +
               pid->Ki * pid->integral +
               pid->Kd * (pid->err - pid->last_err);

    pid->last_err = pid->err;
    return pid->out;
}

4、主循环(数控电源核心)

#define VREF  3.3f
#define ADC_MAX 4095.0f

PID_TypeDef pid;

int main(void)
{
    float v_set = 12.0f;   // 目标电压
    float v_fb;
    float duty;

    SystemInit();
    PWM_Init();
    ADC_Init_Buck();
    PID_Init(&pid);

    while(1)
    {
        uint16_t adc_val = ADC_Read(ADC_Channel_0);

        v_fb = adc_val * VREF / ADC_MAX * 11.0f; // 假设 1:10 分压

        duty = PID_Calc(&pid, v_set, v_fb);

        if(duty < 0) duty = 0;
        if(duty > 999) duty = 999;

        TIM_SetCompare1(TIM1, (uint16_t)duty);

        Delay_ms(10);
    }
}

五、保护功能

过压保护

if(v_fb > 24.0f) TIM_SetCompare1(TIM1, 0);

过流保护

if(current > 5.0f) TIM_SetCompare1(TIM1, 0);

软启动

for(i=0;i<v_set;i+=0.1){ v_set_now=i; Delay_ms(5); }

参考代码 基于STM32F103的DCDC数控开关电源源码 www.youwenfan.com/contentcsv/72889.html

六、常见问题

问题原因
输出抖动PID 参数过大
空载不稳没有最小占空比限制
上电炸管没有软启动
电压不准没校准分压比
效率低PWM 频率太高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值