你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F334的BUCK同步降压数字电源设计  

[复制链接]
Tiny。P 发布时间:2016-7-11 21:20
本帖最后由 Tiny。P 于 2018-9-16 11:03 编辑

1. 方案概述

1.1. 概述
数字电源并不是简单的指在系统中应用了数字器件,如单片机及DSP,而是指整个系统的控制应用数字器件的计算能力和离散控制方法来完成,随着电力电子的发展,电源越来越趋向数字化与智能化发展。本设计采用STM32F334作为控制器的同步降压变换器的数字电源,可以实现降压控制,也可以实现升压控制,能量双向流动。数字控制不只能让电源更简单,还可以让电源实现四遥功能。四遥:遥测、遥信、遥控及遥调。
本设计将介绍同步降压的数字控制方案硬件和软件的设计说明,并附相关电路原理图及参考代码。
1.2. 系统主要结构
如图-1所示,BUCK同步降压系统由辅助电路、控制电路、驱动电路、BUCK电路、信号调理电路构成。具体硬件的介绍及说明见第2章节内容。

同步降压的数字控制方案结构图

同步降压的数字控制方案结构图

-1 基于STM32F334微控制器的BUCK同步降压的数字控制方案结构图
本设计应用了STM32F334PWM模块发出对称的PWM波驱动BUCK电路;通过ADC模块采集直流母线电压,输出电压、输出电流及远端测量,特别说明的是远端测量,认为在电池充放电应用是有效的,因为其可以解决电缆电线的压降问题;预留一个串口通信接口,可以实现与上位机,操作面板等设备通信。
1.3. 主要功能和指标
  • 输入电压:10~64V,输出电压:5~60V
  • 最大电流:5A
  • 最大功率:240w
  • 高效率设计,支持的最大效率超过95%
  • 250 KHz开关频率支持更小的无源组件,从而减小电路板面积并延长寿命
  • 三个满足各种应用场合的控制模式:1) 输出电压控制 2) MPPT 控制(输入电流控制)3) 反向电压控制。
  • 保护机制:过压保护,欠压保护,过流保护。
1.4. 应用对象
适合于太阳能微转换器、数字电源和电池充放电、直流UPS应用
2. 方案硬件设计
2.1. 功率电路

如图-2所示,同步BUCK由经典的BUCK变换而来,具体是使用mos替换二极管实现。输入端与输出端都采用LC滤波,使得输入输出电流连续,便于滤波。输出端的-极采用采用电阻实现电流采样,并经过放大电路放大之后送入MCUADC口,具体将在第2.3节介绍。

BUCK

BUCK

-2 BUCK同步降压电路原理图
2.2. 驱动电路
如图-3所示,MOS管驱动电路采用TI的半桥驱动芯片UCC27211。该器件内部集成自举电容充电用二极管,耐压120V,驱动电流达4A。特别注意,该器件内部不带死区时间功能,为避免上下桥臂同时导通,死区时间必须在MCU上实现。

UCC27211

UCC27211

