基于STM32G474RET6微电网模拟系统功率电路设计

​一、摘要

      本文主要介绍微电网模拟系统功率电路的设计,辅助电路和控制电路设计在以前的文章,三相逆变模块分别由辅助电路供电,系统利用STM32产生SPWM波控制半桥驱动器EG2104实现三相逆变功能。其中MOSFET驱动电路选用自带死区的桥式驱动芯片EG2104驱动,开环输出线电压稳定在24V,相电压输出为24V/根号3=14V,​14X跟号2=19.6V,所以供电电压应大于40V,为留有余量本作品取45V​。

基于STM32G474RET6的微电网模拟系统辅助电源设计 (qq.com)

基于STM32G474RET6的微电网模拟系统控制电路设计 (qq.com)

二、理论分析与计算

1.选择适当的开关频率

       较高的开关频率可以减少变换器的体积和重量,提高输出电压THD,但是随着频率的提高开关管的损耗也会随之增加,开关管的损耗与频率成正比,开关频率越大,损耗也随之升高。因此,综合考虑下逆变器的开关频率为30kHz。

2.选择栅极电容与导通电阻较小的开关管NCE6080K

     减小开关管的栅极串联电阻,可改变控制脉冲上升/下降时间、防止震荡,减小开关管的漏极的冲击电压,本作品用的电阻是3.3欧姆和10姆并联,在栅极串联电阻反接一个二极管可以加速栅极的放电,本作品用的二极管是1N4148;同时在开关管的栅极和源极之间并联较大阻值电阻,本作品用的电阻是10K,减小开关管断开时的静态电流。在开关管的漏极和源极反接一个二极管可以防止MOS管因过压、过流、短路等情况损坏,本作品用的二极管是SS5200(耐压200V),开关管NCE6080K耐压60V。semiee.com/file2/b3808a6c95c74a9dda1fec2c245bf276/Ncepower/Ncepower-NCE6080K.pdf

3.驱动芯片用自带死区时间的EG2104

     EG2104 是一款高性价比的带SD̅̅̅̅功能的 MOS 管、IGBT 管栅极驱动专用芯片,内部集成了逻辑信号输入处 理电路、死区时控制电路、电平位移电路、脉冲滤波电路及输出驱动电路,专用于无刷电机控制器、电源 DC-DC 中的驱动电路。 EG2104 高端的工作电压可达 600V,低端 Vcc 的电源电压范围宽 2.8V~20V,静态功耗小于 1uA。该芯 片输入通道 IN 内建了一个 200K 下拉电阻,SD̅̅̅̅内建了一个 200K 下拉电阻,在输入悬空时使上、下功率 MOS 管处于关闭状态,输出电流能力 IO+/- 1/1.5A,采用 SOP8 封装。

     图1​:eg2104引脚描述图

图2​:eg2104​典型电路

本作品的驱动电路是按照芯片手册来设计的。EG2104芯片数据手册V1.0 (dianyuan.com)

4. 谐波失真的测量
      THD:指输出信号比输入信号多出的谐波成分。谐波失真是系统不完全线性造成的。所有附加谐波电平之和称为总谐波失真。总谐波失真与频率有关。一般说来,1000Hz频率处的总谐波失真最小,因此不少产品均以该频率的失真作为它的指标。同时由于THD的计算比较麻烦,故我们直接用专门的电子仪器来测量THD的值。

5.逆变器滤波器设计

      LC滤波器(正弦波滤波器):由串联电抗L和并联电容C构成。通常电流源的逆变器会使用LCL滤波器,电压源的逆变器会使用LC滤波器。原因是电流源逆变器一般都是与电网相连接,如果使用LC滤波器就会为电网注入开关次谐波,当然这是在电网很强的情况下,如果电网就弱,即系统阻抗较大,其实使用LC滤波器也是没有问题的。

​图3:​正弦波电路结构图

图4:正弦波生成变化图

      正弦波滤波器的电抗和电容必须和电动机的容量精确匹配,否则达不到预期的效果。对于滤波电抗,增大电抗值可以降低输出电压的畸变率,但是当带载情况不变时增大电抗值无益会降低输出电压,甚至会出现拖不动电动机的情况。增大电容值同样可以提高输出电压质量,但是输出电压也会有所降低,并且成本也会相应增加。因此必须寻求平衡点,既能满足滤波要求又能降低成本。

