We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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++)
for(i=50;i<=74;i++)
for(i=75;i<=99;i++)
// 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();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Clive Unspecified