基于stm32的单相正弦变频稳压电源.docx
《基于stm32的单相正弦变频稳压电源.docx》由会员分享,可在线阅读,更多相关《基于stm32的单相正弦变频稳压电源.docx(59页珍藏版)》请在冰豆网上搜索。
![基于stm32的单相正弦变频稳压电源.docx](https://file1.bdocx.com/fileroot1/2023-1/22/58bad9a0-f26b-46e4-a30e-822404829de4/58bad9a0-f26b-46e4-a30e-822404829de41.gif)
基于stm32的单相正弦变频稳压电源
基于stm32的单相正弦变频稳压电源
本项设计的的要求是:
输入40V到60V。
输出稳定的有效值18V,80W。
重载超过5A时,过流保护。
输出正弦波频率在20Hz到60Hz可调,步进为1Hz。
我们做的DC/AC主电路采用全桥式,双极性SPWM,驱动芯片采用IR2110,极容易烧毁,使用时应倍加小心。
用电流互感器采电流,电压互感器采电压,电压经过全波整流后送到stm32里。
这个设计大部分工作由软件完成。
难点在于要调度好中断之间的关系,理解PI的整个控制过程。
如果理解有偏差,就会出现无论怎么改变PI的系数,输出都稳不了压。
同时,硬件电路也要做好。
做电源不要引太多线出来,易受到干扰。
尽量避免使用过零比较器,因为过零比较器的上升沿下降沿极不稳定,易导致单片机误触发。
下面在多分享下我做这个设计时的调试经验:
1,利用高级定时器TIM1,产生SPWM,中断优先级一定要设成最高抢断式2,带重载时波形会失真,原因主要是死区时间和开关管损耗,可以尝试下改小死区时间。
3,我的PI思路是这样的,在一个正弦波周期内,做一次PI。
具体实现方法是:
电压互感器采过来的经全波整流的波对应一个比较器产生的方波,正弦波过零时产生上升沿翻转,触发单片机开始定时,技术到四分之一个周期时,打开AD和DMA,在峰值处连续采14个点,然后排序,去掉最大的三个和最小的三个,然后相加求平均值。
做一次PI,在下个正弦波开始时,赋给Ma。
这里关键是AD一定要采的准,可以设置电平翻转来用示波器观察是不是在峰值附近采值。
下面给出全部代码:
main.h
#ifndef__MAIN_H
#define__MAIN_H
voidRCC_Configuration(void);
voidNVIC_Configuration(void);
voidGPIO_Configuration(void);
voidADC_Configuration(void);
voidTIM_Configuration(void);
voidADC_DMAInit(void);
voidEXTI_Configuration(void);
voiddisplay1(void);
voiddisplay2(void);
voiddisplay3(void);
voiddisplay4(void);
voiddisplay5(void);
voidpinlvzhuanhua(void);
#endif
main.c
#include"stm32f10x_lib.h"
#include"stm32f10x_it.h"
#include"stm32f10x_dma.h"
#include"stm32f10x_adc.h"
#include
#include"lcd1602.h"
#include"juzhenkey.h"
#include"main.h"
/*Privatetypedef-----------------------------------------------------------*/
/*Privatedefine------------------------------------------------------------*/
/*Privatemacro-------------------------------------------------------------*/
/*Privatevariables---------------------------------------------------------*/
/*Privatefunctionprototypes-----------------------------------------------*/
/*Privatefunctions---------------------------------------------------------*/
/*******************************************************************************
*FunctionName:
main
*Description:
Mainprogram.
*Input:
None
*Output:
None
*Return:
None
*******************************************************************************/
#defineN14
#defineADC1_DR_Address((u32)0x4001244c)
unsignedshortADCConvertedValue[N];
EXTI_InitTypeDefEXTI_InitStructure;
ErrorStatusHSEStartUpStatus;
NVIC_InitTypeDefNVIC_InitStructure1;
floatxianshi=0.0;
u8i=0;
u8v1=0,v2=0;
u8p1=0,p2=0,p3=0;
u8pp=0;
u8Time50Ms=0;
floatnn=0.4;
vu16pulse=0;
vu16Period=20;
s8shuzi[]="0123456789";
s8pinlv[]="20HZ";
s8dianya[]="18V";
s8table[]="0.000V";
s8ma[]="0.00";
s8OverCurrent[]="OverCurrent!
!
!
";
u8pinlvshezhi=20;
u8dianyashezhi=18;
u8flag1=0;
u8flag2=0;
u8OverCurrentFlag=0;
floatdel=0.4;
intmain(void)
{
#ifdefDEBUG
debug();
#endif
pinlvzhuanhua();
RCC_Configuration();
GPIO_Configuration();
DelayXms(60);
Lcd_Init();
DelayXms(20);
display1();
TIM_Configuration();
NVIC_Configuration();
EXTI_Configuration();
CH451_Init();
ADC_Configuration();
ADC_DMAInit();
DelayXms(60);
Lcd_Init();
display1();
/*Infiniteloop*/
while
(1)
{
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5))
{
TIM_Cmd(TIM1,DISABLE);
TIM_CtrlPWMOutputs(TIM1,DISABLE);
Lcd_Init();
display5();
OverCurrentFlag=1;
DelayXms(200);
}
elseif((!
(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)))&&(OverCurrentFlag==1))
{
TIM_Cmd(TIM1,ENABLE);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
Lcd_Init();
OverCurrentFlag=0;
}
elseif((!
(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)))&&(OverCurrentFlag==0))
{
DelayXms(200);
display2();
DelayXms(200);
display3();
}
}
}
voidRCC_Configuration(void)
{
RCC_DeInit();//将外设RCC寄存器重设为缺省值
RCC_HSEConfig(RCC_HSE_ON);//使能HSE,即外部高速晶振
HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待HSE就绪
if(HSEStartUpStatus==SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能预取指令缓存
FLASH_SetLatency(FLASH_Latency_2);//设置代码延时值Flash2waitstate
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置AHB时钟HCLK=SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速AHB时钟PCLK2=HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速AHB时钟PCLK1=HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//设置PLL时钟源及倍频系数PLLCLK=8MHz*9=72MHz
RCC_PLLCmd(ENABLE);
//等待PLL就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET){}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//选定PLL为系统时钟源
while(RCC_GetSYSCLKSource()!
=0x08){}//确认PLL作为系统时钟源
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_AFIO,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1|RCC_AHBPeriph_DMA2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_GPIOA
|RCC_APB2Periph_GPIOB
|RCC_APB2Periph_GPIOC
|RCC_APB2Periph_GPIOD
|RCC_APB2Periph_GPIOE,
ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM4,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
}
voidEXTI_Configuration(void)
{
EXTI_DeInit();//将EXIT寄存器重设置为缺省值
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource6);//设置为外部中断
EXTI_InitStructure.EXTI_Line=EXTI_Line6;//设置外部中断线
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI线路为重点请求
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路为下降沿为中断请求
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//中断使能
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource1);//设置为外部中断
EXTI_InitStructure.EXTI_Line=EXTI_Line1;//设置外部中断线
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI线路为重点请求
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;//设置输入线路为下降沿为中断请求
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//中断使能
EXTI_Init(&EXTI_InitStructure);
//EXTI_GenerateSWInterrupt(EXTI_Line5);
EXTI_ClearFlag(EXTI_Line6|EXTI_Line1);
EXTI_ClearFlag(EXTI_Line1|EXTI_Line1);
//EXTI_ClearFlag(EXTI_Line0);
}
voidNVIC_Configuration(void)
{
NVIC_InitTypeDefNVIC_InitStructure;
#ifdefVECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else/*VECT_TAB_FLASH*/
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
/*EnabletheTIM1globalInterrupt*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*EnabletheDMAInterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*EnabletheEXTI9_5globalInterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*EnabletheTIM2globalInterrupt*/
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQChannel;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
//NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//NVIC_Init(&NVIC_InitStructure);
}
voidGPIO_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
//配置1602的控制端RSRWE
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
/*GPIOCConfiguration:
Channel1,2and3asalternatefunctionpush-pull*/
//配置D8--D15为1602数据口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|
GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/**********************键盘*****************************/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
/**********************键盘*****************************/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
//GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);//AD输入测电压
//GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
//GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入测电压
//GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;