[STM32] TIM_Interrupt

myblack·2024년 8월 13일
0

STM32

목록 보기
3/8

Interrupt

인터럽트 이론

인터럽트는 CPU가 프로그램을 실행하고 있을 때,
입출력 하드웨어 등의 장치나 또는 예외상황이 발생해서 처리가 필요할 경우에 CPU에 알려서 처리하는 기술이다. 

인터럽트는 내부 인터럽트와 외부 인터럽트로 나눌 수 있다.

1. 내부 인터럽트
: 주로 프로그램 내부에서 잘못된 명령 또는 잘못된 데이터 사용시 발생
(예를 들어, 0으로 나눴을 경우/사용자 모드에서 허용되지 않은 명령 또는 공간 접근 시/계산 결과가 Overflow/Underflow가 나는경우)

2. 외부 인터럽트
: 입출력 장치, 타이밍 장치, 전원 등의 외부적인 요인에 의해서 발생하는 인터럽트/주로 하드웨어에서 발생
(예를 들어, 전원 이상/기계 문제/키보드 등 I/O 관련 이벤트/Timer 이벤트)

인터럽트의 종류

    1. Program Interrupt는 오버플로우가 발생한 경우, 0으로 나눈 경우, 명령어가 잘못된 경우에 발생
    1. Hardware failure Interrupt는 하드웨어 장치의 문제 있을 때 발생
      => 이 두 가지의 경우는 어떤 종류든 문제가 있을 때 발생하는 인터럽트이다.
    1. Timer Interrupt는 프로그램을 병렬적으로 실행시키기 위해 사용된다. 프로세스들을 조금씩 돌아가면서 실행시키고, 조금씩 실행시키는 시간을 Timer로 계산해서 그만큼씩 CPU가 일을 한다. 
    1. I/O Interrupt는 인터럽트 중에서 가장 중요하다.
      I/O Interrupt가 있는 이유는 CPU와 I/O 장치의 속도차이 때문이다. CPU는 매우 빠르다. 하지만 I/O장치는 그에 비해 현저히 느리다. 따라서 I/O Interrupt가 필요하다.

Timer & Clock 이론

Timer 기본 설정

  • 설정 전에 기존의 HCLK 값 확인 ex : 100MHz

  • TIM7 활성화함 (TIM7 Activated)

  • Prescaler와 Auto-Reload 값을 변경함
    (ex : Prescaler: 4999 Auto-Reload : 4999)

  • -1 한 이유는 카운터가 0부터 세기 때문이다. 8999 대신 9000-1 이런식으로 적어두면 더 직관적이다.

Prescaler는 분주비로 타이머 클럭을 나눠주는데 사용됩니다.
( max 2^16 - 1 까지)

Counter Period는 주기를 정하는데 사용됩니다.

Prescaler , Counter Period는 모두 0부터 시작하기 때문에 설정한 값에 -1을 해줍니다.

ARRAuto Reload Register의 약자로 Counter Register의 값이 ARR과 동일해질때, Update Interrupt가 발생한다. (Period 라고도 한다.)

HCLK = 168MHZ
APB1 TIM CLK = HCLK / 2 = 84MHz
APB2 TIM CLK = HCLK = 168MHZ
즉 한번 올라가는데 1 / 84,000,000[s]

한번 증가할때 다음과 같이 설정 할 수 있음

TIM CLK = APM1 TIM CLK / Prescaler
ex) Prescaler를 10,000으로 하게 되면
TIM CLK는 1 / 8400 이 됨. 한번 증가할 때 1 / 8400 [s]

이때 Auto Reload Register를 8400으로 하면 8400번 증가 할때
인터럽트가 1번 발생함. 계산하면 1초에 1번 인터럽트가 발생함.

Counter Register값이 1증가하는데 걸리는 시간

정리하면 PWM의 주파수는 ((Internal Clock)/(Prescaler + 1)) / (Period=ARR)로 계산되며, DutyCycle(%)은 (Pulse)/(Period)*100으로 계산된다.

소스코드

  • TIM7_IRQHandler -> HAL_TIM_IRQHandler -> HAL_TIM_PeriodElapsedCallback

  • TIM7은 APB1 Bus를 이용

static void MX_TIM7_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 9999;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = 8399;
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}
MX_TIM7_Init();	//타이머 초기화
HAL_TIM_Base_Start_IT(&htim7);	//타이머 인터럽트 활성화


// 1초마다 LED 토글
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM7)
	{
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
	}
}

Ref
https://bo5mi.tistory.com/169
https://louie0724.tistory.com/359
https://velog.io/@sang_yun_911/STM32-TIMInterrupt
https://velog.io/@sang_yun_911/STM32-TIMInterrupt2
https://www.youtube.com/watch?v=GtpHPYGYGNo&list=PLUaCOzp6U-RqMo-QEJQOkVOl1Us8BNgXk&index=8
https://eteo.tistory.com/73

profile
기록과 분석, 이해

0개의 댓글