2015-02-23 03:11 PM
I'm using TIM1 channels 1 and 2 to resolve a PWM input. So far I have been able to get the frequency to a deci-hertz and the duty cycle to a deci-percent.
Since the input signal can, legitimately, go high or low and stay there, I will get no more interrupts to unload the timer and update the calculations.The timer should count to 0xFFFF (counter period), but can I get it to generate an interrupt at that point so I can see where the PWM input is stuck?Thanks. #tim-pwm-stm322015-02-23 04:45 PM
Isn't that the Update interrupt? (STM32F4 -> TIM1_UP_TIM10_IRQHandler)
For some other timeout number, use Channel 3 or 4 with compare values?2015-02-24 03:26 PM
Nothing yet.
What I did is set up the CC and UP interrupts, the CC system works nicely. I set the Timer1 period to 0xFFFF, expecting that when the timer1 CNT register increments (clocked by APB2/1000 == 84MHz/1000) and reaches 0xFFFF (countup), I would get the update interrupt as the counter reloads - but Noooooo. Code follows. (The following is my best understanding of how the PWM input resolving system works) For those not playing along, timer1 is being incremented by a fraction of the system clock. An external signal on TIM1_CH1 causes the capture 1 register to grab a snapshot of CNT on a high going transition. The timer setup also routes TIM1_CH1 to channel 2 which grabs a snapshot of CNT on a low going transition. In the system that I am working with, the PWM can range from 0 to 100% inclusive. Now, when TIM1_CH1 does not make any transitions (stuck high or low because of the nature of the equipment), channel 1 and channel 2 will not grab the value of the CNT register, nor will it cause CNT to clear, it will just keep counting. Eventually CNT will hit 0xFFFF and SHOULD cause a UP interrupt. As you can see from my interrupt routine entry routineTIM1_UP_TIM10_IRQHandler
I have put in code to toggle a bit when the routine is entered (yes I have tested the toggle bit stuff). I get no indication of the interrupt triggering. Bother. Clive, thanks for your help. You should get paid by ST.
tim.c
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim6;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
TIM_IC_InitTypeDef sConfigIC;
TIM_OC_InitTypeDef sConfigOC;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 1000;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xffff;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim1);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_RISING;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 1;
HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);
HAL_TIM_IC_Init(&htim1);
HAL_TIM_PWM_Init(&htim1);
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sSlaveConfig.TriggerFilter = 0;
HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim_base->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* Peripheral clock enable */
__TIM1_CLK_ENABLE();
/**TIM1 GPIO Configuration
PE9 ------> TIM1_CH1
PE14 ------> TIM1_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
{yadda}
stm32f4xx_it.c
void TIM1_CC_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_CC_IRQn 0 */
/* USER CODE END TIM1_CC_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_CC_IRQn 1 */
/* USER CODE END TIM1_CC_IRQn 1 */
}
void TIM1_UP_TIM10_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
HAL_GPIO_WritePin( GPIOD, GPIO_PIN_11, GPIO_PIN_SET);
/* USER CODE END TIM1_UP_TIM10_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
HAL_GPIO_WritePin( GPIOD, GPIO_PIN_11, GPIO_PIN_RESET);
/* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
2015-02-25 07:06 AM
Hello Andrei
just a comment, Did you enable the UPDATE IT by using either : __HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE); or HAL_TIM_Base_Start_IT(&htim1); on top of the input capture start function ( to get the pwm input capture started with CC interrupt enabled) HAL_TIM_IC_Start_IT (&htim1,TIM_CHANNEL_1); regardsFrom: chichak.andrei
Posted: Wednesday, February 25, 2015 12:27 AM Subject: PWM input with a signal that can get stuck high or lowNothing yet.
What I did is set up the CC and UP interrupts, the CC system works nicely. I set the Timer1 period to 0xFFFF, expecting that when the timer1 CNT register increments (clocked by APB2/1000 == 84MHz/1000) and reaches 0xFFFF (countup), I would get the update interrupt as the counter reloads - but Noooooo. Code follows. (The following is my best understanding of how the PWM input resolving system works) For those not playing along, timer1 is being incremented by a fraction of the system clock. An external signal on TIM1_CH1 causes the capture 1 register to grab a snapshot of CNT on a high going transition. The timer setup also routes TIM1_CH1 to channel 2 which grabs a snapshot of CNT on a low going transition. In the system that I am working with, the PWM can range from 0 to 100% inclusive. Now, when TIM1_CH1 does not make any transitions (stuck high or low because of the nature of the equipment), channel 1 and channel 2 will not grab the value of the CNT register, nor will it cause CNT to clear, it will just keep counting. Eventually CNT will hit 0xFFFF and SHOULD cause a UP interrupt. As you can see from my interrupt routine entry routineTIM1_UP_TIM10_IRQHandler
I have put in code to toggle a bit when the routine is entered (yes I have tested the toggle bit stuff). I get no indication of the interrupt triggering. Bother. Clive, thanks for your help. You should get paid by ST.
tim.c
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim6;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
TIM_IC_InitTypeDef sConfigIC;
TIM_OC_InitTypeDef sConfigOC;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 1000;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xffff;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim1);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_RISING;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 1;
HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);
HAL_TIM_IC_Init(&htim1);
HAL_TIM_PWM_Init(&htim1);
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sSlaveConfig.TriggerFilter = 0;
HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim_base->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* Peripheral clock enable */
__TIM1_CLK_ENABLE();
/**TIM1 GPIO Configuration
PE9 ------> TIM1_CH1
PE14 ------> TIM1_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
{yadda}
stm32f4xx_it.c
void TIM1_CC_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_CC_IRQn 0 */
/* USER CODE END TIM1_CC_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_CC_IRQn 1 */
/* USER CODE END TIM1_CC_IRQn 1 */
}
void TIM1_UP_TIM10_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
HAL_GPIO_WritePin( GPIOD, GPIO_PIN_11, GPIO_PIN_SET);
/* USER CODE END TIM1_UP_TIM10_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
HAL_GPIO_WritePin( GPIOD, GPIO_PIN_11, GPIO_PIN_RESET);
/* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
2015-02-25 08:50 AM
Yes, well spotted, I forgot to list this bit:
if (HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2) != HAL_OK) {
/* Starting Error */
error();
}
/*##-5- Start the Input Capture in interrupt mode ##########################*/
if (HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK) {
/* Starting Error */
error();
}
2015-02-25 09:44 AM
Thanks Stark,
This was the solution:__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);The HAL start routine for IT enables the CC interrupt, but not the UP.Thanks again.