Robot/임베디드

[STM32] Microsecond Delay 생성

interactics 2022. 2. 23. 20:41

HAL_Delay 함수는 최소 1ms만 지원한다.

따라서 이보다 더 작은 1ns 나 1us를 생성하기 위해서는 별도의 함수를 정의해야한다.

여기서는 타이머 기능을 이용하여 1us 딜레이 생성을 목표로 한다.

 

타이머 설정

어느 타이머를 설정할 것인가를 선정한다.

일단 timer1를 사용하기로 결정.

사진은 STM32F103의 다이어그램이다.

TIM1 은 APB2 블록에 연결된 것을 알 수 있다.

 

CUBE IDE에서 APB264의 클락은 64MHz 인 것을 확인할 수 있다.

TIMER1 은 64MHz로 설정되어있다는 뜻이다.

 

Pinout & Configuration에서 TIM1의 Clock Source를 Internal Clock으로 하여 내부 클락으로 변경한다.

 

 

 

 

64MHz는 64 x 10^6Hz이다. 따라서 1 ns를 생성하기 위해 Prescaler 분주비를 계산해야한다.

Prescaler는 타이머 클럭을 나눠준다. Prescaler와 Counter Period(ARR) 모두 0부터 시작한다. 따라서 -1을 해준다. 

 

Counter Period(ARR)는 가장 큰 값인 0xFFFF -1 == 65535로 설정하였다.

카운터는 기본적으로 0부터 카운팅을 한다. 매 카운트는 이제 1us마다 카운팅을 하게 된다.  

 

1us 딜레이 코드 생성하기

HAL_delay 코드는 다음과 같다.

__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

 

생성한 마이크로세컨트 함수는 다음과 같다.

void delay_us (uint16_t us)
{
	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
	while (__HAL_TIM_GET_COUNTER(&htim1) < us);  // wait for the counter to reach the us input in the parameter
}

해당 함수는

1. TIM1 카운터는 0부터 시작하도록 설정

2. 목표한 us 까지 카운팅을 하도록 설정

기능을 한다.

 

 

적용하면

HAL_TIM_Base_Start(&htim1);


while (1)
{  
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
    delay_us(5);
 }

 

 

 

오실로스코프 위와 같은 파형이 생성되는 것을 볼 수 있다.