cancel
Showing results for 
Search instead for 
Did you mean: 

Proper way to set up the PWM input using Tim2 ch1 & ch3?

Richard Cooke
Associate II

I'm using the STM32L031K6 chip. I have a 100HZ signal connected to PA0 (Timer2 ch1) and PB0 (Timer2 ch 3). I think I've setup everything correctly using the CubeMX.

The problem I'm finding is the interrupt only fires for the positive going edge on TIM_CHANNEL_1. The TIM_CHANNEL_3 never fires.

Here's my setup in TIM.C:

void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_IC_InitTypeDef sConfigIC;
 
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 3;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xffff;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}

And here's my PWM interrupt handler:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)    // AC input pulses will trigger this interrupt
{
	static uint16_t index = 0;
	static uint16_t index2 = 0;
 
	if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
		timerCount1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
		pulseCount[index] = timerCount1;
		index++;
		if(index > 9)
		 index = 0;
		TIM2->CNT = 0;
		} // end of htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1
 
	if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
		{
		timerCount2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
		pulseCount2[index2] = timerCount2;
		index2++;
		if(index2 > 9)
		  index2 = 0;
		} // end of htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3

Using my oscope I can see the pulses on PA0 and PB0 so I know the signal is there. Using the debugger I can see that TIM_Channel_1 is triggering but not channel_3. The pulse ON time is around 3ms and the off time is 7ms. The clock is at 8MHz with a prescaler of 3 so my timer clock should be 0.5Mhz.

Can anyone point me to where I went wrong?

Thanks in advance,

Ricahrd

6 REPLIES 6

PWM Input pairs CH1 and CH2, not CH3

For CH3 you'll need to use standard input capture in a free-running timer

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

Thanks. I guess I'm way off base. Can you point me to an example of how I'd setup the PWM input using Ch1 and Ch2? What's the benefits of using standard input capture versus the PWM input?

Richard Cooke
Associate II

After looking at the CubeMX configuration screen it looks like I'm actually using the direct input capture and not PWM input. Any clue as to why the TIM_CHANNEL_3 isn't firing?

Richard Cooke
Associate II

After looking at the CubeMX configuration screen it looks like I'm actually using the direct input capture and not PWM input. Any clue as to why the TIM_CHANNEL_3 isn't firing?

It doesn't see a falling edge on the CH3 pin?

Check the pin configuration for PB0 (AF5)

Check that IRQ are enabled for CC3 events

 /*##-3- Start the Input Capture in interrupt mode ##########################*/

 if(HAL_TIM_IC_Start_IT(&hTim2, TIM_CHANNEL_3) != HAL_OK)

 {

   /* Starting Error */

   Error_Handler();

 }

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Richard Cooke
Associate II

Thanks. It looks like I failed to start the input capture:

As soon as I added:

if(HAL_TIM_IC_Start_IT(&hTim2, TIM_CHANNEL_3) != HAL_OK)

Things are working.