본문 바로가기

MCU 제어/STM32Cube Mx

[STM32] Basic Timer

Basic Timer를 이용해 1초에 한 번씩 UART로 문자열 출력하기

드론을 개발할 때, 일정시간마다 자세센서의 값을 읽어오거나 PID계산을 해야한다. 어떻게 시간을 잴 수 있을까? Basic Timer를 이용하면 된다.

 

stm32의 타이머 종류에는 크게 Advanced-control timer, General purpose timer, Basic Timer가 있다. 오늘은 DAC 트리거  및 시간 기반 타이머로 사용되는 Basic Timer를 사용해보겠다.

STM32F767zi의 Timer feature

위 데이터 시트를 보면 Basic Timer는 TIM6, TIM7으로 사용할 수 있다는걸 알 수 있다.

그리고 사용하는 클럭을 알아야한다. TIM6는 APB1 timer clock을 사용하고 Cube MX 툴에서 108MHz라는 걸 알 수 있다.

TIM6 설정

TIM6를 활성화하고 설정(Counter Setting)을 해준다. 설정할 때 값을 1씩 빼서 넣어줘야한다.

108,000,000/10800(prescaler) = 10,000

10,000/10,000(Counter Period) = 1Hz

즉, Counter가 계속 증가하다가(0~period) 1초에 한 번씩 오버플로우가 일어나며 인터럽트가 발생하고 Counter는 0으로 초기화된다.

 

꼭 global interrupt를 enable해준다.

코딩

HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)

- 타이머 인터럽트를 시작한다.

 

void TIM6_IRQHandler()

- 인터럽트 핸들러

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

- 타이머 콜백함수

 

main.c
///////////////
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

  if(htim->Instance == htim6.Instance)   //Go to definition of 'TIM_HandleTypeDef'를 통해 구조체를 확인해보자!

    HAL_UART_Transmit(&huart1, "Hello, World!\r\n", 17, 1000);  //인터럽트 발생할 때 마다 문자열 출력
 

}

int main()
{
  HAL_TIM_Base_Start_IT(&htim6); //TIM6의 타이머 인터럽트를 시작한다.
 
  while(1)
  {
  }
}

콜백함수에는 TIM6뿐만 아니라 다른 종류의 타이머도 인터럽트가 발생할 경우 호출되므로 if문을 통해 현재 어떤 타이머의 인터럽트가 발생했는지 확인해야한다.

 

콜백함수는 stm32Fxx_hal_tim.c 파일에 weak함수로 정의되어있으므로 복사하여 non-weak함수로 main.c 파일에 정의해주었다. TIM6_DAC_IRQHandler()에서  처리해줄 수도 있다. IRQHandler는 stm32Fxx_it.c 파일에 정의되어있다.

 

방법만 알면 매우 간단하다. 다음에는 타이머를 이용해 PWM파형을 발생시키는걸 해보겠다.

잘못설명했거나 궁금하신거 있으시면 댓글 남겨주세요.