cancel
Showing results for 
Search instead for 
Did you mean: 

Timer OC problem

l239955_stm1
Associate II
Posted on April 19, 2016 at 15:18

Hi,

I´m using TIM3(output compare mode) in stm32f072 to generate waveform via GPIO. My function principle is:

- timer initializing

- timer is still running, only is enabled TIM_IT_CC3 a output TIM_CCER_CC3E (BUS_Set_Tx)

- when is CNT equal CCR3, pin is toggled and I set register CCR3 to next pulse lenght

- when is message sended, TIM_IT_CC3 and TIM_CCER_CC3E ale disabled (BUS_Stop_Tx)

Message is sended correctly but sometimes is output pin toggled immediately after enabling TIM_CCER_CC3E in function BUS_Set_Tx (

pin state is toggled though CNT < CCR3 and interrupt is not called). Next time pin isnt´t already toggled.

Timer is running, register CCR3 is correctly setable, interrupt is generated correctly but output pin is not toggled.

The problem occurs randomly. All timer registers are equal in the wrong and correct state.

Please where is problem?

1) timer initialization

void TimerInit() {

    //.......

    GPIO_InitStruct.Pin   = GPIO_PIN_0;

    GPIO_InitStruct.Mode  = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Alternate = GPIOB;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __TIM3_CLK_ENABLE();

    TimHand.Instance          = TIM3;

    TimHand.Init.Period        = 65535;      

    TimHand.Init.Prescaler     = 0;

    TimHand.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    TimHand.Init.CounterMode   = TIM_COUNTERMODE_UP;

    TimHand.Init.RepetitionCounter = 0;

    TimHand.Channel               = HAL_TIM_ACTIVE_CHANNEL_3;

    TimHand.Lock               = HAL_UNLOCKED;

    TimHand.State               = HAL_TIM_STATE_READY;

    HAL_TIM_Base_Init(&TimHand);

    HAL_TIM_OC_Init(&TimHand);

    __HAL_TIM_SET_COUNTER(&TimHand, 0);      

    __HAL_TIM_CLEAR_IT(&TimHand, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_UPDATE);

    sConfig.OCMode     = TIM_OCMODE_TOGGLE;

    sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;

    sConfig.Pulse = 480;   

    HAL_TIM_OC_ConfigChannel(&TimHand, &sConfig, TIM_CHANNEL_3);

    HAL_TIM_OC_Start_IT(&TimHand, TIM_CHANNEL_3);

    &TimHand.Instance->CCER &= ~TIM_CCER_CC3E; disable   //  ''Capture/Compare 3 output enable''

    __HAL_TIM_DISABLE_IT(&TimHand, TIM_IT_UPDATE | TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4);

    __HAL_TIM_CLEAR_IT(&TimHand, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_UPDATE);

    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);

    HAL_NVIC_EnableIRQ(TIM3_IRQn);

}

2) start Tx function

void BUS_Set_Tx(uint32_t messLen_) {

    __HAL_TIM_CLEAR_IT(&TimHand, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_UPDATE);

    __HAL_TIM_SET_COUNTER(&TimHand, 0);

    __HAL_TIM_ENABLE_IT(&TimHand, TIM_IT_CC3);  

    &TimHand.Instance->CCR3 = 480;

    &TimHand.Instance->CCER |= TIM_CCER_CC3E;   // enable ''Capture/Compare 3 output enable''

}

3) stop Tx function

void BUS_Stop_Tx() {

    __HAL_TIM_DISABLE_IT(&TimHand, TIM_IT_CC3);

    __HAL_TIM_CLEAR_IT(&TimHand, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_UPDATE);

    &TimHand.Instance->CCER &= ~TIM_CCER_CC3E;        // disable ''Capture/Compare 3 output enable''

}

9 REPLIES 9
l239955_stm1
Associate II
Posted on April 25, 2016 at 14:24

nobody knows?