正弦波滤波器的电抗和电容必须和电动机的容量精确匹配,否则达不到预期的效果。对于滤波电抗,增大电抗值可以降低输出电压的畸变率,但是当带载情况不变时增大电抗值无益会降低输出电压,甚至会出现拖不动电动机的情况。增大电容值同样可以提高输出电压质量,但是输出电压也会有所降低,并且成本也会相应增加。因此必须寻求平衡点,既能满足滤波要求又能降低成本。逆变器输出会带有基波的奇数次谐波,我们需要滤除这些谐波或者抑制这些谐波输出。逆变器输出是作为供电所用,输出电阻要小,所以不用 RC 无源滤波器选择用 LC 无源滤波器。

滤波器参数计算:LC 无源低通滤波器是滤除高次谐波分量,使电压输出波形为正弦波。本系统的 SPWM 调制信号为 30K。而输出需要的频率是 50Hz,滤波容易实现。

 滤波器截止频率:​

      设置截止频率f=1.3KHz ,CCB电容 取 10μF。得电路中 L= 1.5mH,满足滤波器的要求。振荡电路(LC振荡器)谐振频率,周期在线计算器 (23bei.com)

三、电路设计

        微电网模拟系统由两个三相逆变器并联构成,作为系统的核心部分,三相逆变电路采用半桥并联结构,完成直流电到三相交流电的转换。两部分三相逆变器电路完全一样,其中一个三相逆变器电路如下图5所示。

图5​:​主功率电路图

图6​:LC电路​图

       微电网模拟系统由三相逆变主电路、驱动电路、电压电流采样电路和控制电路组成,三相逆变电路由 6 个 N 沟道 MOS 管构成一个三相逆变桥,驱动电路采用六输出高压驱动器EG2104。三相逆变电路由三路半桥电路和LC滤波电路组成。半桥电路中,驱动器EG2104在SVPWM波控制下驱动NCE6080K通断,完成逆变。逆变输出电压经LC低通滤波器滤除高频载波,得到正弦交流电压。

四、程序设计

#include "main.h"
#include "adc.h"
#include "dma.h"
#include "i2c.h"
#include "usart.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "oled.h"
uint8_t flag=0,flag1=0;
uint32_t i;
uint16_t PhaseA=0,PhaseB=0,PhaseC=0;
//周期为180,幅值为2834的SPWM表
#define USET 1386
short spwm[180] = {0,98,197,296,394,492,589,685,781,875,969,1061,1152,1242,1330,1416,
1501,1584,1665,1744,1821,1896,1968,2038,2106,2170,2233,2292,2349,2403,2454,2502,
2547,2588,2627,2663,2695,2724,2749,2772,2790,2806,2818,2827,2832,2834,2832,2827,
2818,2806,2790,2772,2749,2724,2695,2663,2627,2588,2547,2502,2454,2403,2349,2292,
2233,2170,2106,2038,1968,1896,1821,1744,1665,1584,1501,1417,1330,1242,1152,1061,
969,875,781,685,589,492,394,296,197,98,0,-98,-197,-296,-394,-492,
-589,-685,-781,-875,-969,-1061,-1152,-1242,-1330,-1417,-1501,-1584,-1665,-1744,-1821,-1896,
-1968,-2038,-2106,-2170,-2233,-2292,-2349,-2403,-2454,-2502,-2547,-2588,-2627,-2663,-2695,-2724,
-2749,-2772,-2790,-2806,-2818,-2827,-2832,-2834,-2832,-2827,-2818,-2806,-2790,-2772,-2749,-2724,
-2695,-2663,-2627,-2588,-2547,-2502,-2454,-2403,-2349,-2292,-2233,-2170,-2106,-2038,-1968,-1896,
-1821,-1744,-1665,-1584,-1501,-1417,-1330,-1242,-1152,-1061,-969,-875,-781,-685,-589,-492,
-394,-296,-197,-98};


/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void GPIO_Init(void);
void TIM_Init(void);//定时器端口初始化
//更新逆变器1的PWM数据
void SPWM1_Refresh(uint8_t EN,uint16_t SPWMA,uint16_t SPWMB,uint16_t SPWMC);
//更新逆变器2的PWM数据
void SPWM2_Refresh(uint8_t EN,uint16_t SPWMA,uint16_t SPWMB,uint16_t SPWMC);
//控制函数
void control(void);

