[메모] 타이머 인터럽트에서 L 치카 (STM32L1-TIM2 사용)

개요


  • 타이머 인터럽트에 의한 L치카
  • 타이 마스터트: HAL_TIM_Base_Start_IT(&htim2);
  • 타이머 핸들러 함수: void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

  • 파워 절약도 해본다. (SleepMode)
  • 관련 기사
  • STM32L152C-DISCOVERY + STM32CubeMX + MDK-ARM Lite로 L 치카를 해 보았다 (그 1 ~ 툴 준비)
  • STM32L152C-DISCOVERY + STM32CubeMX + MDK-ARM Lite에서 L 치카를 해 보았다 (그 2 ~ 코드 생성에서 디버거 설정)

  • STM32L152C-DISCOVERY + STM32CubeMX + MDK-ARM Lite에서 L 치카를 해 보았다 (그 3 ~ L 치카 코드 실행) => 폴링에 의한 L 치카 (HAL_Delay)

  • STM32L152C-DISCOVERY + STM32CubeMX + MDK-ARM Lite로 L치카를 해보았다(그 4~FreeRTOS) => FreeRTOS에 의한 L 치카 (osDelay)


  • 환경


  • STM32L152C-DISCOVERY (STM32L152RCT6)
  • STM32CubeMX (v4.15.1)
  • Firmware Package for Family STM32L1 (v1.5.0)
  • MDK-ARM Lite v5.18

  • 절차


  • ↑ 관련 기사 (1 ~ 2 정도)에서 도구 및 환경 준비
  • STM32CubeMX를 열고
  • New Project
  • [Board Selector] => Discovery | STM32L152C-DISCO | STM32L152RCTx 를 선택하고 [OK]


  • [Pinout]
  • RCC => High Speed ​​Clock(HSE) : Bypass Clock Source
  • PC13-WKUP2 (IDD_CNT_EN과 함께)를 클릭하고 Reset State
  • TIM2 => Clock Source : Internal Clock



  • [Configuration] => [Control] => [TIM2] 클릭
  • [Parameter Settings]
  • Counter Settings
  • Prescaler : 999 (= 1000배 (n+1배))
  • Counter Period: 16000
    => TIM2에 공급되는 클럭을 (1000)으로 나눈 주기로, 16000 카운트하면 인터럽트 걸린다.
    => 32MHz ÷ 1000 ÷ 16000 => 2Hz => 500msec마다 인터럽트



  • [NVIC Setting]
  • TIM2 global interrupt: [v] Enabled 체크를 한다


  • Project => Generate Code (Ctrl+Shit+G) 이런 식으로
  • [Open project]
  • MDK-ARM이 열리므로 main.c에 ↓ 코드를 쓴다. 그리고는, 빌드하고[F7], 플래시에 구워서[F8], 디버그 Ctrl+[F5], 실행[F5]하면,

    이런 것이 나오지만, LED는 깜짝 놀랐다. STM이 잠들어가면 디버거가 끊어진다.

  • Application/user/main.c
    /* USER CODE BEGIN 0 */
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
      static int ledOn = 0;
      if (htim == &htim2)
      {
        #define LED_GPIO_PORT         GPIOB
        #define LED_GREEN_GPIO_PIN    GPIO_PIN_7
        #define LED_BLUE_GPIO_PIN     GPIO_PIN_6
        HAL_GPIO_WritePin(LED_GPIO_PORT, LED_GREEN_GPIO_PIN, (ledOn==0) ? GPIO_PIN_RESET : GPIO_PIN_SET);
        ledOn = 1 - ledOn;
      }
    }
    /* USER CODE END 0 */
    
    int main(void)
    {
    
    ....
    
      /* USER CODE BEGIN 2 */
      HAL_TIM_Base_Start_IT(&htim2);
      HAL_SuspendTick();
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
      /* USER CODE END WHILE */
    
      /* USER CODE BEGIN 3 */
      HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
    
      }
      /* USER CODE END 3 */
    
    }
    ...
    

    간단한 설명


  • void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  • 타이머 인터럽트로 여기에 날아온다.
  • 타이머 핸들 htim에서 TIM2로 날아 왔는지 확인
  • 호출될 때마다 LED를 토글시키는 코드.

  • HAL_TIM_Base_Start_IT(&htim2);
  • 타이머 시작

  • HAL_SuspendTick();

  • SysTick을 멈춘다. 1msec마다 SysTick의 인터럽트가 걸려 있는 것 같지만, 이번, SleepMode에 떨어뜨리기 위해, SysTick을 끊는다. 그렇지 않으면, 이 녀석에서 일어나 버린다. (같은 일이 코멘트에 쓰여졌다)

    stm32l1xx_hal_pwr.c
    /**
    * @brief Enters Sleep mode.
    * @note  In Sleep mode, all I/O pins keep the same state as in Run mode.
    * @param Regulator: Specifies the regulator state in SLEEP mode.
    *         This parameter can be one of the following values:
    *            @arg PWR_MAINREGULATOR_ON: SLEEP mode with regulator ON
    *            @arg PWR_LOWPOWERREGULATOR_ON: SLEEP mode with low power regulator ON
    * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
    *           When WFI entry is used, tick interrupt have to be disabled if not desired as 
    *           the interrupt wake up source.
    *           This parameter can be one of the following values:
    *            @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
    *            @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
    * @retval None
    */
    void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
    ...
    


  • HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
  • => SleepMode에 들어간다. WFI (Wait For Interrupt)에서 인터럽트가 발생하면 발생합니다.

  • 좋은 웹페이지 즐겨찾기