基于STM32的多功能数控电源设计

基于STM32的多功能数控电源设计

一、系统概述与核心功能

1. 系统定位

基于STM32的多功能数控电源是一款高精度、宽范围、智能化的实验室电源,支持恒压(CV)和恒流(CC)两种工作模式,具备过压(OVP)、过流(OCP)、过温(OTP)等多重保护功能。系统采用PID闭环控制算法,通过STM32的PWM和ADC实现精确的电压/电流调节,并配备OLED显示屏和旋转编码器实现便捷的人机交互。

2. 核心功能模块

模块 功能描述 技术指标
电源变换 采用同步Buck拓扑,输入电压12-24V DC,输出0-30V/0-5A可调 效率≥92%,纹波≤50mVpp
控制核心 STM32F103C8T6,72MHz Cortex-M3,12位ADC,PWM分辨率1/1000 电压调节精度±0.05V,电流调节精度±0.01A
采样反馈 高侧电流采样(INA240)+ 分压电阻电压采样,双路ADC同步采样 电压采样精度±0.5%,电流采样精度±1%
人机交互 0.96寸OLED显示,旋转编码器调节参数,按键切换模式 显示分辨率128×64,参数调节步进0.01V/0.001A
保护功能 过压保护(OVP)、过流保护(OCP)、过温保护(OTP)、短路保护 响应时间<10ms,保护精度±2%
扩展接口 USB通信(虚拟串口)、电压/电流校准接口、外部控制接口 支持PC端软件监控和控制

二、硬件设计方案

1. 核心硬件选型

模块 型号 关键参数 接口方式
主控MCU STM32F103C8T6 72MHz,64KB Flash,20KB RAM,3个ADC,4个定时器 核心控制器
电源变换 同步Buck模块 输入12-24V,输出0-30V/5A,开关频率200kHz 外部功率模块
电流采样 INA240A2 增益50V/V,共模电压-4V至80V,带宽400kHz ADC1_IN0(电流采样)
电压采样 精密分压电阻 100kΩ+10kΩ 1%精度,分压比1/11 ADC1_IN1(电压采样)
显示模块 OLED 12864(I2C) 0.96寸,128×64像素,自发光 I2C1(PB6/PB7)
交互模块 EC11旋转编码器+按键 20脉冲/圈,带按键功能 PB0-PB2(编码器A/B/Z相)
保护模块 NTC热敏电阻+比较器 过温检测阈值85℃,硬件快速关断 ADC1_IN2(温度采样)

2. 硬件电路设计要点

2.1 电源变换电路(同步Buck)

输入电压Vin (12-24V)
    │
    ├── 输入滤波电容(100μF+0.1μF)
    │
    ├── 同步Buck控制器(如LM5176)
    │   ├── PWM输入:STM32 PB1(TIM3_CH4)
    │   ├── 反馈电压:来自输出电压分压
    │   └── 使能控制:STM32 PB3
    │
    ├── 功率电感(33μH,饱和电流≥8A)
    ├── 同步整流MOSFET(IRF540N×2)
    ├── 输出滤波电容(470μF+10μF)
    │
    └── 输出电压Vout (0-30V)

2.2 采样电路设计

电压采样:
Vout ──[100kΩ]──┬──[10kΩ]── GND
                 └── ADC1_IN1(电压采样点)

电流采样:
Vout ──[采样电阻0.01Ω]──负载
         │
         └── INA240A2(增益50V/V)
              ├── 输入+:采样电阻高端
              ├── 输入-:采样电阻低端
              └── 输出:ADC1_IN0(电流采样点)

2.3 保护电路设计

过压保护(硬件):
Vout ──[分压电阻]──比较器+输入端
参考电压──比较器-输入端
比较器输出──STM32 PB4(外部中断)
当Vout > 设定阈值时,比较器输出低电平,触发中断关断PWM

过温保护:
NTC热敏电阻──ADC1_IN2
STM32实时监测温度,超过85℃时降低输出或关断

三、软件设计与核心代码

1. 系统架构(前后台系统)

采用前后台系统,以定时器中断为后台,主循环为前台:

  1. TIM2定时器中断(1ms):执行PID控制算法,更新PWM输出

  2. 主循环

    • 读取旋转编码器和按键状态
    • 更新OLED显示
    • 检查保护条件并执行保护动作
    • 处理USB通信命令

