This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

3 phase sine wave using stm32f030r8t6 MCU

Hi all,

i am trying to generate 3 phase sine with 120degree phase shift by using STM32F030R8T6 MCU. i have its nucleo board Nucleo-F030R8

My code generates 3phase sine wave which i can see on CRO but the freq varies from 50 hz to 200 hz . freq is not stable.

please help me to figure out where i am doing wrong.

Here is the code which i have written

this is code of main.c file

///////////////////////////////////////////////////////////////////////////////////////////////////////////// 

#include "stm32f0xx.h"

#include "stm32f030x8.h"

#include "math.h"

 

void GPIO_Init(void);

void EXTI_Init(void);

void TIM1_Init(void);

void TIM1I_Init(void);

void UpdatePulse(void);

 

unsigned int i,i1=0,i2=0,i3=0,count,Ch1_DutyCycle=0,Ch2_DutyCycle=0,Ch3_DutyCycle=0,Ch1_Dir=0,Ch2_Dir=0,Ch3_Dir=0,Max_Duty=0,Start_Duty=0,Duty_Diff=0,Period=0;

unsigned int SinTable[100],SineFreq=0;

double x=0;

int main()

{

/****start PLL setting for system clock at 48Mhz using 8Mhz HSI****/

RCC->CFGR |= ((1<<19)|(1<<21)); // PLL Multification factor = 12

RCC->CFGR |= (1<<1); // PLL selected as system clock

RCC->CR |= (1<<24); // Enable / ON PLL

while((RCC->CR & (1<<25)) == 0); // Wait until PLL gets Ready

/****PLL settigs end here****/

 

Period = 1199; // 40khz i.e. 20 khz in center aligned mode

Max_Duty = 1080; // 90%

Start_Duty = 600; // 50%

Duty_Diff = (Max_Duty-Start_Duty);

// Generating sine table , here x is angle

x=0;

for(i=0;i<=24;i++)

{

x=x+0.062832;

SinTable[i] = Start_Duty+(Duty_Diff*(sin(x)));

}

for(i=25;i<=49;i++)

{

x=x+0.062832;

SinTable[i] = Start_Duty+(Duty_Diff*(sin(x)));

}

for(i=50;i<=74;i++)

{

x=x+0.062832;

SinTable[i] = Start_Duty+(Duty_Diff*(sin(x)));

}

for(i=75;i<=99;i++)

{

x=x+0.062832;

SinTable[i] = Start_Duty+(Duty_Diff*(sin(x)));

}

// maintaining 120 deg phase shift between 3 sine waves.

i1 = 33; // 120 degree W

i2 = 66; // 240 degree V

i3 = 99; // 0/360 degree U

GPIO_Init(); // gpio initialization

TIM1_Init(); // timer1 initialization

TIM1I_Init(); // timer 1 interrupt initialization

while(1) // infinite loop

{

}

}

 

void GPIO_Init()

{

RCC->AHBENR |= (1<<17); // Enable clock for GPIOA

RCC->AHBENR |= (1<<18); // Enable clock for GPIOB

GPIOA->MODER |= (1<<17); // PA8 in alternate function mode TIM1_CH1

GPIOA->OTYPER &= ~(1<<8); // PA8 as output push pull

GPIOA->OSPEEDR |= ((1<<16)|(1<<17)); // PA8 at high speed

GPIOA->PUPDR &= ~((1<<16)|(1<<17)); // PA8 no pull-up, no pull-down

GPIOA->AFR[1] |= (1<<1); // PA8 as TIM1_CH1 alternate function

GPIOA->MODER |= (1<<19); // PA9 in alternate function mode TIM1_CH2

GPIOA->OTYPER &= ~(1<<9); // PA9 as output push pull

GPIOA->OSPEEDR |= ((1<<18)|(1<<19)); // PA9 at high speed

GPIOA->PUPDR &= ~((1<<18)|(1<<19)); // PA9 no pull-up, no pull-down

GPIOA->AFR[1] |= (1<<5); // PA9 as TIM1_CH1 alternate function

GPIOA->MODER |= (1<<21); // PA10 in alternate function mode TIM1_CH3

GPIOA->OTYPER &= ~(1<<10); // PA10 as output push pull

GPIOA->OSPEEDR |= ((1<<20)|(1<<21)); // PA10 at high speed

GPIOA->PUPDR &= ~((1<<20)|(1<<21)); // PA10 no pull-up, no pull-down

GPIOA->AFR[1] |= (1<<9); // PA10 as TIM1_CH1 alternate function

GPIOA->MODER |= (1<<15); // PA7 in alternate function mode TIM1_CH1N

GPIOA->OTYPER &= ~(1<<7); // PA7 as output push pull

GPIOA->OSPEEDR |= ((1<<14)|(1<<15)); // PA7 at high speed

GPIOA->PUPDR &= ~((1<<14)|(1<<15)); // PA7 no pull-up, no pull-down

GPIOA->AFR[0] |= (1<<29); // PA7 as TIM1_CH1 alternate function

GPIOB->MODER |= (1<<1); // PB0 in alternate function mode TIM1_CH2N

GPIOB->OTYPER &= ~(1<<0); // PB0 as output push pull

GPIOB->OSPEEDR |= ((1<<0)|(1<<1)); // PB0 at high speed

GPIOB->PUPDR &= ~((1<<0)|(1<<1)); // PB0 no pull-up, no pull-down

GPIOB->AFR[0] |= (1<<1); // PB0 as TIM1_CH1 alternate function

GPIOB->MODER |= (1<<3); // PB1 in alternate function mode TIM1_CH3N

GPIOB->OTYPER &= ~(1<<1); // PB1 as output push pull

GPIOB->OSPEEDR |= ((1<<2)|(1<<3)); // PB1 at high speed

GPIOB->PUPDR &= ~((1<<2)|(1<<3)); // PB1 no pull-up, no pull-down

GPIOB->AFR[0] |= (1<<5); // PB1 as TIM1_CH1 alternate function

}

 

