提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、所需要的主要器件
  • 二、硬件电路图
    • 1.单相逆变主电路
    • 2.继电器过流过压保护
    • 3.辅助电源供电
    • 4.IR2104驱动
  • 三、软件流程图
    • 1.Visio流程图
    • 2.主函数
    • 3.定时器中断函数
    • 4.逆变器SPWM函数
  • 四、实物调试图片
  • 总结

前言

本篇文章是对单相逆变电路进行实战演练的一次项目,主要实现功能为:

直流电压48V输入,通过STM32F103C8T6单片机输出SPWM波,通过IR2104S驱动模块控制两组对管的开关闭合,通过LCL滤波实现工频正弦波的平滑输出。额定输出电压为24V,额定输出电流为2A,额定输出功率为48W,适合对逆变电路感兴趣的朋友实战演练。

实物图如下:


一、所需要的主要器件

1、STM32F103C8T6开发板一块
2、0.96寸OLED屏幕一块
3、IRF540N(MOSFET管)四个
4、1mh铁铝硅电感33MM
5、MKP电容10uf(圆柱形)
6、两个IR2104驱动模块
7、交流电计量模块HLW8032

二、硬件电路图

1.单相逆变主电路


主要原理为:HO3、LO3为IR2104S驱动模块1驱动,HO2、LO2为IR2104S驱动模块2驱动。在任一瞬间,HO3和LO3波形相反,HO2与LO2波形相反,且HO3和HO2波形相反。即整体电路只对应两种工作状态:

第一种工作状态为:直流电流通过Q1mos管流经L6,负载L3再流经Q4最终到达地,在这一工作状态里,若负载上端视为电压正极,则负载上会加上一个正向的电压,也即处于正弦波的正半周期。

第二种工作状态为:直流电流通过Q3mos管流经L3,负载L6再流经Q2最终到达地,在这一工作状态里,若负载上端视为电压正极,则负载上会加上一个反向的电压,也即处于正弦波的负半周期。

2.继电器过流过压保护


CTRL为单片机控制继电器开关闭合的信号,I+和I-分别连至逆变电路的输出和负载的上端。若CTRL给低电平,9013关闭,继电器磁铁不吸合,I+和I-处于连接状态。若CTRL给高电平,则9013导通,继电器磁铁吸合,I-和FLOAT处于连接状态,电路输出浮空,起到保护作用。

3.辅助电源供电


12V电源适配器输入,通过7805降压至5V,给单片机和总体供电。

4.IR2104驱动

芯片输入口主要有四个信号,一个是12V的供电信号,一个是PWM的驱动信号,一个是5V的芯片使能信号,另外一个是数字地。输出口同样有四个信号,分别为HO,VS,LO和模拟地。本驱动的功能是,输入一路PWM信号,在HO和LO口得到互补的PWM波,VS接在对管MOSFET的中间,即上管的S端和下管的D端,利用自举驱动原理驱动上管开关闭合。

三、软件流程图

1.Visio流程图

2.主函数

代码如下(示例):

