基于STM32控制的数字BUCK电路及程序编写

本文芯片采用STM32G474CBT6,采用STM32cubeMX进行程序生成。

BUCK电路拓扑结构:

 如图所示,BUCK变换器主要由电源VDC、场效应管MOSFET、续流二极管VD、电感L以及滤波电容C和负载RES组成。当MOSFET开通时,电流通过MOSFET给电感L储能,同时给负载供电;当MOSFET关闭时,电感L释放能量,电流从电感L经过负载再通过续流二极管VD流回电感L。通过改变MOSFET的开关时间,即改变MOSFET的占空比D可以控制输出电压的大小,其中D=Vo/Vi,该公式只适用于BUCK变换器中的CCM模式。

控制方式:

模拟控制:

传统的模拟控制方式通常采用电源控制芯片控制电路,如常用的UC3842。该控制方式通常将输出电压通过反馈电路产生一个电压与电源芯片内部的基准进行比较,再将比较的得到的值与芯片的锯齿波进行比较产生PWM波,通过这样的一个控制回路调节占空比,最终与芯片内部基准相等,从而进行稳压的目的。        

数字控制:

图1为数字控制的流程图,输出电压通过电压采样电路进入MCU的AD模块,AD模块在一定的周期内对AD的值进行采样与MCU设置的基准进行比较产生误差,(图1中VDC2可看为MCU设置的基准)产生的误差进入PID算法中进行一个误差运算,再将运算出来的值进行一个限幅,防止PWM过大或者过小对电路造成不稳定。控制量再经过MCU内部定时器的预分频器的值进行除运算得出相对应的占空比值赋给定时器更新占空比对MOSFET进行控制。其中PID需要每个周期进行一次运算。

 图1        

程序编写:

得知数字控制的流程之后我们就可以将其转换为程序放入MCU中,其中最重要的是AD采样的位置和PID算法。

如图2所示,在一个周期的中点对ADC进行采样是最好的,这样可以避免开关噪声所带来的误差。程序中采用HRTIM1的TimerA的寄存器1产生PWM波,寄存器3进行触发AD采用。

 图2

接下来开始编写程序。

以下程序为定时器寄存器3的中断回调函数,用同一个定时器的好处就是可以方便确定AD采样的点,该程序主要进行ADC的采样和PID的计算,其中将采样回来的值进行换算成实际电压后放入PID程序中进行计算。电压是否要放大根据自己的实际采样电路进行取舍,也可自行加入滤波程序。

void HAL_HRTIM_Compare3EventCallback(HRTIM_HandleTypeDef * hhrtim, uint32_t timerA)
{
	uint32_t sum = 0;								//循环总和
	uint32_t value_sum = 0;							//滤波后电压
	
	Vout = ADC_Value[1]*3.3f/4095;			        //计算采样出来的实际电压
	Value = Vout * 1000;							//电压放大一千倍
	PID_Incremental(Value,251);			            //PID计算
}

以下程序为PID程序,首先定义需要用到的变量,再将这些变量进行初始化赋值,其次就进入PID的主要程序。该程序有两个变量,一个是AD采样得到的值,一个是自己设置的一个值,(设置值主要根据自己想要的输出电压进行设置)首先计算出设置值和当前采样值的误差(若采样电压有放大则需要除一个放大倍数,若采样时没有放大,则不需要),求得多几次的误差,得到误差后就可以放入PID的程序中进行计算出ERROR_Increase_V。(PID的公式为∆u= Kp * [e- ek-1 + Ki * e+ Kd * [e- 2ek-1 + e(k-2)])计算完PID后将误差进行移位,留给下一次计算做准备。将计算得到的ERROR_Increase_V进行占空比的限幅,防止没有设置合适的PID参数时得到的结果过大对电路造成损坏。用得到的ERROR_Increase_V计算出实际电压计算出占空比赋值给定时器的寄存器1更新占空比,将计算出的占空比的一半的值赋值给寄存器3进行更新ADC的采样点。其中PID的参数对电路的稳定性有决定性的影响,调试PID参数时可采用串口的方式进行调试,但是调整好参数之后要将串口程序进行屏蔽,否则输出电压会跳动。

float  Kp_V;             //比例系数
float  Ki_V;             //积分系数
float  Kd_V;             //微分系数
float  error1_V;         //当前输出和设定值误差
float  error2_V;         //当前输出和设定值误差
float  e1_V;             //上次输出和设定值误差
float  e2_V;             //上上次输出和设定值误差

float  Duty;			 //占空比
float  ERROR_Increase_V; //占空比增加量

uint32_t Pulse_width = 0;		 //占空比宽度
 
void PID_init(void)              //PID初始化
{	
	Kp_V = 0.3f;                 //比例系数
	Ki_V = 0.001f;               //积分系数
	Kd_V = 0.8;                  //微分系数

	error1_V = 0.0;              //当前输出和设定值误差
	error2_V = 0.0;              //当前输出和设定值误差
	e1_V = 0.0;                  //上次输出和设定值误差
	e2_V = 0.0;                  //上上次输出和设定值误差

	ERROR_Increase_V = 0.0; 	 //占空比增加量
	Duty = 0.0;
}

void PID_Incremental(uint16_t Vout_actual,uint16_t Vset_target) //当前电压和设置电压
{
	error1_V = (Vset_target - Vout_actual) * 0.001f;		    //当前误差
	e1_V = error1_V - error2_V;									//上上次误差
	ERROR_Increase_V += Kp_V * e1_V + Ki_V * error1_V + Kd_V * (e1_V - e2_V);	//PID算法
	error2_V = error1_V;								        //移位
	e2_V = e1_V;												//移位
	
	if(ERROR_Increase_V >= 2.706f)		    //限制最大占空比82% 	
	{
		ERROR_Increase_V = 2.706f;
	}
	if(ERROR_Increase_V <= 0.33f)	        //限制最小占空比10%		
	{
		ERROR_Increase_V = 0.33f;
	}
	
	Duty = ERROR_Increase_V * 0.303030303f;				           //计算电压
	Pulse_width = Duty * 27200;									   //计算占空比
		
	hhrtim1.Instance->sTimerxRegs[0].CMP1xR = Pulse_width;         //修改占空比
	hhrtim1.Instance->sTimerxRegs[0].CMP3xR = Pulse_width >> 1;    //修改AD的采样点
	
}

BUCK电路改为同步整流只需要将续流二极管改为MOSFET即可,程序只需要将PWM波改为互补的PWM即可。

  • 32
    点赞
  • 191
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值