cancel
Showing results for 
Search instead for 
Did you mean: 

TIM's feature out compare have some problem

Jerry Yung
Associate III

Hello, I try to do with out compare,

I use TIM out-compare feature and set TIM_IT_UPDATE interrupt,

if go into TIM's update interrupt ,clear TIM's all register content , I config TIM second , of course ,same procedure, I config third TIM .

second and third config are different from first config just TIM'period and pulse ,other is same.

then enable TIM , I can see via scope ,only first OC singal waveform ,second and third waveform is none,.

here I confirm something :

1.TIM go into update interrupt total three times

2.TIM'register content only diff just period and pulse

of course , I don't modfiy second config , I only enable TIM, I can see singal waveform via scope ,

also , I enable third config, I also see correlate singal waveform via scope ,

So ,I don't know why three times one by one config ,just only see the first config correlate waveform .

---------------------------------------------- code ------------------------------------------------------------------------

TIM config function ( name Gate_Driver )

void TIM16_Gate_Driver_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin         = HVC_GATE_DRIVER_PIN;

GPIO_InitStruct.Mode         = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull         = GPIO_PULLDOWN;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

GPIO_InitStruct.Alternate = GPIO_AF4_TIM16;

HAL_GPIO_Init(HVC_GPIO_PORT_E, &GPIO_InitStruct);

   GPIO_InitStruct.Pin           = TIM16_BRK_IN_PIN;

   GPIO_InitStruct.Alternate        = GPIO_AF1_TIM16;

   HAL_GPIO_Init(TIM16_BRK_IN_PORT, &GPIO_InitStruct);

GATE_DRIVER_TIM_CLK_ENABLE();

// 暂时使用内部晶振

tim16_gate_driver.Instance = GATE_DRIVER_TIM;

tim16_gate_driver.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 

tim16_gate_driver.Init.Prescaler = GATE_DRIVER_TIM_PRESCALER - 1; // 1us

tim16_gate_driver.Init.CounterMode = TIM_COUNTERMODE_UP;

tim16_gate_driver.Init.Period = GATE_DRIVER_TIM_PERIOD - 1;

tim16_gate_driver.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

tim16_gate_driver.Init.RepetitionCounter = 0;

HAL_TIM_OC_Init(&tim16_gate_driver);

tim16_sConfigOC.OCMode = TIM_OCMODE_ACTIVE;

tim16_sConfigOC.Pulse = 0 ;

tim16_sConfigOC.OCPolarity  = TIM_OCPOLARITY_LOW;

tim16_sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; 

HAL_TIM_OC_ConfigChannel(&tim16_gate_driver, &tim16_sConfigOC,TIM_CHANNEL_1);

 tim16_sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;

 tim16_sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;

 tim16_sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

 tim16_sBreakDeadTimeConfig.DeadTime = 0;

 tim16_sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;

 tim16_sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

 tim16_sBreakDeadTimeConfig.BreakFilter = 0;

 tim16_sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;

 HAL_TIMEx_ConfigBreakDeadTime(&tim16_gate_driver, &tim16_sBreakDeadTimeConfig);

Disable_Gate_Driver();

HAL_NVIC_SetPriority(GATE_DRIVER_TIM_CC_IRQ, 2, 0);

HAL_NVIC_EnableIRQ(GATE_DRIVER_TIM_CC_IRQ);

}

void Enable_Gate_Driver_Keep( UINT16 br_on_time , UINT16 br_off_time )

{

UINT16 br_total_time = 0;

br_total_time = br_on_time + br_off_time;

if ( br_total_time >= 0xFFFF )

{

br_total_time = 0xFFFF;

}

GATE_DRIVER_TIM_CLK_DISABLE();// 能清空定时器所有的寄存器数�?�

GATE_DRIVER_TIM_CLK_ENABLE();

// 暂时使用内部晶振

tim16_gate_driver.Init.Period = br_total_time - 1;

HAL_TIM_OC_Init(&tim16_gate_driver);

tim16_sConfigOC.Pulse     = br_on_time ;

HAL_TIM_OC_ConfigChannel(&tim16_gate_driver, &tim16_sConfigOC, TIM_CHANNEL_1);

// �?新开�?�

TIM_CCxChannelCmd(tim16_gate_driver.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);

__HAL_TIM_CLEAR_FLAG(&tim16_gate_driver, TIM_FLAG_UPDATE);

__HAL_TIM_ENABLE_IT(&tim16_gate_driver, TIM_IT_UPDATE);

__HAL_TIM_MOE_ENABLE(&tim16_gate_driver);

   __HAL_TIM_ENABLE(&tim16_gate_driver);

}

void Disable_Gate_Driver( void )

{

TIM_CCxChannelCmd(tim16_gate_driver.Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);

// 先 Disable 互补输出, �?�?�关闭定时器

__HAL_TIM_DISABLE(&tim16_gate_driver);

// 先关闭定时器�?�?�清除 Flag 

__HAL_TIM_CLEAR_FLAG(&tim16_gate_driver, TIM_FLAG_UPDATE);

  __HAL_TIM_CLEAR_FLAG(&tim16_gate_driver, TIM_FLAG_CC1);

  __HAL_TIM_CLEAR_FLAG(&tim16_gate_driver, TIM_FLAG_COM);

__HAL_TIM_MOE_DISABLE(&tim16_gate_driver);

__HAL_TIM_DISABLE_IT(&tim16_gate_driver, TIM_IT_UPDATE);

}

