cancel
Showing results for 
Search instead for 
Did you mean: 

Can STM32F303RE send Comparator to both output pin and to Timer ?

BTrem.1
Senior II

I've configured my STM32F303RE to send the COMP4 to the output (PB1) as well as to TIM4_Ch2. I also am running an external signal generator in from PB6 to TIM4_Ch1.

I can see the COMP4 output on PB1 but not at the TIM4_Ch2. I can see the external signal being captured from TIM2_Ch1.

[Q] Can the COMP4 output be directed simultaneously to both the output pin and to the TIM4_Ch2 ?

If I modify the TIM4 initialization to send Ch1 to IC2 and Ch2 to IC1 I do see the signal generator capture move to the other capture register but the COMP4 is still not detected.

P.S. My comparator output also has multiple crossings from zero-crossing chatter.

static void MX_TIM4_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 32;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 23500;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
	/* sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; */
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_Base_Start(&htim4);
}

COMP4 Init:

static void MX_COMP4_Init(void)
{
  /*##-1- Configure the COMP4 peripheral ################################*/
 
  hcomp4.Instance = COMP4;
  hcomp4.Init.InvertingInput = COMP_INVERTINGINPUT_DAC1_CH1;
  hcomp4.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_IO1;
  hcomp4.Init.Output = COMP_OUTPUT_TIM4IC2;
  hcomp4.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
  hcomp4.Init.BlankingSrce = COMP_BLANKINGSRCE_NONE;
  hcomp4.Init.TriggerMode = COMP_TRIGGERMODE_NONE;
	
  hcomp4.Init.Hysteresis = COMP_HYSTERESIS_NONE;
  hcomp4.Init.WindowMode = COMP_WINDOWMODE_DISABLE;
 
  if (HAL_COMP_Init(&hcomp4) != HAL_OK)
  {
    Error_Handler();
  }
	
   /*##-2- Start the comparator process ###############################*/
	if (HAL_COMP_Start(&hcomp4) != HAL_OK)
  {
    Error_Handler();
  }
 
}

14 REPLIES 14

What did you change in the software?

Can you put it back into the non-working state?

JW

0693W000001tU1DQAU.jpgThat's the strange thing; no code change. The COMP4 output is always present on PB1. With no input on PB6 (TIM4_Ch1) both TIM4_CH1 and TIM4_Ch2 do not run. Then I connect a jumper wire (real-time) from PB1 to PB6. When I do this both TIM4 CCR1 and CCR2 start capturing.

I'll go through the pin out of the Nucleo-64 F303RE again and also matrix connection for PB1 & PB6 going to TIM4_Ch1 and TIM4_Ch2.

I'm attaching an updated block diagram adding TIM4_Ch1 and showing the jumper wire. Also, FYI, when I do this both dma channels start running.

Thanks,

I changed my setup to run an external clock source into PB6 (CN10_17). When I do this BOTH TIM4_Ch1 and TIM4_Ch2 start capturing in CCR1 and CCR2 the same value. It's almost like IC1 and IC2 are both receiving TIM4_Ch1 input.

Block diagram attached.0693W000003BHuZQAW.jpg

> When I do this BOTH TIM4_Ch1 and TIM4_Ch2 start capturing in CCR1 and CCR2 the same value. It's almost like IC1 and IC2 are both receiving TIM4_Ch1 input.

And don't they? What's the CCMR1 setting?

Is this still the Nucleo board? Maybe you could strip down the code to an absolute minimal but compilable example, preferrably not depending on Cube or any other "library", and post.

JW

I think I have it working now !!!!

  • The DAC1_Ch1 at PA4 is driving the COMP4. The output of COMP4 is visible on PB1 and it is also driving TI2.
  • An external signal source is coming in on PB6 as TIM4_Ch1 and is captured by the timer at TI1
  • The DMA1 channels 1 and 4 are being triggered properly.

>> And don't they? What's the CCMR1 setting? : This was the latest problem see below.

>> Is this still the Nucleo board? : Yes it is, Nucleo-64 F303RE + IHM16M1 Motor driver

This is my TIM4 initialization where I had a problem with the CCMR1 register setting. Note I commented out line 40 where the CC1S bits were wrong. It gets set properly on line 33.

static void MX_TIM4_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 32;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 23500;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTI;  <== commented out
  */
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */
  //bpt
  HAL_TIM_Base_Start(&htim4);
  /* USER CODE END TIM4_Init 2 */
 
}

For completeness here is the setup of COMP4:

static void MX_COMP4_Init(void)
{
  hcomp4.Instance = COMP4;
  hcomp4.Init.InvertingInput = COMP_INVERTINGINPUT_DAC1_CH1;
  hcomp4.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_IO1;
  hcomp4.Init.Output = COMP_OUTPUT_TIM4IC2;
  hcomp4.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
  hcomp4.Init.BlankingSrce = COMP_BLANKINGSRCE_NONE;
  hcomp4.Init.TriggerMode = COMP_TRIGGERMODE_NONE;
  if (HAL_COMP_Init(&hcomp4) != HAL_OK)
  {
    Error_Handler();
  }
}

For now I am manually enabling COMP4 in the debugger.

JW --- I want to thank you for all your help. I'll mark your last response as Best Answer.