cancel
Showing results for 
Search instead for 
Did you mean: 

Quadratic Output using Output Compare

stuk
Associate II
Posted on February 01, 2016 at 11:16

Hi, i'm trying to use timer2 to generate two output shifted by 90 degree, like an encoder emulator. The idea is using the period of the timer2 to set the frequency, and set two output compare ch2,ch3 to set the output.

This is the code i'm using to set the timers:


static
int
numPackets;

static
int
currentPackets;


void
setQuadraticOutputConfig(
long
frequency,
long
_numPackets,
long
direction)

{

numPackets = (_numPackets*2)-1;

currentPackets = 0;

double
tmp = 0;


unsigned 
long
period = (TIMER_FREQ/(frequency*2)-1);

unsigned 
long
pulseA = period/4;

unsigned 
long
pulseB = pulseA*3;


TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;


htim2.Instance = TIM2;

htim2.Init.Prescaler = 0;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = period;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;


HAL_TIM_Base_DeInit(&htim2);

HAL_TIM_Base_Init(&htim2);


sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

HAL_TIM_OC_Init(&htim2);


sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);


sConfigOC.OCMode = TIM_OCMODE_TOGGLE;

if
(direction)

sConfigOC.Pulse = pulseA;

else

sConfigOC.Pulse = pulseB;

sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;

sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;


HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

if
(direction)

sConfigOC.Pulse = pulseB;

else

sConfigOC.Pulse = pulseA;

HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3);


TIM2->CNT = 0; 
//Force timer2 to 0

HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_2);

HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3);


HAL_TIM_Base_Start_IT(&htim2);

}

And this the interrupt:


void
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if
(htim == &htim2){

if
(currentPackets == numPackets)

{

HAL_TIM_OC_Stop(&htim2, TIM_CHANNEL_2);

HAL_TIM_OC_Stop(&htim2, TIM_CHANNEL_3);

HAL_TIM_Base_Stop(&htim2);

}

currentPackets++;

}

}

Sometimes the first output is smaller then the others: 0690X00000605L8QAI.png Or the last: 0690X00000605L4QAI.png Why? Any idea? Thanks Stuk #!stm32 #!timer #!outputcompare
4 REPLIES 4
Posted on February 01, 2016 at 12:41

Please, don't reply by opening the reply link into a new window/tab, because the broken forum software creates a new sub-thread which contains un-openable contributions and also does not update this thread's timestamp/position in the main list.

Also, in this particular thread, please don't reply to the above two posts which are members of the sub-thread, reply to this post or the original one.

JW
stuk
Associate II
Posted on February 01, 2016 at 13:46

ok

mark239955_stm1
Associate II
Posted on February 02, 2016 at 07:02

@stuk

If you need to use the TIM2 interrupt, set the URS flag in CR1 instead of the UDIS flag.  Then you will get IRQ's on counter rollover/under, but you won't get an IRQ when you reset the counter with the UG flag.

Walid FTITI_O
Senior II