cancel
Showing results for 
Search instead for 
Did you mean: 

TIM1 CCR3 Register Problem? STM32F429

lk1991
Associate II
Posted on February 06, 2015 at 17:29

Can someone explain why the following code causes CCR1, CCR2 and CCR3 to have the same value:

TIM1->CCR1=value1;

TIM1->CCR2=value2;

TIM1->CCR3=value3;

While the following code doesn't cause this problem (CCR1 and CCR2 different values):

TIM1->CCR1=value1;

TIM1->CCR2=value2;
9 REPLIES 9
Posted on February 06, 2015 at 17:41

Let me guess: value1, value2 and value3 in the first instance are uninitialized local variables?

JW
Posted on February 06, 2015 at 17:53

Preloaded or Immediate?

Post some actual code that demonstrates your issue.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lk1991
Associate II
Posted on February 06, 2015 at 18:12

If I comment lineTIM1->CCR3=val2;, the channels 1 and 2 work properly.If not commented, the three output waves will have the same duty cycle(varying sinusoidaly of course).    void

TIM1_CC_IRQHandler(

void

)

{

int

val;

// integer values, because counter is not double

int

val1;

int

val2;

double

inbtw;

// double values, used for calculations with sine wave

double

inbtw1;

double

inbtw2;

cx++;

// Refresh counter

if

(cx>1799)

//If reached maximum then reset

{

cx=1;

}

if

(parameter==1)

//If direct phase sequence

{

inbtw=scalefactor*sin(2*3.1416*freqfactor*(

double

)cx/1799);

// Calculate value of sinus wave

val=(

int

)((inbtw*1799)/2+1799/2);

// Shift value (only positive values are accepted) and convert to int

//same for other phases

inbtw1=scalefactor*sin(2*3.1416*freqfactor*((

double

)cx/1799+2/3*3.1416));

val1=(

int

)((inbtw1*1799)/2+1799/2);

// note +120 and -120phase shift

inbtw2=scalefactor*sin((2*3.1416*freqfactor*(

double

)cx/1799)-2/3*3.1416);

val2=(

int

)((inbtw2*1799)/2+1799/2);

}

if

(parameter==2)

// If indirect phase sequence

{

inbtw=scalefactor*sin(2*3.1416*freqfactor*(

double

)cx/1799);

val=(

int

)((inbtw*1799)/2+1799/2);

inbtw1=scalefactor*sin(2*3.1416*freqfactor*(

double

)cx/1799-2/3*3.1416);

val1=(

int

)((inbtw1*1799)/2+1799/2);

inbtw2=scalefactor*sin(2*3.1416*freqfactor*(

double

)cx/1799+2/3*3.1416);

val2=(

int

)((inbtw2*1799)/2+1799/2);

}

if

(val<1)

{

val=1;

}

if

(val1<1)

{

val1=1;

}

if

(val2<1)

{

val2=1;

}

TIM1->CCR1=val;

TIM1->CCR2=val1;

TIM1->CCR3=val2;

// IRQ handling

HAL_NVIC_ClearPendingIRQ(TIM1_CC_IRQn);

//reset pending flag

HAL_TIM_IRQHandler(&htim1);

//continue

}

lk1991
Associate II
Posted on February 06, 2015 at 18:13

/* TIM1 init function */
void
MX_TIM1_Init(
void
)
{
TIM_OC_InitTypeDef sConfigOC;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim1.Instance = TIM1;
htim1.Init.Prescaler = (uint32_t) (SystemCoreClock / 18000000) - 1;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = 1799;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&htim1);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 450;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_SET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_SET;
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_ENABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
sBreakDeadTimeConfig.DeadTime = 255;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
if
(HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Start channel 1 */
if
(HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 1N */
if
(HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 2 */
if
(HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 2N */
if
(HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 3 */
if
(HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/* Start channel 3N */
if
(HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
}

Posted on February 06, 2015 at 19:39

I don't understand how could it lead to described symptoms, but you are attempting some very heavy math (double is calculated entirely in software), which might in case of 3 channels lead to ISR taking longer than the reload period.

JW

Posted on February 06, 2015 at 20:48

inbtw1=scalefactor*sin(2*3.1416*freqfactor*((
double
)cx/1799+2/3*3.1416));
inbtw2=scalefactor*sin((2*3.1416*freqfactor*(
double
)cx/1799)-2/3*3.1416);

Review your brackets
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lk1991
Associate II
Posted on February 06, 2015 at 21:00

Thanks for the suggestions, I'll try and post results after.

Posted on February 06, 2015 at 21:14

I'm not 100% convinced on the math here as it relates to the scalefactor, and inbtw, but this looks to be doable with float, and not doubles.

void TIM1_CC_IRQHandler(void)
{
const float pi2ff = 2.0f * 3.141592f * (float)freqfactor;
const float phase120 = 2.0f / 3.0f * 3.141592f;
const float recip1799 = 1.0f / 170f;
float alpha;
int val1 = 1; // integer values, because counter is not float
int val2 = 1;
int val3 = 1;
float inbtw1; // float values, used for calculations with sine wave
float inbtw2;
float inbtw3;
cx++; // Refresh counter
// honestly 0..1799 relates to 1800 steps
if (cx>1799) //If reached maximum then reset
{
cx = 1;
}
alpha = pi2ff * (float)cx * recip1799;
if (parameter == 1) //If direct phase sequence
{
inbtw1=scalefactor*sinf(alpha); // Calculate value of sinus wave
val1=(int)((inbtw1 + 1.0)*170f * 0.5f); // Shift value (only positive values are accepted) and convert to int
//same for other phases
inbtw2=scalefactor*sinf(alpha + phase120);
val2=(int)((inbtw2 + 1.0)*170f * 0.5f);
// note +120 and -120phase shift
inbtw3=scalefactor*sinf(alpha - phase120);
val3=(int)((inbtw3 + 1.0)*170f * 0.5f);
}
else if (parameter==2)// If indirect phase sequence
{
inbtw1=scalefactor*sinf(alpha);
val1=(int)((inbtw1 + 1.0)*170f * 0.5f);
inbtw2=scalefactor*sinf(alpha - phase120);
val2=(int)((inbtw2 + 1.0)*170f * 0.5f);
inbtw3=scalefactor*sinf(alpha + phase120);
val3=(int)((inbtw3 + 1.0)*170f * 0.5f);
}
if (val1 < 
1
)
val1
=1;
if (val2 < 1)
val2
=
1
;
if (val3 < 1)
val3
=
1
;
TIM1->CCR1=val1;
TIM1->CCR2=val2;
TIM1->CCR3=val3;
// IRQ handling
HAL_NVIC_ClearPendingIRQ(TIM1_CC_IRQn); //reset pending flag
HAL_TIM_IRQHandler(&htim1); //continue
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lk1991
Associate II
Posted on February 10, 2015 at 10:25

I have tested it today in the lab and it worked properly. Thanks again!