void GATE_DRIVER_TIM_CC_IRQ_Handler(void)

{

if(__HAL_TIM_GET_FLAG(&tim16_gate_driver, TIM_FLAG_UPDATE) != RESET)

{

if(__HAL_TIM_GET_IT_SOURCE(&tim16_gate_driver, TIM_IT_UPDATE) !=RESET)

Disable_Gate_Driver(); // �?�时关闭比较,�?然一直�?�?比较,�?�?进入中断,导致清除中断标志�?无效

Stop_Shock_Release();

HAL_GPIO_WritePin( GPIOE, GPIO_PIN_2, GPIO_PIN_SET );

if ( Shock_Flow == SHOCK_FLOW_PRE_CHARGE )

{

Start_Pos_Shock(); // second config

return ;

}

if ( Shock_Flow == SHOCK_FLOW_POS )

{

Start_Neg_Shock(); // third config

return ;

}

if ( Shock_Flow == SHOCK_FLOW_NEG )

{

Disable_Patient_Relay();

Shock_Flow = SHOCK_FLOW_END;

DEBUG(" shock complete !");

return ;

}

}

}

}

void Start_Pos_Shock(void)

{

Shock_Flow = SHOCK_FLOW_POS;

Enable_Gate_Driver_Keep( 30*Delay + shock_param.pos_time , shock_param.pause_time );

Positive_Shock_Release_Keep( shock_param.pos_time );

}

void Start_Neg_Shock(void)

{

UINT16 neg_time = shock_param.neg_time ;

Shock_Flow = SHOCK_FLOW_NEG;

Enable_Gate_Driver_Keep( 30*Delay + neg_time , 0 );

Neg_Shock_Release_Keep( neg_time );

}

4 REPLIES 4

We don't see what exactly do you do in Start_Pos_Shock() and Start_Neg_Shock(), and those are apparently the functions which prevent the timer from working, according to your description.

If the TIM registers content does not change except ARR and CCRx, make sure that CNT *is* changing between consecutive readouts of the TIM registers, which means that TIM is running. If there is no interrupt, then make sure you did not disable it in NVIC. If there is no output waveform, check the relevant GPIO registers, and make sure CRRx is below ARR.

JW

hello ,

Start_Pos_Shock() and Start_Neg_Shock() , just include two function ,below detail:

1.

void Enable_Gate_Driver_Keep( UINT16 br_on_time , UINT16 br_off_time )

{

UINT16 br_total_time = 0;

br_total_time = br_on_time + br_off_time;

if ( br_total_time >= 0xFFFF )

{

br_total_time = 0xFFFF;

}

GATE_DRIVER_TIM_CLK_DISABLE();

GATE_DRIVER_TIM_CLK_ENABLE();

tim16_gate_driver.Init.Period = br_total_time - 1;

HAL_TIM_OC_Init(&tim16_gate_driver);

tim16_sConfigOC.Pulse    = br_on_time ;

HAL_TIM_OC_ConfigChannel(&tim16_gate_driver, &tim16_sConfigOC, TIM_CHANNEL_1);

// �?新开�?�

TIM_CCxChannelCmd(tim16_gate_driver.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);

__HAL_TIM_CLEAR_FLAG(&tim16_gate_driver, TIM_FLAG_UPDATE);

__HAL_TIM_ENABLE_IT(&tim16_gate_driver, TIM_IT_UPDATE);

__HAL_TIM_MOE_ENABLE(&tim16_gate_driver);

  __HAL_TIM_ENABLE(&tim16_gate_driver);

}

2.Positive_Shock_Release_Keep(), this function is use config TIM 1, so it don't affect TIM16.

via keil debug watch , I can see SR-register , CC1IF and UIF are be set, I have set update interrupt, toggle one pin in interrupt , I can see the pin toggle three times ,also CC1IF, UIF be set three times, but just no output waveform about the last two config.

of course ,I have tried config GPIO every time, but no matter .

thank you ​

OK, so in the debugger, when there is no output waveform, stop the code execution (break); check, if the TIM CNT register is changing, i.e. if the timer is running; then check if the CCRx register is set to nonzero and below ARRx register; check if the given channel is set properly in CCMR and enabled in CCER; and then check if MOE in BDTR register is set.

JW

0690X000009YPm9QAG.pngI have confirm below :

  1. TIM CNT is changing , because TIM can generate three UIF interrupt
  2. CCRX register set nonzero value ,and below ARR register .
  3. MOE in BDTR register is set
  4. channel is set properly in CCMR ,enabled in CCER

you can see my upload pic ,the left vertical yellow is time start point ,from top to ​bottom, four lines ,

  • the top line ( red line ) pin waveform , in update interrupt hander ,I pull up ,when I pull down config TIM complete ,enable TIM .

so, TIM is running ,otherwise , can not generate interrupt three times.

  • the blue line is OC waveform during T1, the TIM is running, only T1 generate OC wavform once, T2,T3 not generate.

If convenient for you, I send my source code to you .