-3 MOS管驱动电路
2.3. 信号调理电路
信号调理电路包含输入电压检测,输出电压检测,远端电压测量,输出电流检测等,这些功能都是基于TLV2374运算放大器实现并且采用差分形式。
1)输入电压检测
如图-4所示,输入电压检测直接采用电阻分压实现。
表达式:
Vin   =   ADC_V_IN * 31              (式1

12

12


-4 输入电压检测电路

2)输出电压检测
如图-5所示,输出电压检测电路基于TLV2374的差分电路实现,由于主电路的输出端的低端电流采样会对电压检测形成干扰,并且差分电路具有很高的共模信号抑制,有利于猜到准确的信号。
表达式:
Vout   =   ADC_V_OUT * 30              (式2

13

13


-5 输出电压检测电路
3)远端电压检测
如图-6所示,远端电压检测电路基于TLV2374的差分电路实现,远端电压测量对于电池充放电是有效的,可以避免由于导线压降产生的影响。用法:直接接入电池两端,请注意正负极。
表达式:
Vext   =   ADC_EXT_SENSN * 30              (式3

14

14


-6 远端电压检测电路
4)输出电流检测
如图-7所示,输出电流检测电路基于TLV2374的差分放大电路实现,在主电路中采样电阻采用10mΩ,要使MCU能够识别该信号,必须经过放大到一定值。由因为本应用要实现双向DCDC功能,这就使得电流有正负,但是MCU无法采集负信号,这里得认为将电压提高,保证电流在负值时,ADC_I_OUT输出还是为正。所以,采用1:1电阻分压,然后经过一个跟随器(提高驱动能力)输出一个1.65V的参考电压,如图-8所示。到这里,该检测电路就可实现正负点流的采样。
表达式:
Iout   =   ADC_I_OUT - 1.65/ 0.20           (式3

15

15


-7 输出电流检测电路

16

16


-8 参考电压1.65V产生电路


2.4. 控制电路

17.png

-9 控制电路
如图-9所示,控制电路采用STM32F334微控制器,有下载接口,串口通信等接口以及运行指示LED灯。STM32资源分配如表1所示。

1 STM32资源分配
功能分类
引脚名称
对应信号
说明
PWM信号
PA8
PWM1A
上桥臂驱动信号
PA9
PWM1B
下桥臂驱动信号
ADC信号
PA0
ADC_I_OUT
输出电流检测
PA1
ADC_V_OUT
输出电压检测
PA2
ADC_EXT_SENSN
远端电压检测
PA3
ADC_V_IN
输入电压检测
串口通信
PB6
USART1_TX
USART1发送
PB7
USART1_RX
USART1接收
程序下载接口
PA13
SWDAT
SWD仿真接口
PA14
SWCLK
LED指示灯
PB3
LED2
故障指示灯
PB4
LED1
运行指示灯

2.5. 辅助电源电路
如图-10所示图-10 辅助电源电路产生12V3.3V两种电压等级。XL7005A将输入端降压到12VSPX3819-M-3.312V稳压到3.3V

18.png


-10 辅助电源电路

3. 方案主要算法介绍
3.1. PID算法
PID算法是一个很经典的自动控制算法,经过几十年的认证,在我们生活发挥了重大作用。PID的资料已经太多了,此处不再讲述其原理,直接给出C代码,若想了解其根本原理,请自行学习。

PID算法用到的数据:
typedef struct  _PID{   
pid_float32        SetPoint;                //输入:给定值
        pid_float32        Feedback;                //输入:反馈值

        pid_float64        T;                //采样时间
        pid_float64        Kp;                //比例常数
        pid_float64        Ti;                //积分时间
        pid_float64        Td;                //微分时间

        pid_float32        a0;                //系数1:a0 = Kp(1 + T/Ti + Td/T)
        pid_float32        a1;                //系数2: a1 = Kp(1 + 2Td/T)
        pid_float32        a2;                //系数3:a2 = Kp*Td/T

        pid_float32        Ek;       //当前误差
        pid_float32        Ek_1;     //前一次误差
        pid_float32        Ek_2;     //第二次误差

        pid_float32        Output;                        //输出值
        pid_float32        Last_Output;        //上一次输出值
        pid_float32        Increment;                //增量值

        pid_float32        OutMax;                        //输出限制最大值
        pid_float32        OutMin;                        //输出限制最小值

} PID_TypeDef;


PID的数据初始化程序:
void PID_init ( PID_TypeDef *p)
{   

        p->a0                = p->Kp*(1 + 1.0*p->T/p->Ti + 1.0*p->Td/p->T);
        p->a1                = p->Kp*(1 + 2.0*p->Td/p->T);
        p->a2                = 1.0*p->Kp*p->Td/p->T;
}


增量式PID算法:
pid_float32 PID_Calc( PID_TypeDef *p, pid_float32 feedback, pid_float32 ref)
{
        p->Ek        = ref - feedback;                //¼ÆËãÎó²î

        p->Increment                = (  p->a0*p->Ek        - p->a1*p->Ek_1 + p->a2*p->Ek_2 );        //PID¼ÆËã

        p->Output = p->Last_Output + p->Increment;

        if(p->Output > p->OutMax)p->Output   =        p->OutMax;
        if(p->Output < p->OutMin)p->Output   =        p->OutMin;
        p->Ek_2           = p->Ek_1;
        p->Ek_1           = p->Ek;               
        p->Last_Output    = p->Output;
        return p->Output;
}

附件:
img_0122.jpg
img_0124.jpg
img_0125.jpg

===============================================================
数字电源的交流1群: 474805564
数字电源的交流2群: 183376789





评分

参与人数 1 ST金币 +30 收起 理由
wolfgang2015 + 30 很给力! 写的很详细~~

查看全部评分

收藏 20 评论27 发布时间:2016-7-11 21:20

举报

27个回答
Tiny。P 回答时间:2016-7-11 21:20:26
4. BUCK同步减压拓扑及控制方式说明
4.1. BUCK同步降压
降压转换器仅能提供比输入电压低的平均输出电压,这正如其名称所表示的一样。降压转换器的基本原理图和开关波形如图-11所示。在降压转换器中,开关(Q1)与输入电压源VIN 串联。输入电压源VIN 通过功率开关和低通滤波器馈送到输出,而低通滤波器则由电感和电容构成。在稳态运行中,若开关导通时间为TON,输入将向输出和电感(L)提供能量。在TON 期间,电感电流流经功
率开关且VIN 和VOUT 之间的正向电压差将加在电感两端,如图-11(C)所示。因此,电感电流IL 将呈线性规律从当前值IL1 上升到IL2,如图-11(E)所示。在TOFF 期间,当开关关闭,电感电流的方向与前面相同,这是由于电感中的储能继续提供负载所需电流。在Q1 关闭期间(TOFF),二极管D1 提供电感电流回路;因此,该二极管称为续流二极管。在TOFF 期间,输出电压VOUT 将以反方向加在电感两端,如图-11(C)所示。因此,电感电流将从当前值IL2 减小至IL1,如图-11所示。
19.jpg

图-11 电压模式控制

当输出电流要求较高时,续流二极管D1 中过高的功耗将限制可达到的最小输出电压。为减少大电流下的功耗并获得较低的输出电压,采用具有极低导通电阻RDSON的MOSFET替代续流二极管。该MOSFET的导通与关断与降压MOSFET同步。因此,这一结构称为同步降压转换器。该同步MOSFET的栅极驱动信号需与降压开关栅极驱动信号呈现互补关系。
4.2. 控制模式
1)电压模式控制
在电压模式控制中,对输出电压进行测量并将测量结果与参考值(期望的输出电压)进行比较。随后补偿电路将对误差进行处理以产生下一个占空比值,如图-12所示。该模式只有一个控制环,因此易于设计和分析。然而,在这种控制方法中,当输出电压变化时,必须首先对线电压或负载变化进行检测,随后通过反馈环对它们进行校正。
20.jpg