void dianyaxs(void) //电压显示
{ 	
    uint16_t temp;
	  temp=VIN/1.45;
	  OLED_ShowStr(0,4,"VIN:", 1);
	  OLED_ShowNum(24,4,temp/1000,1,1);
		OLED_ShowNum(30,4,temp%1000/100,1,1);//
		OLED_ShowChar(36,4,'.',1);//
		OLED_ShowNum(42,4,temp%10/10,1,1);//
		OLED_ShowNum(48,4,temp%10,1,1);//
	  OLED_ShowChar(54,4,'V',1);//
	
	
	  OLED_ShowStr(66,4,"UA1:", 1);
	  OLED_ShowNum(90,4,UA.DCvalue/10000,1,1);
		OLED_ShowNum(96,4,UA.DCvalue %10000/1000,1,1);//
		OLED_ShowChar(102,4,'.',1);//
		OLED_ShowNum(108,4,UA.DCvalue %1000/100,1,1);//
		OLED_ShowNum(114,4,UA.DCvalue %100/10,1,1);//
	  OLED_ShowChar(120,4,'V',1);//
	  
	  OLED_ShowStr(0,5,"UB1:", 1);
	 	OLED_ShowNum(24,5,UB.DCvalue/10000,1,1);//
		OLED_ShowNum(30,5,UB.DCvalue%10000/1000,1,1);//
		OLED_ShowChar(36,5,'.',1);//
		OLED_ShowNum(42,5,UB.DCvalue%1000/100,1,1);//
		OLED_ShowNum(48,5,UB.DCvalue%100/10,1,1);//
	  OLED_ShowChar(54,5,'V',1);//
		
		OLED_ShowStr(66,5,"UC1:", 1);
	  OLED_ShowNum(90,5,UC.DCvalue/10000,1,1);
		OLED_ShowNum(96,5,UC.DCvalue %10000/1000,1,1);//
		OLED_ShowChar(102,5,'.',1);//
		OLED_ShowNum(108,5,UC.DCvalue %1000/100,1,1);//
		OLED_ShowNum(114,5,UC.DCvalue %100/10,1,1);//
	  OLED_ShowChar(120,5,'V',1);//
}

void dianliuxs(void) //电流显示
{ 		
	  OLED_ShowStr(0,6,"IA1:", 1);
	  OLED_ShowNum(24,6,IA1.DCvalue/10000,1,1);
		OLED_ShowNum(30,6,IA1.DCvalue %10000/1000,1,1);//
		OLED_ShowChar(36,6,'.',1);//
		OLED_ShowNum(42,6,IA1.DCvalue %1000/100,1,1);//
		OLED_ShowNum(48,6,IA1.DCvalue %100/10,1,1);//
	  OLED_ShowChar(54,6,'A',1);//
	  
	  OLED_ShowStr(0,7,"IB1:", 1);
	 	OLED_ShowNum(24,7,IB1.DCvalue/10000,1,1);//
		OLED_ShowNum(30,7,IB1.DCvalue%10000/1000,1,1);//
		OLED_ShowChar(36,7,'.',1);//
		OLED_ShowNum(42,7,IB1.DCvalue%1000/100,1,1);//
		OLED_ShowNum(48,7,IB1.DCvalue%100/10,1,1);//
	  OLED_ShowChar(54,7,'A',1);//
		
		OLED_ShowStr(66,7,"IC1:", 1);
	  OLED_ShowNum(90,7,IC1.DCvalue/10000,1,1);
		OLED_ShowNum(96,7,IC1.DCvalue %10000/1000,1,1);//
		OLED_ShowChar(102,7,'.',1);//
		OLED_ShowNum(108,7,IC1.DCvalue %1000/100,1,1);//
		OLED_ShowNum(114,7,IC1.DCvalue %100/10,1,1);//
	  OLED_ShowChar(120,7,'A',1);//
}