2. 核心代码实现(基于标准库)

2.1 PID控制算法

#include "pid.h"

// PID参数结构体
typedef struct {
    float Kp;           // 比例系数
    float Ki;           // 积分系数
    float Kd;           // 微分系数
    float setpoint;     // 设定值
    float feedback;     // 反馈值
    float integral;     // 积分项
    float prev_error;    // 上次误差
    float output;       // 输出值
    float output_min;   // 输出最小值
    float output_max;   // 输出最大值
} PID_Controller_t;

// PID计算函数
float PID_Calculate(PID_Controller_t *pid) {
    float error = pid->setpoint - pid->feedback;
    
    // 比例项
    float P = pid->Kp * error;
    
    // 积分项(带抗饱和)
    pid->integral += error;
    if (pid->integral > pid->output_max) pid->integral = pid->output_max;
    if (pid->integral < pid->output_min) pid->integral = pid->output_min;
    float I = pid->Ki * pid->integral;
    
    // 微分项
    float D = pid->Kd * (error - pid->prev_error);
    pid->prev_error = error;
    
    // 计算输出并限幅
    pid->output = P + I + D;
    if (pid->output > pid->output_max) pid->output = pid->output_max;
    if (pid->output < pid->output_min) pid->output = pid->output_min;
    
    return pid->output;
}

// 电压PID控制器
PID_Controller_t voltage_pid = {
    .Kp = 2.5f,       // 比例系数
    .Ki = 0.8f,       // 积分系数
    .Kd = 0.1f,       // 微分系数
    .setpoint = 12.0f,  // 设定电压12V
    .feedback = 0.0f,  // 实际电压
    .integral = 0.0f,
    .prev_error = 0.0f,
    .output = 0.0f,
    .output_min = 0.0f,
    .output_max = 1000.0f  // PWM最大占空比
};

// 电流PID控制器
PID_Controller_t current_pid = {
    .Kp = 1.5f,
    .Ki = 0.5f,
    .Kd = 0.05f,
    .setpoint = 1.0f,    // 设定电流1A
    .feedback = 0.0f,
    .integral = 0.0f,
    .prev_error = 0.0f,
    .output = 0.0f,
    .output_min = 0.0f,
    .output_max = 1000.0f
};

2.2 ADC采样与转换

#include "adc.h"

// ADC采样值转实际电压/电流
float ADC_ToVoltage(uint16_t adc_value) {
    // ADC参考电压3.3V,12位分辨率
    float voltage_adc = (float)adc_value * 3.3f / 4095.0f;
    // 分压比1/11,实际电压 = 采样电压 × 11
    return voltage_adc * 11.0f;
}

float ADC_ToCurrent(uint16_t adc_value) {
    // INA240增益50V/V,采样电阻0.01Ω
    // 电流 = (ADC电压 / 增益) / 采样电阻
    float voltage_adc = (float)adc_value * 3.3f / 4095.0f;
    return (voltage_adc / 50.0f) / 0.01f;  // 单位:安培
}

// 读取电压和电流
void Read_Voltage_Current(float *voltage, float *current) {
    // 启动ADC转换
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
    uint16_t adc_voltage = ADC_GetConversionValue(ADC1);
    
    ADC_SoftwareStartConvCmd(ADC2, ENABLE);
    while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC));
    uint16_t adc_current = ADC_GetConversionValue(ADC2);
    
    *voltage = ADC_ToVoltage(adc_voltage);
    *current = ADC_ToCurrent(adc_current);
}

2.3 PWM输出控制

#include "pwm.h"

// 初始化PWM(TIM3_CH4,PB1)
void PWM_Init(void) {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    
    // 时基配置:72MHz / (71+1) = 1MHz
    TIM_TimeBaseStructure.TIM_Period = 999;        // ARR=999,PWM频率1kHz
    TIM_TimeBaseStructure.TIM_Prescaler = 71;     // PSC=71
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    
    // PWM通道配置
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;            // 初始占空比0%
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC4Init(TIM3, &TIM_OCInitStructure);
    
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
}

// 设置PWM占空比(0-1000对应0-100%)
void PWM_SetDuty(uint16_t duty) {
    if (duty > 1000) duty = 1000;
    TIM_SetCompare4(TIM3, duty);
}

2.4 主控制逻辑

#include "main.h"

