Skip to main content
Explorer
June 22, 2023
Solved

TIM2_ETR on Nucleo-f439zi

  • June 22, 2023
  • 4 replies
  • 2670 views

I have a 1Hz square wave signal with a 50 % duty cycle going into a pin on the MCU.

The pin on the MCU (PA0) is configured to be TIM2_ETR via the STM MX Cube tool.

I am expecting to go into TIM2_IRQHandler() every second, i.e. every positive edge of the external clock.

However, I don't, I just go in TIM2_IRQHandler once just after startup.

Any ideas as to why this is happening ?

    This topic has been closed for replies.
    Best answer by Bob S

    I think you have things backwards.  The "input capture" function copies the current TIMx.CNT value into the CCR register.  If you want to count the number of signal_b edges per signal_a edge, put signal_b into the ETR as clock, then signal_a into CH4.  Then instead of HAL_TIM_Start_IT() you need to call the "start input capture" (I don't recall the exact name).

    4 replies

    Super User
    June 22, 2023

    Can't help much without seeing your code.  Are you using the stock HAL TIM2_IRQHandler()?

    Explorer
    June 29, 2023

    static void MX_TIM2_Init(void)
    {

    /* USER CODE BEGIN TIM2_Init 0 */

    /* USER CODE END TIM2_Init 0 */

    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    /* USER CODE BEGIN TIM2_Init 1 */

    /* USER CODE END TIM2_Init 1 */
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 0;
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 4294967295;
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
    {
    Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
    sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
    sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
    sClockSourceConfig.ClockFilter = 0;
    if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
    {
    Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
    {
    Error_Handler();
    }
    /* USER CODE BEGIN TIM2_Init 2 */

    /* USER CODE END TIM2_Init 2 */

    }

     

    main() looks like so:

    int main(void)
    {
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_TIM2_Init();
    /* USER CODE BEGIN 2 */

    /* Start timer */
    HAL_TIM_Base_Start_IT(&htim2);

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
    }

     

    Visitor II
    July 1, 2023

    Am i wrong or i do not see any :

     HAL_NVIC_SetPriority(xxxx, 9, 0);
     HAL_NVIC_EnableIRQ(xxx);

    Related to Timer 2? (xxxx have to be substituted with the relative IRQN of TIM2). Please note that also the priority need to be adjusted based on your project.

     

    D.

    Super User
    June 29, 2023

    You don't show any timer callback functions, and I presume you are using the stock HAL timer interrupt handler.

    You have PA0/ETR2 configured as the CLOCK input to the timer.  So every rising edge will increment the timer count.  Calling HAL_TIM_Base_Start_IT() only enabled the UPDATE interrupt (i.e. timer overflow/reload).  You SHOULD only get an interrupt after 2^32 rising edges, when the timer rolls over.  Not sure why you get 1 interrupt.

    What do you REALLY want this signal to do?  Do you only need an interrupt on each rising edge?  Then maybe use GPIO EXTI instead.  Or configure PA0 as TIM2 CH1 and configure it as "input capture).

    If you need an interrupt AND some kind of counter value to measure the time between interrupts, the use PA0 as an input capture like above.

    Explorer
    June 30, 2023

    Yes i am using the stock HAL interrupt timer.

    Ultimately what I want is shown below (I am using a GPS 1pps signal to do some sync, want to get simple example working first on dev board).

    signal_a is a 1Hz square wave

    signal_b is a 1kHz sinewave, amplitude of 3.3V.

    I was aiming to connect signal_a to PA0, and use the TIM2_ETR functionality.

    Then I was aiming to connect signal_b to PA3, and use the TIM2_CH4 input capture functionality.

    In every period of signal_a (every second) I want to count signal_b, so in this case I would get the answer (should) of 1000. I would then like to reset the count of signal_b such that i cant obtain another total count (of signal_b) in the next period of signal_a.

    I want to jump in interrupt associated with TIM2_ETR (every second), then pull the count from the input capture / TIM2_CH4. So every second ideally I should get 1000, on my actual circuit board though I might get 999, then 990 etc, this is when I can apply some correction factor.

    Thanks for your help, really appreciate it.

     

     

    Bob SAnswer
    Super User
    June 30, 2023

    I think you have things backwards.  The "input capture" function copies the current TIMx.CNT value into the CCR register.  If you want to count the number of signal_b edges per signal_a edge, put signal_b into the ETR as clock, then signal_a into CH4.  Then instead of HAL_TIM_Start_IT() you need to call the "start input capture" (I don't recall the exact name).