/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_LPUART1_UART_Init();
  MX_ADC1_Init();
  MX_TIM4_Init();
  MX_USART1_UART_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
  GPIO_Init();
  TIM_Init();//定时器端口初始化
	OLED_Init();
	OLED_CLS();//清屏
	HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC_Value, 20);//20数据量
	HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED); // 校准ADC
  OLED_ShowStr(0, 0,"OLED_TEXT", 2);
	OLED_ShowStr(0, 2, "OLED_TEXT2", 2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
	   
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
	  char str[255];
	  dianyaxs(); //电压显示
		dianliuxs(); //电流显示
		
		//__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,1500);
		    // 点亮LED
		if(i>=7000)
		{
		 sprintf(str,"%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f,%1.2f, %1.2f\r\n", ((float)ADC_Value[0]*3.3F/4096.0F),((float)ADC_Value[1]*3.3F/4096.0F),
		 ((float)ADC_Value[2]*3.3F/4096.0F),((float)ADC_Value[3]*3.3F/4096.0F),((float)ADC_Value[4]*3.3F/4096.0F),((float)ADC_Value[5]*3.3F/4096.0F),
		 ((float)ADC_Value[6]*3.3F/4096.0F),((float)ADC_Value[7]*3.3F/4096.0F),((float)ADC_Value[8]*3.3F/4096.0F),((float)ADC_Value[9]*3.3F/4096.0F),
		 ((float)ADC_Value[10]*3.3F/4096.0F),((float)ADC_Value[11]*3.3F/4096.0F),((float)ADC_Value[12]*3.3F/4096.0F),((float)ADC_Value[13]*3.3F/4096.0F),
		 ((float)ADC_Value[14]*3.3F/4096.0F),((float)ADC_Value[15]*3.3F/4096.0F),((float)ADC_Value[16]*3.3F/4096.0F),((float)ADC_Value[17]*3.3F/4096.0F),
		 ((float)ADC_Value[18]*3.3F/4096.0F),((float)ADC_Value[19]*3.3F/4096.0F));
		 HAL_UART_Transmit(&hlpuart1, (uint8_t *)str, strlen(str) , 0xffff);
			i=0;
		}
		 

		 


		
		 
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enables the Clock Security System
  */
  HAL_RCC_EnableCSS();
}

/* USER CODE BEGIN 4 */
void TIM_Init(void)//定时器端口初始化
{
	// 清除定时器初始化过程中的更新中断标志,避免定时器一启动就中断
   __HAL_TIM_CLEAR_IT(&htim4, TIM_IT_UPDATE);		
// 使能定时器4更新中断并启动定时器
  HAL_TIM_Base_Start_IT(&htim4);
	
	// 使能定时器2更新中断并启动定时器
  HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
	// 使能定时器4更新中断并启动定时器
  HAL_TIM_Base_Start_IT(&htim3);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
	
}




