cancel
Showing results for 
Search instead for 
Did you mean: 

Space Vector Modulation Request for assistance regarding

Sözde.11
Associate II

First of all, thank you all in advance, I am trying to control IKCM15L60GA IPM with Stm32f429.

I have added the circuit diagram below, my problem is that when I start the 250 W asynchronous motor drive process that I connected to the IPM output, it vibrates and remains fixed as if it is braked, it does not turn.

I will add the logic analyzer samples and other details as a file.
PLEASE HELP.

3 REPLIES 3
Sözde.11
Associate II
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <math.h>

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */

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

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TIMER_PERIOD 35999 // 5 kHz PWM için
#define SQRT3 1.73205080757
/* USER CODE END PD */

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

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;

/* USER CODE BEGIN PV */
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */
void SVM_Update(float Vd, float Vq);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void SVM_Update(float Vd, float Vq)
{
float T1, T2, T0;
float Va, Vb, Vc;
float sector;

// Üç faz referans gerilimlerini hesapla
Va = Vd;
Vb = -0.5 * Vd + SQRT3 / 2 * Vq;
Vc = -0.5 * Vd - SQRT3 / 2 * Vq;

// Sektör belirleme
if (Va >= 0 && Vb >= 0)
sector = 1;
else if (Vb >= 0 && Vc >= 0)
sector = 2;
else if (Vc >= 0 && Va >= 0)
sector = 3;
else if (Va < 0 && Vb < 0)
sector = 4;
else if (Vb < 0 && Vc < 0)
sector = 5;
else
sector = 6;

// Aktif ve sıfır vektör sürelerini hesapla
T1 = TIMER_PERIOD * fabs(sin(sector * M_PI / 3));
T2 = TIMER_PERIOD * fabs(sin((1.0 / 3.0 - sector) * M_PI));
T0 = TIMER_PERIOD - (T1 + T2);

// CCR değerlerini hesapla
uint32_t CCR1 = (uint32_t)((T0 / 2.0 + T1) / TIMER_PERIOD * TIMER_PERIOD);
uint32_t CCR2 = (uint32_t)((T0 / 2.0 + T2) / TIMER_PERIOD * TIMER_PERIOD);
uint32_t CCR3 = (uint32_t)((T0 / 2.0) / TIMER_PERIOD * TIMER_PERIOD);

// Timer 1 PWM kanallarını güncelle
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, CCR1);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, CCR2);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, CCR3);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM1)
{
static float angle = 0.0;
float Vd = 0.8 * cos(angle);
float Vq = 0.8 * sin(angle);
angle += (2 * M_PI * 40 / 5000); // 50 Hz motor frekansı, 5 kHz taşıyıcı frekansı
if (angle > 2 * M_PI)
angle -= 2 * M_PI;

SVM_Update(Vd, Vq);
}
}
/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();

// PWM çıkışlarını başlat
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

// Timer interrupt başlat
HAL_TIM_Base_Start_IT(&htim1);

while (1)
{
// Ana döngü kullanılmıyor, tüm işlemler kesmelerle yapılır
}
}

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

__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

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 = 4;
RCC_OscInitStruct.PLL.PLLN = 180;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Error_Handler();

if (HAL_PWREx_EnableOverDrive() != HAL_OK)
Error_Handler();

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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
Error_Handler();
}

/**
* @brief TIM1 Initialization Function
* @retval None
*/
static void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = TIMER_PERIOD;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;

HAL_TIM_Base_Init(&htim1);

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);
HAL_TIM_PWM_Init(&htim1);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 5;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);

HAL_TIM_MspPostInit(&htim1);
}

/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
}

/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}  

Hello @Sözde.11 ,

In next time please use </> button to paste your code: https://community.st.com/t5/community-guidelines/how-to-insert-source-code/ta-p/693413

I've edited your post to be inline with the community rules.

Thank you.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hi, I didn't know it was like this, thank you for your help.