// 系统状态
typedef enum {
    MODE_CV = 0,    // 恒压模式
    MODE_CC = 1     // 恒流模式
} PowerMode_t;

PowerMode_t system_mode = MODE_CV;
float set_voltage = 12.0f;    // 设定电压
float set_current = 1.0f;     // 设定电流
float actual_voltage = 0.0f;  // 实际电压
float actual_current = 0.0f;   // 实际电流

// TIM2中断服务函数(1ms执行一次PID控制)
void TIM2_IRQHandler(void) {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
        // 读取实际电压和电流
        Read_Voltage_Current(&actual_voltage, &actual_current);
        
        if (system_mode == MODE_CV) {
            // 恒压模式:电压PID控制
            voltage_pid.setpoint = set_voltage;
            voltage_pid.feedback = actual_voltage;
            float pid_output = PID_Calculate(&voltage_pid);
            PWM_SetDuty((uint16_t)pid_output);
            
            // 如果电流超过设定值,切换到恒流模式
            if (actual_current > set_current * 1.05f) {
                system_mode = MODE_CC;
            }
        } else {
            // 恒流模式:电流PID控制
            current_pid.setpoint = set_current;
            current_pid.feedback = actual_current;
            float pid_output = PID_Calculate(&current_pid);
            PWM_SetDuty((uint16_t)pid_output);
            
            // 如果电压低于设定值,切换到恒压模式
            if (actual_voltage < set_voltage * 0.95f) {
                system_mode = MODE_CV;
            }
        }
        
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

int main(void) {
    // 系统初始化
    SystemClock_Config();
    GPIO_Init();
    ADC_Init();
    PWM_Init();
    OLED_Init();
    Encoder_Init();
    
    // 启动TIM2中断(1ms)
    TIM2_Init();
    
    while (1) {
        // 扫描旋转编码器
        Encoder_Scan();
        
        // 更新OLED显示
        OLED_ShowVoltage(set_voltage, actual_voltage);
        OLED_ShowCurrent(set_current, actual_current);
        OLED_ShowMode(system_mode);
        
        // 检查保护条件
        Protection_Check();
        
        // 处理USB通信
        USB_Process();
    }
}

四、系统调试与优化

1. PID参数整定

参数 调整方法 现象 解决方案
Kp过小 逐步增大Kp 响应慢,稳态误差大 增大Kp直到出现小幅震荡
Kp过大 逐步减小Kp 震荡剧烈,不稳定 减小Kp直到稳定
Ki过小 逐步增大Ki 稳态误差消除慢 增大Ki加快消除静差
Ki过大 逐步减小Ki 积分饱和,超调量大 减小Ki,增加积分限幅
Kd过小 逐步增大Kd 超调量大,震荡 增大Kd抑制超调
Kd过大 逐步减小Kd 响应迟缓,高频噪声敏感 减小Kd

2. 系统校准

// 电压校准函数
void Voltage_Calibration(void) {
    float measured_voltage;
    float actual_voltage;
    
    // 设置输出电压为10.00V
    set_voltage = 10.00f;
    Delay_ms(2000);  // 等待稳定
    
    // 读取实际电压(用高精度万用表测量)
    actual_voltage = 10.00f;  // 假设实际测量值为10.00V
    measured_voltage = actual_voltage;
    
    // 计算校准系数
    float calibration_factor = actual_voltage / measured_voltage;
    
    // 保存校准系数到EEPROM
    EEPROM_WriteFloat(CALIB_VOLTAGE_ADDR, calibration_factor);
}

3. 保护功能测试

测试项目 测试方法 预期结果
过压保护 逐步增加设定电压,超过30V 电源自动关断,显示"OVP"
过流保护 输出端短路 电流限制在5A以内,显示"OCP"
过温保护 加热散热片至85℃ 降低输出功率或关断,显示"OTP"
短路恢复 短路后移除短路 自动恢复正常输出

参考代码 基于STM32的多功能数控电源设计(原理图、PCB、程序源码等) www.youwenfan.com/contentcnt/123512.html

五、扩展功能

1. 高级功能扩展

2. 安全增强设计

六、总结

基于STM32的多功能数控电源通过PID闭环控制实现高精度稳压稳流,同步Buck拓扑保证高效率,多重保护机制确保使用安全。

专注于matlab/simulink,电子电路,编程