//控制函数
void control(void)
{
	static uint16_t SPWMA1,SPWMB1,SPWMC1,SPWMA2,SPWMB2,SPWMC2;
	static double MD_A1,MD_B1,MD_C1,MD_A2,MD_B2,MD_C2;
	static float Upid_A,Upid_B,Upid_C;
	static float U_Ki = 0.000136,I_Kp = 0.0001,I_Ki = 0.000005;
	static short err_sum_A,err_sum_B,err_sum_C;
	static short sum_IA,sum_IB,sum_IC,IA2_target,IB2_target,IC2_target;
	static short rms_IA,rms_IB,rms_IC,rms_IA2_target,rms_IB2_target,rms_IC2_target;
	static short err_IA,err_IB,err_IC;
	static int err_IA_sum,err_IB_sum,err_IC_sum;
	static uint16_t u_target;

	
	//欠压保护
	if(VIN > 3000)
		ON_Flag = 1;
	else if(VIN < 1000)
		ON_Flag = 0;
	if(ON_Flag==1)//开启输出
	{
		//计算相位
		if(++PhaseC >= 180)  //C相的相位加法器
		{
			PhaseC = 0;
			SYNC_flag = 1;
		}
		PhaseB = PhaseC + 60 ;//计算B相相位
		PhaseA = PhaseC + 120;//计算C相相位
		if(PhaseB >= 180)//B相位限幅
			PhaseB -= 180;
		if(PhaseA >= 180)//C相位限幅
			PhaseA -= 180;
		
		//软启动
		if(u_target < USET)
			u_target ++;
		
		//计算开环调制深度
		MD_A1=MD_B1=MD_C1=MD_A2=MD_B2=MD_C2=(u_target*2.8284/VIN);
		
		
		//PID算法
		if(u_target == USET && 1 == PhaseC)
		{
			//计算误差积分
			err_sum_A += u_target - UA.rms;
			err_sum_B += u_target - UB.rms;
			err_sum_C += u_target - UC.rms;
			
			//误差积分限幅
			if(err_sum_A > 2000) err_sum_A = 2000;
			else if(err_sum_A < -2000) err_sum_A = -2000;
			if(err_sum_B > 2000) err_sum_B = 2000;
			else if(err_sum_B < -2000) err_sum_B = -2000;
			if(err_sum_C > 2000) err_sum_C = 2000;
			else if(err_sum_C < -2000) err_sum_C = -2000;
			
			//积分控制
			Upid_A = U_Ki * err_sum_A;
			Upid_B = U_Ki * err_sum_B;
			Upid_C = U_Ki * err_sum_C;
		}
		
		//计算稳压PID后的调制深度
		MD_A1 += Upid_A;
		MD_B1 += Upid_B;
		MD_C1 += Upid_C;
		MD_A2 += Upid_A;
		MD_B2 += Upid_B;
		MD_C2 += Upid_C;
//    MD_A1 += 0.5;
//		MD_B1 += 0.5;
//		MD_C1 += 0.5;
//		MD_A2 += 0.5;
//		MD_B2 += 0.5;
//		MD_C2 += 0.5;
		
/**************************

	以下是电流比例控制程序

***************************/
		
//		//计算总电流
//		sum_IA = IA1.ACvalue + IA2.ACvalue ;
//		sum_IB = IB1.ACvalue + IB2.ACvalue ;
//		sum_IC = IC1.ACvalue + IC2.ACvalue ;
//		rms_IA = IA1.rms + IA2.rms;
//		rms_IB = IB1.rms + IB2.rms;
//		rms_IC = IC1.rms + IC2.rms;


//		
//		//计算目标电流
//		IA2_target = sum_IA * 10 / (10 + Curr_bili);
//		IB2_target = sum_IB * 10 / (10 + Curr_bili);
//		IC2_target = sum_IC * 10 / (10 + Curr_bili);
//		rms_IA2_target = rms_IA * 10 / (10 + Curr_bili);
//		rms_IB2_target = rms_IB * 10 / (10 + Curr_bili);
//		rms_IC2_target = rms_IC * 10 / (10 + Curr_bili);
//		
//		//判断逆变器2的并联状态
//		if(Binglian_flag)
//		{
//			if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0) || (IA2.rms < 30 && IB2.rms < 30 && IC2.rms < 30)) //电流都小于30mA,判定并联断开
//				Binglian_flag = 0;
//		}
//		else
//		{
//			if((1 == HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)==0) && (IA2.rms > 200 || IB2.rms > 200 || IC2.rms > 200)) //电流都大于200mA,判定并联
//				Binglian_flag = 1;
//		}
//		
//		//逆变器并联且非空载状态
//		if(Binglian_flag && rms_IA > 200 && rms_IB > 200 && rms_IC > 200)
//		{
//			//均流工作,指示灯量
//			
//			//计算电流误差
//			err_IA = (PhaseA < 90)? IA2.ACvalue - IA2_target : IA2_target - IA2.ACvalue ;//实际输出电流和目标输出电流的差值
//			err_IB = (PhaseB < 90)? IB2.ACvalue - IB2_target : IB2_target - IB2.ACvalue ;
//			err_IC = (PhaseC < 90)? IC2.ACvalue - IC2_target : IC2_target - IC2.ACvalue ;
//			if(1 == PhaseC)
//			{
//				err_IA_sum += rms_IA2_target - IA2.rms;
//				err_IB_sum += rms_IB2_target - IB2.rms;
//				err_IC_sum += rms_IC2_target - IC2.rms;
//			
//				//积分限幅
//				if(err_IA_sum > 10000) err_IA_sum = 10000;
//				else if(err_IA_sum < -10000) err_IA_sum = -10000;
//				if(err_IB_sum > 10000) err_IB_sum = 10000;
//				else if(err_IB_sum < -10000) err_IB_sum = -10000;
//				if(err_IC_sum > 10000) err_IC_sum = 10000;
//				else if(err_IC_sum < -10000) err_IC_sum = -10000;
//			}
//				
//			//均流PI控制
//			MD_A2 += I_Kp * err_IA + err_IA_sum * I_Ki;
//			MD_B2 += I_Kp * err_IB + err_IB_sum * I_Ki;
//			MD_C2 += I_Kp * err_IC + err_IC_sum * I_Ki;
//			
//		}
//		else 
//		{
//			//逆变器2没并联或空载,不执行均流PID
//			err_IA_sum = err_IB_sum = err_IC_sum = 0;
//		}
		
		//调制深度限幅
		if(MD_A1 > 1)MD_A1 = 1;
		if(MD_A2 > 1)MD_A2 = 1;
		if(MD_B1 > 1)MD_B1 = 1;
		if(MD_B2 > 1)MD_B2 = 1;
		if(MD_C1 > 1)MD_C1 = 1;
		if(MD_C2 > 1)MD_C2 = 1;
		
		//计算逆变器的SPWM值
		SPWMA1 = 2834 + MD_A1*spwm[PhaseA];
		SPWMB1 = 2834 + MD_B1*spwm[PhaseB];
		SPWMC1 = 2834 + MD_C1*spwm[PhaseC];
		SPWMA2 = 2834 + MD_A2*spwm[PhaseA];
		SPWMB2 = 2834 + MD_B2*spwm[PhaseB];
		SPWMC2 = 2834 + MD_C2*spwm[PhaseC];
		
		//更新SPWM
		if(Binglian_flag)//逆变器处于并联状态
		{
			SPWM1_Refresh(1,SPWMA1,SPWMB1,SPWMC1);
			SPWM2_Refresh(1,SPWMA2,SPWMB2,SPWMC2);
		}
		else//逆变器没并联,关闭逆变器2
		{
			SPWM1_Refresh(1,SPWMA1,SPWMB1,SPWMC1);
			SPWM2_Refresh(0,0,0,0);
		}
		
	}
	else//关闭输出
	{
		u_target = err_sum_A = err_sum_B = err_sum_C = 0;
		SPWM1_Refresh(1,2834,2834,2834);
		SPWM2_Refresh(0,0,0,0);
	}
	
//	//按键调节输出电流比例
//	key_ctrl();
}