Walid FTITI_O
Senior II
Posted on April 25, 2016 at 14:48

Hi paroulek.lukas,

>''Message is sended correctly but sometimes is output pin toggled immediately after enabling TIM_CCER_CC3E in function BUS_Set_Tx (

pin state is toggled though CNT < CCR3 and interrupt is not called). Next time pin isnt´t already toggled.

Timer is running, register CCR3 is correctly setable, interrupt is generated correctly but output pin is not toggled.''

Your description here of the problem is not clear. What is the result that you expect ? what is the problem that you see (pin not toggling or interupt not occured or both ) ? and when it occurs (did you try to debug .. it is always happening or in specific conditions) ?

-Hannibal-

l239955_stm1
Associate II
Posted on April 28, 2016 at 08:47

Hi Hannibal,

what I expect: Receiver and transmitter to the own bus. Receiver check input data message (IC mode, it´s OK) and transmitter corresponds (OC mode).

what is the problem: interrupt is called but pin not toggling

problem conditions: I tried to debug, the problem occurs randomly. All timer registers are equal in the correct state and state when pin not toggling. Sometimes transmitter corresponds OK but sometimes not.

Best regards

L.Paroulek

Posted on April 28, 2016 at 15:14

Try

void BUS_Set_Tx(uint32_t messLen_) {

    __HAL_TIM_CLEAR_IT(&TimHand, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_UPDATE);

    __HAL_TIM_SET_COUNTER(&TimHand, 0);

 

    &TimHand.Instance->CCR3 = 480;

  __HAL_TIM_ENABLE_IT(&TimHand, TIM_IT_CC3);  

  &TimHand.Instance->CCER |= TIM_CCER_CC3E;   // enable ''Capture/Compare 3 output enable''

}

JW
l239955_stm1
Associate II
Posted on April 28, 2016 at 15:28

This solution still does not work. :(

Walid FTITI_O
Senior II
Posted on April 28, 2016 at 19:29

Hi 

paroulek.lukas, 

Remove the following line :

 TimHand.State  = HAL_TIM_STATE_READY;

you should keep all instances in their default RESET state. 

Otherwise in your case, code will not configure the IO  by HAL_TIM_OC_MspInit()

which is executed only if the state = HAL_TIM_STATE_RESET  ( see inside HAL_TIM_OC_Init() function)

-Hannibal-
l239955_stm1
Associate II
Posted on April 28, 2016 at 20:29

Thanks for your answer but I´m not using week function 

HAL_TIM_OC_MspInit()

Posted on April 29, 2016 at 16:00

I don't quite understand your problem, but maybe you just misinterpret what you are seing:

&TimHand.Instance->CCER &= ~TIM_CCER_CC3E;        // disable ''Capture/Compare 3 output enable''

this does NOT stop the compare, so the OCxREF (the internal signal just before the output stage of the timer module) continues to toggle. Clearing TIMx_CCER.CCxE disconnects OCxREF from the pin and causes the pin to go to high-Z, so its state depends either on internal pullup/down (if switched on), any external pullup/down; or if pull, the parasitic capacitances may ''hold'' the last logic state for a short period. When you set TIMx_CCER.CCxE, the current state of OCxREF is driven out, and it may be different than what the ''hold'' state of the pin was - of course without throwing an interrupt.

This does not explain why would there be later an interrupt without toggle, but then maybe we don't see enough of your program.

Try, instead of clearing/setting TIMx_CCER.CCxE, stop/start the counter by clearing/setting TIMx_SR1.CEN.

Also, as you write to CNT and CCRx, make sure you don't have shadowing of either of them switched on, as that might cause surprising results too.

JW

PS. You can try to discuss this problem also on a local mailing list, list.hw.cz

Walid FTITI_O
Senior II
Posted on April 29, 2016 at 18:38

Hiparoulek.lukas,

Correct the pin configuration (wrong alternate ) replace

GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIOB;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

by

GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

-Hannibal-