stm32计时器HAL_TIM_PerioidElapsedCallback()未触发

时间:2018-09-10 21:28:35

标签: timer arm interrupt stm32 nucleo

我才刚刚开始学习如何使用ST的HAL对ARM微控制器进行编程。所以我有这段代码,它使用计时器在输出比较模式下生成1khz和20khz信号。一切都很好,我按预期进行了示波器测试。问题出在HAL_TIM_PeriodElapsedCallback()上,当计时器溢出并切换LED时应调用该函数。 LED的配置正确。HAL_TIM_IRQHandler(&htim3);调用了HAL_TIM_PeriodElapsedCallback()。每当定时器3的中断被触发时(例如定时器溢出),就会调用该函数。 HAL_TIM_IRQHandler(&htim3);当输出比较寄存器与定时器“计数”寄存器的值匹配并且调用HAL_TIM_OC_DelayElapsedCallback()时,也经常调用该函数。所有这一切都有效,所以我知道timer3中断已正确配置,但是我无法弄清楚为什么在计时器溢出时未调用正确的回调。我想的是,输出比较触发的中断会以某种方式弄乱溢出中断。我也尝试过使用调试器并遵循代码,但只是跳过了HAL_TIM_OC_DelayElapsedCallback()。我已经包含了main()以及HAL_Timer库中处理所有中断的相关代码。 请帮我调试一下!  PS。 Nucleo_BSP_Init();只需配置时钟和GPIO,所以我就不用输入这段代码了,因为我知道LED可以工作并且时钟是使用CubeMX配置的。

----------------MAIN CODE --------------------

    #include "stm32f4xx_hal.h"
    #include <nucleo_hal_bsp.h>
    #include <string.h>

    /* Private variables ---------------------------------------------------------*/
    TIM_HandleTypeDef htim3;

    void MX_TIM3_Init(void);

    uint16_t computePulse(TIM_HandleTypeDef *htim, uint32_t chFrequency) {
      uint32_t timFrequency= HAL_RCC_GetPCLK1Freq() / (htim->Instance->PSC + 1);

      return (uint16_t)(timFrequency / chFrequency);
    }

    volatile uint16_t CH1_FREQ = 0;
    volatile uint16_t CH2_FREQ = 0;

    int main(void) {
      HAL_Init();

      Nucleo_BSP_Init();
      MX_TIM3_Init();

      HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);
      HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_2);

      while (1);
    }

    /* TIM3 init function */
    void MX_TIM3_Init(void) {
      TIM_OC_InitTypeDef sConfigOC;

      htim3.Instance = TIM3;
      htim3.Init.Prescaler = 2;
      htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim3.Init.Period = 65535;
      htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      HAL_TIM_OC_Init(&htim3);

      CH1_FREQ = computePulse(&htim3, 1000);
      CH2_FREQ = computePulse(&htim3, 20000);

      sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
      sConfigOC.Pulse = CH1_FREQ;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

      sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
      sConfigOC.Pulse = CH2_FREQ;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);
    }

    void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) {
      uint32_t pulse;

      /* TIMx_CH1 toggling with frequency = 1KHz */
      if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
      {
        pulse = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
        /* Set the Capture Compare Register value */
        __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (pulse + CH1_FREQ));
      }

      /* TIM2_CH2 toggling with frequency = 20KHz */
      if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
      {
        pulse = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
        /* Set the Capture Compare Register value */
        __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, (pulse + CH2_FREQ));
      }
    }

    void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* htim_base) {
      GPIO_InitTypeDef GPIO_InitStruct;
      if(htim_base->Instance==TIM3) {
        __TIM3_CLK_ENABLE();

        /**TIM3 GPIO Configuration
        PA6     ------> TIM3_CH1
        PA7     ------> TIM3_CH2
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
      }
    }

    void TIM3_IRQHandler(void) {

      HAL_TIM_IRQHandler(&htim3);
    }

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

      if(htim->Instance == TIM3){
         // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
         HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
      }

    }

IRQ处理程序代码,每次触发中断时都会被调用。

 void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    {
      /* Capture compare 1 event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
        {
          {
            __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
            htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;

            /* Input capture event */
            if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
            {
              HAL_TIM_IC_CaptureCallback(htim);
            }
            /* Output compare event */
            else
            {
              HAL_TIM_OC_DelayElapsedCallback(htim);
              HAL_TIM_PWM_PulseFinishedCallback(htim);
            }
            htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
          }
        }
      }
      /* Capture compare 2 event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
      {

        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
          /* Input capture event */
          if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
          {          
            HAL_TIM_IC_CaptureCallback(htim);
          }
          /* Output compare event */
          else
          {
            HAL_TIM_OC_DelayElapsedCallback(htim);
            HAL_TIM_PWM_PulseFinishedCallback(htim);
          }
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
        }
      }
      /* Capture compare 3 event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
          /* Input capture event */
          if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
          {          
            HAL_TIM_IC_CaptureCallback(htim);
          }
          /* Output compare event */
          else
          {
            HAL_TIM_OC_DelayElapsedCallback(htim);
            HAL_TIM_PWM_PulseFinishedCallback(htim); 
          }
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
        }
      }
      /* Capture compare 4 event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
          /* Input capture event */
          if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
          {          
            HAL_TIM_IC_CaptureCallback(htim);
          }
          /* Output compare event */
          else
          {
            HAL_TIM_OC_DelayElapsedCallback(htim);
            HAL_TIM_PWM_PulseFinishedCallback(htim);
          }
          htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
        }
      }
      /* TIM Update event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)

      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
        {

          __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);

          HAL_TIM_PeriodElapsedCallback(htim);
        }
      }
      /* TIM Break input event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
          HAL_TIMEx_BreakCallback(htim);
        }
      }
      /* TIM Trigger detection event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
          HAL_TIM_TriggerCallback(htim);
        }
      }
      /* TIM commutation event */
      if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
      {
        if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
        {
          __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
          HAL_TIMEx_CommutationCallback(htim);
        }
      }
    }

0 个答案:

没有答案