图-12 电压模式控制

2)电流模式控制
电流模式控制技术需要两个反馈环,如图13 所示。在这一模式,需对两个参数进行检测以实现控制目的。在输出电容侧或负载端(称为远程检测)对输出电压进行检测。还需对输出电感/ 原边开关电流进行检测。在电流模式控制中,首先将输出电压和参考电压(期望输出电压)进行比较。补偿电路随后对该误差进行处理以产生电流环的参考信号。这一电流参考信号将与测量电流进行比较。电流补偿电路将对由电压补偿电路产生的参考信号与实际从输入汲取的电流进行比较得到的误差进行处理。这将产生所需占空比以保持输出电压在限定范围之内。由于电流模式控制对电路电流进行检测,因此任何输出负载电流或输入电压的变化在影响输出电压之前都会被校正。由于输入电流取决于输入电压,因此对输入电流的检测具有内在的前馈控制特性。电流模式控制提供了推挽式或桥式转换器内在的输入电流对称特性、内在电流限制特性和多转换器并联连接时的负载分流特性。由于采用电流内环,因此阶跃负载响应和瞬态响应特性也得到改善。
21.jpg

图-13 电流模式控制


4.3. 参考代码
此处给出固定电压输出的DEMO 代码,采用电流模式控制:(此处只给出主函数程序,若要详细代码,请自行到Q群下载)