void TIM1_Init()

{

RCC->APB2ENR |= (1<<11); // Enable clock for TIM1

TIM1->PSC = 0;

TIM1->ARR = Period; // period

TIM1->CR1 |= ((1<<5)); // Center-aligned mode 1.

TIM1->CR1 |= ((1<<2)); // Only counter overflow/underflow generates an update interrupt

TIM1->DIER = 1; // Update interrupt enable

TIM1->RCR = 5; // update event after RCR+1 period

TIM1->CCMR1 |= ((1<<4)|(1<<5)|(1<<6)|(1<<3)); // TIM1_CH1 is set to pwm mode-2

TIM1->CCMR1 |= ((1<<12)|(1<<13)|(1<<14)|(1<<11)); // TIM1_CH2 is set to pwm mode-2

TIM1->CCMR2 |= ((1<<4)|(1<<5)|(1<<6)|(1<<3)); // TIM1_CH3 is set to pwm mode-2

Ch1_DutyCycle = SinTable[i1]; // 120 degree W @ start

Ch2_DutyCycle = SinTable[i2]; // 240 degree V @ start

Ch3_DutyCycle = SinTable[i3]; // 0/360 degree U @ start

TIM1->CCR1 = Ch1_DutyCycle; // Ch1 duty cycle

TIM1->CCR2 = Ch2_DutyCycle; // Ch2 duty cycle

TIM1->CCR3 = Ch3_DutyCycle; // Ch3 duty cycle

TIM1->CCER |= ((1<<0)|(1<<2)); // TIM1_CH1, TIM1_CH1N is Active, active high 

TIM1->CCER |= ((1<<4)|(1<<6)); // TIM1_CH2, TIM1_CH2N is Active, active high 

TIM1->CCER |= ((1<<8)|(1<<10)); // TIM1_CH3, TIM1_CH3N is Active, active high 

TIM1->BDTR |= (1<<15); // main output enable

TIM1->BDTR |= (1<<14); // automatic output enable

TIM1->BDTR |= ((1<<5)|(1<<4)|(1<<3)); // dead time

TIM1->EGR = 1; // Reinitialize the counter and generates an update of the registers

TIM1->CR1 |= 1; // TIM1 Counter enable

}

 

void TIM1I_Init()

{

 // interrupt enabling settings

__NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0);

__NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);

}

 

void ISR()

{

UpdatePulse();

TIM1->SR = 0; // clear update interrupt flag

}

void UpdatePulse()

{

i1++;

if(i1>99)

{

i1=0;

}

Ch1_DutyCycle = SinTable[i1];

i2++;

if(i2>99)

{

i2=0;

}

Ch2_DutyCycle = SinTable[i2];

i3++;

if(i3>99)

{

i3=0;

}

Ch3_DutyCycle = SinTable[i3];

TIM1->CCR1 = Ch1_DutyCycle; // duty cycle

TIM1->CCR2 = Ch2_DutyCycle; // duty cycle

TIM1->CCR3 = Ch3_DutyCycle; // duty cycle

}

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

 

// this is code of it.c file

 

void ISR(void);

 

void TIM1_BRK_UP_TRG_COM_IRQHandler(void)

{

ISR();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Parents Reply Children
No data