/*
STM32F103C8T6
iic通信0.96寸OLED显示屏;显示中英文、数字、图片
18B20温度传感器
HC-SR04超声波传感器OLED接线定义:VCC--3.3V/5VGND--GNDSCL--PB8SDA--PB9
*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "string.h"
#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "stdio.h"
#include "timer.h"
#include "usart.h"
#include "usart2.h"
#include "led.h"
#include "show.h"
#include "main.h"
#include "pid.h"
#include "key.h"
float jiaozheng=1.0023f;
/*电能数据采集参量设置*/
extern u32 Voltage_Parameter_Reg,Voltage_Reg,Current_Reg,Current_Parameter_Reg,Power_Parameter_Reg,Power_Reg;
extern u8 Data_Updata_Reg;
extern u16 PF_Reg;
float ACVotage,ACCurrent,ActivePower,ApparentPower,PowerFactor,ElectricEnergy;
u8 Pre_Data_Updata_Reg;
u16 UpdataCount;
u32 PFCount,PF_OneDegree;
u8 buf[5]={11,12,12,12,12};
/*实际电路运行中需要用到的一些电路参数*/
u8 gonglv_status=1;                     //功率状态标志位,为1时是额定48W输出,为2时是额定24W输出,为3时是额定12W输出
u8 dianya_status=1;                     //电压状态标志位,为1时是调节整数位输出,为2时是调节小数位输出
u8 work_mode=0;                         //工作模式为0,代表启动界面;工作模式为1,代表模式选择界面;
u8 mode_status=1;                       //=1代表指向额定电压输出,=2代表指向额定功率输出,=3代表指向初始启动界面
u8 key_value=0;                         //按键键值,1-4分别代表control,choice,add,reduce
float duty=1000.0f;                     //逆变电路的调制系数
float AC_Target=240.0f;                 //逆变电路输出目标值
float gonglv_Target=232.0f;             //功率追踪位
float PID_flag=0;                       //PID使能控制位
float kp_v=0.04;                          //P环调节系数
float kp_p=0.04;
float dianzu=11.20f;
/*第一次进入界面使能*/
u8 mode_1=0;
u8 mode_2=0;
u8 mode_3=0;
u8 mode_4=0;
int main(void)
{   u16 i=0;u8 x=0,y=0;  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级                 delay_init();           //延时uart_init(9600);        //串口初始化uart2_init(4800);        //串口初始化为115200TIM3_Int_Init(3600-1,1-1);//10KHZTIM4_Int_Init(3600-1,2-1);//10KHZBOOST_PWM_Init();LED_Init();             //LED初始化KEY_Init();init_PID();             //初始化PID参数OLED_Init();          //初始化OLED  OLED_Clear();loop:GPIO_SetBits(GPIOB,GPIO_Pin_5);        //关闭继电器qidong_view();       TIM_Cmd(TIM1,DISABLE);PID_flag=0;duty=0;AC_Target=240.0f;while(1){key_value=KEY_Scan(0);if(key_value==1){work_mode=1;TIM_Cmd(TIM1,ENABLE);GPIO_ResetBits(GPIOB,GPIO_Pin_5);for(i=1;i<=1000;i++){duty=i;delay_ms(1);}break;           }}choice_view();while(1){key_value=KEY_Scan(0);//扫描键值/*选择初始界面函数*/if(work_mode==0){           goto loop;}/*选择界面处理函数*/else if(work_mode==1){if(mode_1==0)choice_view(),mode_1=1,PID_flag=0,duty=600;if(key_value==2){mode_status+=1;if(mode_status==4){mode_status=1;}}else if(key_value==1){mode_1=0;if(mode_status==1)work_mode=2;else if(mode_status==2)work_mode=3;else if(mode_status==3)work_mode=0;}if(mode_status==1){OLED_ShowString(90,2,"<-",16);OLED_ShowString(90,4,"  ",16);OLED_ShowString(90,6,"  ",16);}else if(mode_status==2){OLED_ShowString(90,2,"  ",16);OLED_ShowString(90,4,"<-",16);OLED_ShowString(90,6,"  ",16);}else if(mode_status==3){OLED_ShowString(90,2,"  ",16);OLED_ShowString(90,4,"  ",16);OLED_ShowString(90,6,"<-",16);}}/*选择电压界面处理函数*/else if(work_mode==2){if(mode_2==0)dianya_view(),mode_2=1;if(key_value==2){dianya_status+=1;if(dianya_status==3){dianya_status=1;}}else if(key_value==1){mode_2=0;PID_flag=1;work_mode=4;                }else if(key_value==4&&dianya_status==1){AC_Target+=10;}else if(key_value==4&&dianya_status==2){AC_Target+=1;}else if(key_value==3&&dianya_status==1){AC_Target-=10;}else if(key_value==3&&dianya_status==2){AC_Target-=1;}if(dianya_status==1){OLED_ShowString(90,2,"<-",16);OLED_ShowString(90,4,"  ",16);}else if(dianya_status==2){OLED_ShowString(90,2,"  ",16);OLED_ShowString(90,4,"<-",16);}OLED_ShowNum(56,2,(int)AC_Target/10,2,16);OLED_ShowNum(56,4,(int)AC_Target%10,1,16);OLED_ShowNum(56,6,(int)AC_Target/10,2,16);OLED_ShowNum(80,6,(int)AC_Target%10,1,16);}/*选择功率界面处理函数*/else if(work_mode==3){if(mode_3==0)gonglv_view(),mode_3=1;if(key_value==2){gonglv_status+=1;
//              if(gonglv_status==3)
//              {//                  gonglv_status=1;
//              }if(gonglv_status==4){gonglv_status=1;}}else if(key_value==1){mode_3=0;PID_flag=1;work_mode=4;if(gonglv_status==1)gonglv_Target=232.0f;else if(gonglv_status==2)gonglv_Target=164.0f;else if(gonglv_status==3)gonglv_Target=116.0f;                }
//          else if(key_value==4&&gonglv_status==1)
//          {//              gonglv_Target+=10;
//          }
//          else if(key_value==4&&gonglv_status==2)
//          {//              gonglv_Target+=1;
//          }
//          else if(key_value==3&&gonglv_status==1)
//          {//              gonglv_Target-=10;
//          }
//          else if(key_value==3&&gonglv_status==2)
//          {//              gonglv_Target-=1;
//          }
//          if(gonglv_status==1)
//          {//              OLED_ShowString(90,2,"<-",16);
//              OLED_ShowString(90,4,"  ",16);
//          }
//          else if(gonglv_status==2)
//          {//              OLED_ShowString(90,2,"  ",16);
//              OLED_ShowString(90,4,"<-",16);
//          }
//          OLED_ShowNum(56,2,(int)gonglv_Target/10,2,16);
//          OLED_ShowNum(56,4,(int)gonglv_Target%10,1,16);
//          OLED_ShowNum(56,6,(int)gonglv_Target/10,2,16);OLED_ShowNum(80,6,(int)gonglv_Target%10,1,16);if(gonglv_status==1){OLED_ShowString(90,2,"<-",16);OLED_ShowString(90,4,"  ",16);OLED_ShowString(90,6,"  ",16);}else if(gonglv_status==2){OLED_ShowString(90,2,"  ",16);OLED_ShowString(90,4,"<-",16);OLED_ShowString(90,6,"  ",16);}else if(gonglv_status==3){OLED_ShowString(90,2,"  ",16);OLED_ShowString(90,4,"  ",16);OLED_ShowString(90,6,"<-",16);}}/*参数选择界面*/else if(work_mode==4){if(mode_4==0)canshu_view(),mode_4=1;if(key_value==1){mode_4=0;PID_flag=0;work_mode=1;         }/*显示电压电流数据*/OLED_ShowNum(40,0,(u32)(ACVotage*100)/100,2,16);OLED_ShowNum(64,0,(u32)(ACVotage*100)%100,2,16);OLED_ShowNum(40,2,(u32)(ACCurrent*100)/100,2,16);OLED_ShowNum(64,2,(u32)(ACCurrent*100)%100,2,16);OLED_ShowNum(40,4,(u32)(ApparentPower*10)/10,3,16);OLED_ShowNum(72,4,(u32)(ApparentPower*10)%10,1,16);}ACVotage=(Voltage_Parameter_Reg*1.88/Voltage_Reg)*jiaozheng;//电压有效值if(ACVotage<=2)ACVotage=0;ACCurrent=(Current_Parameter_Reg*1.0/Current_Reg)*0.4893;//电流有效值if(ACCurrent<0.1)//无电压时电压又飘移{ACCurrent=0;ApparentPower=0;ActivePower=0;PowerFactor=0;}if(ACVotage>2&&ACCurrent>0.1)//空载时电流有飘移{ApparentPower=ACVotage*ACCurrent;//视在功率ActivePower=Power_Parameter_Reg*1.88/Power_Reg;//有功功率PowerFactor=ActivePower/ApparentPower;//功率因数}printf ("电压有效值:%f\r\n",ACVotage);printf ("电流有效值:%f\r\n",ACCurrent);printf ("视在功率:%f\r\n",ApparentPower);printf ("有功功率:%f\r\n",ActivePower);printf ("功率因数:%f\r\n",PowerFactor);if(Pre_Data_Updata_Reg!=(Data_Updata_Reg&0x80)){UpdataCount++;Pre_Data_Updata_Reg=Data_Updata_Reg&0x80;}PFCount=UpdataCount*65536+PF_Reg;//脉冲信号个数PF_OneDegree=1000000000/Power_Parameter_Reg;PF_OneDegree=PF_OneDegree*3600/1.88;//1度电对应的脉冲个数;ElectricEnergy=(float)PFCount/(float)PF_OneDegree;//电能printf ("电能:%f\r\n",ElectricEnergy);delay_ms(50);      }

主代码里面主要是对于界面的显示和模式的切换,以及处理交流电压和交流电流等参数数据。

3.定时器中断函数

#include "timer.h"
#include "inverter.h"
#include "main.h"
#include "pid.h"
#include "usart.h"
#include "string.h" #define BOOST_TIMx TIM1
#define BOOST_Plus 0//初始化占空比为0.5%,高电平有效时的低电平占空比
#define BOOST_ARR (3600-1)//重装载值1000
#define BOOST_PSC (1-1)//分频系数2
void BOOST_PWM_Init(void)//boost电路输出互补PWM波形(PA8、PB13)
{   GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_BDTRInitTypeDef TIM_BDTRInitStruct;TIM_OCInitTypeDef TIM_OCInitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); //使能PORTA,B时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//初始化GPIO,PA8GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//端口复用GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure); //PA8GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;GPIO_Init(GPIOB,&GPIO_InitStructure);//PB13//初始化时具单元TIM_DeInit(BOOST_TIMx);TIM_TimeBaseInitStruct.TIM_ClockDivision=0;TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period=BOOST_ARR;TIM_TimeBaseInitStruct.TIM_Prescaler=BOOST_PSC;TIM_TimeBaseInit(BOOST_TIMx,&TIM_TimeBaseInitStruct);//将输出通道2初始化为PWM模式1TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;TIM_OCInitStruct.TIM_OutputNState=TIM_OutputNState_Enable;TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OCInitStruct.TIM_OCNPolarity=TIM_OCNPolarity_High;TIM_OCInitStruct.TIM_OCIdleState=TIM_OCIdleState_Set;TIM_OCInitStruct.TIM_OCNIdleState=TIM_OCNIdleState_Reset;TIM_OCInitStruct.TIM_Pulse=BOOST_Plus;TIM_OC1Init(BOOST_TIMx,&TIM_OCInitStruct);//使能预装载寄存器TIM_OC1PreloadConfig(BOOST_TIMx,TIM_OCPreload_Enable);//死区和刹车功能配置TIM_BDTRInitStruct.TIM_OSSIState=TIM_OSSIState_Disable;TIM_BDTRInitStruct.TIM_OSSRState=TIM_OSSRState_Disable;TIM_BDTRInitStruct.TIM_LOCKLevel=TIM_LOCKLevel_1;TIM_BDTRInitStruct.TIM_DeadTime=0; //40.92nsTIM_BDTRInitStruct.TIM_BreakPolarity=TIM_BreakPolarity_Low;TIM_BDTRInitStruct.TIM_Break=TIM_Break_Disable;TIM_BDTRInitStruct.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;TIM_BDTRConfig(BOOST_TIMx,&TIM_BDTRInitStruct);//使能自动重装载TIM_ARRPreloadConfig(BOOST_TIMx,ENABLE);//开启定时器TIM_Cmd(BOOST_TIMx,DISABLE);//主输出使能TIM_CtrlPWMOutputs(BOOST_TIMx,ENABLE);
}
//定时器7中断服务程序
void TIM2_IRQHandler(void)
{   if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//是更新中断{                TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIM7更新中断标志    TIM_Cmd(TIM2, DISABLE);  //关闭TIM7 }
}void TIM2_Int_Init(u16 arr,u16 psc)
{   NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//TIM7时钟使能    //定时器TIM7初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM7中断,允许更新中断TIM_Cmd(TIM2,ENABLE);//开启定时器7NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;      //子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器}
void TIM3_IRQHandler(void)
{   static u16 jishu=0;if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//是更新中断{ inverter_spwm();if(jishu==400){jishu=0;if(PID_flag==1){if(mode_status==1)duty=PID_X(ACVotage*10,AC_Target,kp_v,2,1200);else if(mode_status==2)duty=PID_X(ACVotage*10,gonglv_Target,kp_p,2,1200); //else if(mode_status==2)duty=PID_X(ACVotage*10,sqrt((gonglv_Target/10)*11.2)*10,kp_p,2,1200);             }}jishu++;TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIM7更新中断标志    }
}void TIM3_Int_Init(u16 arr,u16 psc)
{   NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//TIM3时钟使能    //定时器TIM7初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断TIM_Cmd(TIM3,ENABLE);//开启定时器3NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器}void TIM4_IRQHandler(void)
{   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中断{ TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIM7更新中断标志    }
}
void TIM4_Int_Init(u16 arr,u16 psc)
{   NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//TIM3时钟使能    //定时器TIM7初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断TIM_Cmd(TIM4,ENABLE);//开启定时器3NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器}/*选择通道函数*/
void set_pwm(TIM_TypeDef* TIMx,u8 chx,u16 prec,u16 up)
{//判断输入参数是否正确if(chx<1||chx>4)return;if(prec>up)prec=up;//根据输入的通道设置PWM占空比switch(chx){case 1:TIM_SetCompare1(TIMx,prec);break;case 2:TIM_SetCompare2(TIMx,prec);break;     case 3:TIM_SetCompare3(TIMx,prec);break;case 4:TIM_SetCompare4(TIMx,prec);break;           }
}

定时器一主要是用来输出互补的PWM波,定时器二和定时器四无明显作用,定时器三主要是控制SPWM波的生成以及进行PID运算。定时器三时钟频率为20KHz,在其中断里面定义了一个暂态变量,每进入400次中断循环复位一次,这样没执行一次中断改变一次PWM的占空比,即可实现SPWM波的生成。PID由于我们的信号采集模块每隔50ms发一次数据,所以选择50Hz的频率进行一次PID的运算。

4.逆变器SPWM函数

#include "inverter.h"
#include "timer.h"
#include "main.h"
#define length 400u16 sinData[length]=
{1800,1821,1842,1864,1885,1906,1927,1949,1970,1991,2012,2033,2054,2075,2096,2117,
2137,2158,2179,2199,2219,2240,2260,2280,2300,2320,2339,2359,2378,2397,2416,2435,
2454,2473,2491,2510,2528,2546,2563,2581,2598,2615,2632,2649,2666,2682,2698,2714,
2730,2745,2760,2775,2790,2805,2819,2833,2847,2860,2873,2886,2899,2911,2924,2935,
2947,2958,2969,2980,2990,3001,3010,3020,3029,3038,3047,3055,3063,3071,3078,3085,
3092,3098,3105,3110,3116,3121,3126,3130,3134,3138,3142,3145,3148,3150,3152,3154,
3156,3157,3158,3158,3159,3158,3158,3157,3156,3154,3152,3150,3148,3145,3142,3138,
3134,3130,3126,3121,3116,3110,3105,3098,3092,3085,3078,3071,3063,3055,3047,3038,
3029,3020,3010,3001,2990,2980,2969,2958,2947,2935,2924,2911,2899,2886,2873,2860,
2847,2833,2819,2805,2790,2775,2760,2745,2730,2714,2698,2682,2666,2649,2632,2615,
2598,2581,2563,2546,2528,2510,2491,2473,2454,2435,2416,2397,2378,2359,2339,2320,
2300,2280,2260,2240,2219,2199,2179,2158,2137,2117,2096,2075,2054,2033,2012,1991,
1970,1949,1927,1906,1885,1864,1842,1821,1800,1778,1757,1735,1714,1693,1672,1650,
1629,1608,1587,1566,1545,1524,1503,1482,1462,1441,1420,1400,1380,1359,1339,1319,
1299,1279,1260,1240,1221,1202,1183,1164,1145,1126,1108,1089,1071,1053,1036,1018,
1001,984,967,950,933,917,901,885,869,854,839,824,809,794,780,766,
752,739,726,713,700,688,675,664,652,641,630,619,609,598,589,579,
570,561,552,544,536,528,521,514,507,501,494,489,483,478,473,469,
465,461,457,454,451,449,447,445,443,442,441,441,441,441,441,442,
443,445,447,449,451,454,457,461,465,469,473,478,483,489,494,501,
507,514,521,528,536,544,552,561,570,579,589,598,609,619,630,641,
652,664,675,688,700,713,726,739,752,766,780,794,809,824,839,854,
869,885,901,917,933,950,967,984,1001,1018,1036,1053,1071,1089,1108,1126,
1145,1164,1183,1202,1221,1240,1260,1279,1299,1319,1339,1359,1380,1400,1420,1441,
1462,1482,1503,1524,1545,1566,1587,1608,1629,1650,1672,1693,1714,1735,1757,1778
};void inverter_spwm(void)
{static u16 spwm_count=0;set_pwm(TIM1,1,(u16)((sinData[spwm_count%length]-1800)*duty/1000+1800),3500);    spwm_count++;if(spwm_count>=400)spwm_count=0;
}

如上图所示,想要实现SPWM波的效果我们就得让PWM波模拟出SPWM波的效果,由于我们单片机不能产生负压信号,所以我们在此处假定PWM波输出占空比为50%的时候,等同于输出电压0V。原理也在于,如果占空比为50%时,那么正压和负压加在负载上的功率一致,相互抵消最终宏观上显现的就是0V的电压。占空比大于50%时,相当于输出正压,小于50%时相当于输出负压。因此只需让PWM波以50%占空比为原点,让其按照正弦规律变化即刻,比如从50%一直升到90%,然后再从90%缓慢降到10%,再升到50%由此就实现了一个正弦规律的变化,在此处还设置了调制系数,通过控制调制系数的大小,可以改变超出50%和低于50%占空比的占空比大小。比如若之前设定为最高75%占空比输出,最低25%输出,改变调制系数的大小,使其最高输出90%占空比,最低10%占空比,这样输出的交流电压幅值就会高。

而改变调制系数也不能直接乘以我们数组里面的占空比,由于我们设置的重装载值是3600,对应的最大占空就为100%,因此以1800为中心点进行正弦规律变化。想要改变上下幅值大小,首先将数组里面执行的当前值减去1800,然后再乘以调制系数,最终再加上一个1800就能得到相对于50%占空比的幅值倍增而不是整体倍增。大家画画图就可以理解了。

四、实物调试图片

1、额定电压输出24V

2、额定电压输出16V


3、额定电压输出8V

总结

这就是单相逆变电路的设计,有不懂的朋友可以评论下方留言,我看到了就会回复

单相逆变电路实战!(基于STM32F103C8T6的单相逆变电路,PID控制输出额定电压)相关推荐

  1. 基于台达PLC的水箱液位PID控制(matlab处理数据)

    1.实验目的 (1)掌握过程控制的方法: (2)熟练掌握台达编程技巧: (3)熟悉实验室水箱系统.变频器的接线方法: (4)学会用文件寄存器来读取数据并处理数据: (5)学会台达PLC内部PID控制器 ...

  2. 基于simulink的车用质子交换膜燃料电池(PEMFC)PID控制系统仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 能源是人类社会赖以生存和发展的重要物质基础,能源的开发利用极大地推进了世界经济和人类社会的发展.随着 ...

  3. 基于遗传算法和粒子群算法的PID悬架控制、LQR悬架控制和滑模悬架控制

    目录 1.基于遗传算法和粒子群算法的的PID悬架控制 1.1 两种悬架系统 1.1.1 将路面激励整合到悬架系统 1.1.2 不将路面激励整合到悬架系统 1.1.3 总结 1.2 PID经典控制理论 ...

  4. 练习 电源 基于STM32F103C8T6的单片机降压电路

    基于STM32F103C8T6的单片机降压电路 一.任务 实验三的电路采用TL494内部的误差放大器实现电压的稳定,叫做硬件闭环控制,优点是控制快速,但缺点是电路复杂,改变PID参数不方便.用软件也可 ...

  5. DSP28335,三相逆变电路电压闭环程序,三相逆变数字电源程序

    DSP28335,三相逆变电路电压闭环程序,三相逆变数字电源程序. 包括源代码文件和PDF说明文件. 详细说明了代码含义,三相逆变电路电路电压闭环分析,电路设计步骤,软件设计流程,软件调试步骤等. I ...

  6. 项目实战——基于计算机视觉的物体位姿定位及机械臂抓取(单目标定)

    项目实战--基于计算机视觉的物体位姿定位及机械臂抓取(单目标定) 请各位读者朋友注意,这里面很多东西涉及到我的毕设,写作辛苦,请勿滥用,转载请务必注明出处!         单目标定主要分为两个部分, ...

  7. 【STM32】基于STM32F103C8T6的水质检测系统设计(声光报警、多级菜单)

    需求 1.检测参数:水温.TDS.浊度.PH 2.超出阈值声光报警 3.LCD显示目标参数的测量结果 4.测量模式:单参数测量.所有参数表同时测量 切换方式:按键切换 原理 单总线技术 单总线技术采用 ...

  8. 《数据分析实战 基于EXCEL和SPSS系列工具的实践》一第2章 数据分析的理论、工具、模型...

    本节书摘来自华章出版社<数据分析实战 基于EXCEL和SPSS系列工具的实践>一书中的第2章,第2.1节,纪贺元 著,更多章节内容可以访问云栖社区"华章计算机"公众号查 ...

  9. 基于FPGA的单目内窥镜定位系统设计(上)

    今天给大侠带来基于FPGA的单目内窥镜定位系统设计,由于篇幅较长,分三篇.今天带来第一篇,上篇,话不多说,上货. 导读 随着现科技的发展和社会的进步,信息科技迅速发展,我们可从互联网.电台等媒体获取大 ...

最新文章

  1. 搭建高可用mongodb集群(二)—— 副本集
  2. selenium + python自动化测试环境搭建
  3. php date的警告
  4. 如何成为一名专家级的开发人员
  5. 理解CMS GC日志
  6. HDU1907 ZJU3113
  7. 创建 WPF 不规则窗口
  8. c#实现播放器的集中方式
  9. 20191024:单调栈问题的引出
  10. Linux多网卡配置高级策略路由---从哪里来就回哪里去~!
  11. android的findviewbyid,Android开发中如何简化findViewById类型转换
  12. Win10设置系统保护色
  13. 【STM32f401学习之路-02】USART串口通信
  14. 克里斯蒂安贝尔_克里斯蒂安贝尔现身机场,身材瘦到认不出来,蝙蝠侠又开始减重了...
  15. Go语言环境搭建详解(2020版)
  16. # android移动开发——第十三章——个人理财通案例(Eclipse版)
  17. 【备赛必读】2021年 全国大学生英语竞赛 命题大纲
  18. [POI2005]DWU-Double-row(图论?)
  19. revi怎么弄插件能够使附件发生一定角度的旋转?
  20. pytorch学习(五)---torch.nn模块

热门文章

  1. Wireles Tools移植
  2. 【Python3】文本分类综合(rnn,cnn,word2vec,TfidfVectorizer),中文纠错代码解析(pycorrector)
  3. kafka(1) 初识
  4. 【语音唤醒】MDTC:Multi-scale dilated temporal convolutional network
  5. 不可忽视的UPS电源电池除尘
  6. windows 生成免费ssl证书 配置 https
  7. 关于ES自定义script painless的问题
  8. 安装Python3.7 spyder
  9. 【工具】JS脚本|网页任意视频倍速播放(包括MOOC、本地视频、其他的视频)
  10. 教学|3DsMAX怎么样制作环境贴图,3D建模步骤教程