/*--------Includes--------*/
#include "system_typedef.h"
#include "hp_pid_code.h"
#include "onboard_led.h"
#include "timer.h"
#include "usart.h"
#include "hrpwm.h"
#include "stdio.h"
#include "adc.h"
#include "stdio.h"
#include "string.h"


#define fabs(x)        (x < 0 ? -x : x)        //¾ø¶ÔÖµ¼ÆËã

#define Err_OK                 0x00
#define Err_HV        0x01
#define Err_LV        0x02
#define Err_        0x03



float32        VIPWR        = 0;
float32        VOPWR        = 0;
float32        VOEXT        = 0;
float32        IOPWR        = 0;
float32        PWRIN        = 0;
float32        PWROUT        = 0;
float32 VoutREF = 24;
float32 VinREF          = 28;

uint16  ADC_VIPWR_Value;
uint16  ADC_VOPWR_Value;
uint16  ADC_VOEXT_Value;
uint16  ADC_IOPWR_Value;

uint32 PWM_Period;
uint32 PWM_Duty;
PID_TypeDef pid_voltage_loop;
PID_TypeDef pid_current_loop;

void Get_Voltage_Current(void);

int main(void)
{
static uint64 i        = 0;

u8 Status = 0;
GPIO_InitTypeDef  GPIO_Struct;
  SysTick_Config(SystemCoreClock / 1000);//Systick³õʼ»¯,SysTick end of count event each 1ms
Delay_ms(100);  

  LED_Init();
LED1_On();
LED2_On();
Delay_ms(200);
LED1_Off();
LED2_Off();
Delay_ms(200);
LED1_On();
LED2_On();
Delay_ms(200);
LED1_Off();
LED2_Off();
//-----------USART1_Rx == PB7-------------//
  GPIO_Struct.GPIO_Pin        = GPIO_Pin_7;
  GPIO_Struct.GPIO_Mode        = GPIO_Mode_OUT;
  GPIO_Struct.GPIO_OType = GPIO_OType_PP;
  GPIO_Struct.GPIO_PuPd        = GPIO_PuPd_UP;
GPIO_Struct.GPIO_Speed        = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_Struct);

TIMER3_init(0.1e3);
USART1_init(115200);
PWM_Period        = HrPWM_CHA_Init(200e3);//PWM³õʼ»¯
  
ADC_init();//ADCÍâÉè³õʼ»¯

PID_DeInit( &pid_voltage_loop );
pid_voltage_loop.T        = 1000;//PI²ÉÑùÖÜÆÚ£¬µ¥Î»Îªus
pid_voltage_loop.Kp        = 0.2;
pid_voltage_loop.Ti        = 2000;
pid_voltage_loop.Td        = 0;
pid_voltage_loop.OutMax        = 5;
pid_voltage_loop.OutMin        = -4;
PID_init(&pid_voltage_loop);//µçѹ»·PI²ÎÊý³õʼ»¯

PID_DeInit( &pid_current_loop );
pid_current_loop.T        = 10;//PI²ÉÑùÖÜÆÚ£¬µ¥Î»Îªus
pid_current_loop.Kp        = 12;
pid_current_loop.Ti        = 100;
pid_current_loop.Td        = 0;
pid_current_loop.OutMax        = 0.90*PWM_Period;
pid_current_loop.OutMin        = 0.05*PWM_Period;
PID_init(&pid_current_loop);//µçÁ÷»·PI²ÎÊý³õʼ»¯
Delay_ms(5);
HrPWM_CHA_Update(PWM_Period, 0.05*PWM_Period);
HRTIM_WaveformOutputStart(HRTIM1, HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2 );
Delay_ms(300);
LED1_Off();
LED2_Off();


