b. 임베디드/STM32

[STM32F407VGT Discovery] Timer UPDATE INTERRUPT

로봇쟁이 2019. 6. 18. 00:41

이번에는 타이머/카운터 업데이트 인터럽트를 이용해서 LED를 순차적으로 점멸해보겠습니다.

먼저 STM32F4 시리즈는 다음과 같이 많은 수의 타이머가 존재합니다.

 

그런데 각 타이머 별로 특징이 있습니다.

각 타이머당 채널도 여러 가지고 Resolution이 다르다거나 최대 클럭이 다르다거나 사용하는 APB 레지스터가 다르다거나 등등 종류가 참 많고 복잡합니다. ^^;;;;

 

일단 TypeBASIC이라고 되어 있는 타이머를 이용해보도록 하겠습니다.

저는 TIM7을 이용해봤습니다.

 

먼저 TIM7은 채널이 없고 다른것과 비교해봤을 때 꽤 단순하게 되어 있습니다.

TIM7APB1 번 클럭을 사용하고 MAX Clock168MHz/2 = 84MHz

그림처럼 Activated에 클릭하고

 

Prescaler = 9999

CounterPeriod (ARR : AutoReload 레지스터) = 8399 를 설정합니다.

 

계산식 = 1 / 84MHz * (Prescaler + 1) * (CP + 1) = 1

 

Counter Mode = UP

0~부터 시작해서 CounterPeriod에 도착하면 INTERUPT 발생합니다.

 

 

 

인터럽트를 발생시키기 위해서 반드시 저 Enabled를 체크해야 합니다.

그리고 HAL -> LL로 변경해주시고 Generate Code하세요 ^^;

 

MAIN 코드입니다. 두줄 추가 되었습니다 ^^;;;

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_TIM7_Init();

  /* USER CODE BEGIN 2 */
  LL_TIM_EnableCounter(TIM7);
  LL_TIM_EnableIT_UPDATE(TIM7);
  /* USER CODE END 2 */

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

LL_TIM_EnableCounter(TIM7) -> 타이머를 동작시키겠다는 의미이고

LL_TIM_EnableIT_UPDATE(TIM7) -> TIM7 UPDATE 인터럽트를 ENABLE 하겠다는 의미입니다.

 

이제 stm32f4xx_it.c 파일을 열어보면 TIM7_IRQHandler 함수가 생성되어 있는데

해당 함수에 인터럽트가 발생 시 동작할 LED 점멸 구문을 작성하시면 됩니다.

 

저는 다음과 같이 flag를 변수로 만들어서 순차 점멸하도록 만들었습니다.

 

void TIM7_IRQHandler(void)
{
  /* USER CODE BEGIN TIM7_IRQn 0 */
	Timer_flag++;
	if(Timer_flag == 1)
	{
		LL_GPIO_TogglePin(GPIOD, LL_GPIO_PIN_12);
	}
	else if(Timer_flag == 2)
	{
		LL_GPIO_TogglePin(GPIOD, LL_GPIO_PIN_13);
	}
	else if(Timer_flag == 3)
	{
		LL_GPIO_TogglePin(GPIOD, LL_GPIO_PIN_14);
	}
	else if(Timer_flag == 4)
	{
		LL_GPIO_TogglePin(GPIOD, LL_GPIO_PIN_15);
		Timer_flag = 0;
	}
	LL_TIM_ClearFlag_UPDATE(TIM7);
  /* USER CODE END TIM7_IRQn 0 */
  /* USER CODE BEGIN TIM7_IRQn 1 */

  /* USER CODE END TIM7_IRQn 1 */
}

 

동작됨을 확인해보시기 바랍니다 ^^

반응형