按键调节输出电流比例
//void key_ctrl(void)
//{
//	static u8 key;
//	key = KEY_Scan(1);//支持连按的按键扫描
//	if(1 == key)
//	{
//		if(Curr_bili > 5)//最小电流比为1:2
//			Curr_bili --;
//	}
//	else if(2 == key)
//	{
//		if(Curr_bili < 20)//最大电流比为2:1
//			Curr_bili ++;
//	}
//}

//更新逆变器1的PWM数据
void SPWM1_Refresh(uint8_t EN,uint16_t SPWMA,uint16_t SPWMB,uint16_t SPWMC)
{
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	
	 __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,SPWMA);
		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,SPWMB);
	  __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,SPWMC);
}
//更新逆变器2的PWM数据
void SPWM2_Refresh(uint8_t EN,uint16_t SPWMA,uint16_t SPWMB,uint16_t SPWMC)
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
    __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,SPWMA);
		__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_3,SPWMB);
	   __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_4,SPWMC);
		 
}

void GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  // 打开GPIOB时钟
  __HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();

  // 配置GPIOB引脚为通用推挽输出
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pin = GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim4.Instance) 
	{	 
		  
	  	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
			 control();
		   get_value();
		
		  
		//书写我们想要执行的功能
	}
	
	if(htim->Instance == htim2.Instance) 
	{	 
		  i++;
		 
		//书写我们想要执行的功能
	}
	
	

}



/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

上面的代码是部分代码,还没有用到PID算法,​只是开环的测试。

五、效果测试

图7:输入电压图

图8:输出电压和波形图

图9:输出电压和波形图

六、总结

从测试结果可以看出输出电压24V,峰峰值67.7V,频率50Hz,输出的正弦波也很完美​!

本文已同步发表在微信公众号:基于STM32G474RET6微电网模拟系统功率电路设计 (qq.com)

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值