while (1)
  {
VIPWR        = ADC_VIPWR_Value * 3.3/4095.0*30.00;
VOPWR        = ADC_VOPWR_Value * 3.3/4095.0*30.00;
VOEXT        = ADC_VOEXT_Value * 3.3/4095.0*30.00;
if(((VIPWR < 26 + 1.0)  || fabs(IOPWR) > 6.0) && i > 5 )
{
HRTIM_WaveformOutputStop(HRTIM1, HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2 );
LED2_Off();
if(i%50 == 0)LED1_Toggle();//ָʾµÆ½»ÌæÉÁ˸
}
else
{
LED1_Off();
if(i%50 == 0)LED2_Toggle();//ָʾµÆ½»ÌæÉÁ˸
}
PID_Calc( &pid_voltage_loop, VOPWR, VoutREF);        //µçѹ»·PI¼ÆËã
if(i%1000 == 0)
{
printf("Vin  = %fv\r\nVout = %fv\r\nVext = %fv\r\nIout = %fA\r\nPWM  = %f\r\n", VIPWR, VOPWR, VOEXT, IOPWR, (float)PWM_Duty/PWM_Period);
}
Delay_ms(1);


i++;        //¼ÆÊ±
   }
}

void TIM3_IRQHandler(void)   //TIM3ÖжÏ
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)        {
GPIOB->ODR ^= GPIO_Pin_7;
ADC_IOPWR_Value        = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
ADC_VOPWR_Value        = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2);
ADC_VOEXT_Value        = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_3);
ADC_VIPWR_Value        = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_4);

IOPWR        = -(ADC_IOPWR_Value * 3.3/4095 - 1.585)/0.265;

PWM_Duty        = PID_Calc( &pid_current_loop, IOPWR, pid_voltage_loop.Output);
HrPWM_CHA_Update(PWM_Period, PWM_Duty);//¸üÐÂPWMÕ¼¿Õ±È
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);           //Çå³ýTIMxµÄÖжϴý´¦Àíλ:TIM ÖжÏÔ´
}

#pragma arm section code = "RAMCODE"
void Get_Voltage_Current(void)
{
//        IOPWR        = (float32)(-((ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1) * 3.3)/4095.0 - 1.681)/0.201 );
//        VOPWR        = (float32)((ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2) * 3.3)/4095.0*31.50);
//        VOEXT        = (float32)((ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_3) * 3.3)/4095.0*31.60);
//        VIPWR        = (float32)((ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_4) * 3.3)/4095.0*32.30);
}
#pragma arm section

===============================================================
数字电源的交流群: 474805564

想了解详细源代码,请加入交流群,即可下载。

Tiny。P 回答时间:2016-7-11 21:28:24
同步降压数字电源原理图.pdf (880.39 KB, 下载次数: 807)
harvardx 回答时间:2016-7-12 21:57:20
不错 不知道这个pid代码性能如何.
Tiny。P 回答时间:2016-7-12 22:20:36
harvardx 发表于 2016-7-12 21:57
不错 不知道这个pid代码性能如何.

谢谢夸奖,我一直在用感觉效果还不错,还请再指导优化。
harvardx 回答时间:2016-7-14 19:29:01
已经加群学习 谢谢
1146105613 回答时间:2016-9-26 15:23:52
首先很感谢你的分享。看完了代码,我有两个疑惑的地方,希望可以得到您的指点。首先,PID的采样时间Ts与中断没有关系吗?其次,PID的参数,是实际尝试出来的,还是计算出来的?模拟的buck参数我会算,怎么转变为数字的呢?
加加的杯具 回答时间:2017-7-16 21:45:52
亲,能给点stm32f334的固件库吗?官网下不到。谢谢。2537992865@qq.com
wolfgang2015 回答时间:2018-1-23 22:15:02
这么好的帖子,翻出来读读又是另一番味道~
wangxihe 回答时间:2018-1-25 23:12:19
首先很感谢你的分享
123下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版