[STM32] Microsecond Delay 생성
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);
}
오실로스코프 위와 같은 파형이 생성되는 것을 볼 수 있다.