таймеры stm32 HAL_TIM_PerioidElapsedCallback () не запускаются - PullRequest
0 голосов
/ 11 сентября 2018

Я только начинаю изучать, как программировать микроконтроллеры ARM с помощью STAL HAL.Итак, у меня есть этот код, который генерирует сигнал 1 кГц и 20 кГц, используя таймер в режиме сравнения выходных данных.Это все работает хорошо, и я проверил это с областью, и это как ожидалось.Проблема связана с HAL_TIM_PeriodElapsedCallback (), который должен вызываться при переполнении таймера и переключении светодиода.Конфигурация индикатора правильная. HAL_TIM_PeriodElapsedCallback () вызывается HAL_TIM_IRQHandler (& htim3);который вызывается всякий раз, когда запускается прерывание для timer3, например, когда переполняется таймер.HAL_TIM_IRQHandler (& htim3);также часто вызывается, когда регистр сравнения выходных данных совпадает с регистром счетчика таймеров и вызывает HAL_TIM_OC_DelayElapsedCallback ().Все это работает, поэтому я знаю, что прерывание timer3 настроено правильно, но я просто не могу понять, почему при переполнении таймера не вызывается правильный обратный вызов.Я предполагаю, что interrputs, запущенные Output Compare, каким-то образом путаются с прерыванием переполнения.Я также пытался использовать отладчик и следовать коду, но HAL_TIM_OC_DelayElapsedCallback () просто пропущен.Я включил мой main (), а также соответствующий код из библиотеки HAL_Timer, которая обрабатывает все прерывания.Пожалуйста, помогите мне отладить это!PS.Nucleo_BSP_Init ();просто настраивает часы и GPIO, поэтому я не буду помещать этот код, так как я знаю, что светодиод работает, и часы настроены с использованием 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);
        }
      }
    }
...