2019-07-03 08:49 PM
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 );
}
2019-07-04 01:33 AM
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
2019-07-04 02:03 AM
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
2019-07-04 04:19 AM
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
2019-07-04 05:03 AM
I have confirm below :
you can see my upload pic ,the left vertical yellow is time start point ,from top to bottom, four lines ,
so, TIM is running ,otherwise , can not generate interrupt three times.
If convenient for you, I send my source code to you .