본문 바로가기
하만 세미콘 아카데미/Embedded (STM32)

[Embedded] STM32 - US Interrupt

by smileww 2024. 5. 31.

이전 글에서 초음파 센서를 GPIO로 통제했다면 이번에는 Interrupt를 이용하여 센서를 동작시켜보도록 하겠습니다.

 

트리거 & 에코에 대한 설명은 이전 글을 참고해주시길 바랍니다.

https://engineeringstudentww.tistory.com/36

 

[Embedded] STM32 - US GPIO

이번에는 초음파 센서를 이용하여 거리를 측정하는 코드를 GPIO를 사용하여 만들어보도록 하겠습니다.  트리거 & 에코 신호 트리거 신호 (Initiate)센서에는 일반적으로 TTL(Transistor-Transistor Logic)

engineeringstudentww.tistory.com

 

 

먼저 새 프로젝트를 생성합니다. 그 다음 핀을 설정해주도록 하겠습니다.

 

 

 

 

PB5 신호, 트리거 신호는 출력 모드로 설정합니다.

 

PB4 신호에서 GPIO 모드를 외부 인터럽트 모드로 설정하여 상승 에지와 하강 에지 모두에서 트리거될 수 있도록 설정합니다. 이 설정은 에코 신호의 시작과 끝을 감지하는 데 사용되며, 이를 통해 센서가 물체까지의 거리를 계산할 수 있도록 합니다.

 

 

 

 

타이머3을 활성화 합니다. Internal Clock을 체크하여 타이머의 클록 소스로 내부 클록을 사용하고 채널은 모두 Disable 하여 독립적으로 작동시킵니다.

 

Prescaler를 560으로 나누고 카운터의 최대 값을 10000-1로 설정하여 오버플로우 주기를 결정합니다. TIM3 타이머 관련 글로벌 인터럽트를 활성화 시켜 타이머의 오버플로우, 이벤트 업데이트 등에 대응하도록 합니다.

 

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void microDelay(int us)
{
	/*int t1 = htim5.Instance->CNT;
	//while(1)
	//{
	//	int tmp_us = htim5.Instance->CNT - t1; // 경과?���????????
	//	if(tmp_us > us) break;
	//}
	while((htim5.Instance->CNT - t1) < us);*/

	htim5.Instance->CNT = 0;
	while(htim5.Instance->CNT < us);
}

void Trigger()
{
	// Trigger Signal
	HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, 1);
	microDelay(10);  // 10us delay
	HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, 0);
	microDelay(20);  // 20us delay
}

int ts = 0;
double dist = 0.0;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == Echo_Pin)
	{
		int tt = htim5.Instance->CNT;  // micro count

		if(HAL_GPIO_ReadPin(Echo_GPIO_Port, Echo_Pin) == 1) //rising edge
			ts = tt;
		else
			dist = (tt - ts) * (0.000170); // meter
	}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim3)  // htim3 ISR
	{
		Trigger();
	}
}

/* USER CODE END 0 */

 

 

microDelay 함수

  • 기능: 지정된 마이크로초(us) 동안 지연(delay)을 생성합니다.
  • 동작: htim5의 카운터를 0으로 설정하고, 지정된 us 값에 도달할 때까지 대기합니다. 이는 매우 정밀한 짧은 지연 시간을 필요로 하는 작업에 유용합니다.

Trigger 함수

  • 기능: 초음파 센서를 활성화하기 위해 트리거 핀에 짧은 전기 신호를 전송합니다.
  • 동작: Trig_GPIO_Port의 Trig_Pin을 high로 설정한 다음 10마이크로초 동안 유지합니다. 이후 핀을 low로 다시 설정하고 추가로 20마이크로초 동안 대기합니다. 이 과정은 센서에게 초음파 펄스를 발생시키라는 명령을 내리는 방식입니다.

HAL_GPIO_EXTI_Callback 함수

  • 기능: 외부 인터럽트 콜백 함수로, 특정 GPIO 핀의 상태 변경(예: Echo 핀)을 감지합니다.
  • 동작:
    • Echo 핀에서 상승 에지(rising edge)가 감지되면 현재 타이머 값(htim5.Instance->CNT)을 시작 시간 ts로 저장합니다.
    • 하강 에지(falling edge)에서는 시작 시간 ts와 현재 타이머 값을 이용하여 초음파가 이동한 시간을 계산하고, 이를 거리로 변환하여 dist에 저장합니다.

4. HAL_TIM_PeriodElapsedCallback 함수

  • 기능: 타이머 인터럽트 서비스 루틴(ISR)으로, htim3 타이머가 설정된 주기마다 호출됩니다.
  • 동작: 이 콜백에서 Trigger() 함수를 호출하여 정기적으로 초음파 센서를 활성화합니다. 이는 지속적인 거리 측정을 가능하게 합니다.

 

하드웨어 타이머를 활용하여 초음파 센서의 트리거링과 에코 신호 감지를 통해 정밀한 거리 측정을 수행합니다. GPIO 인터럽트를 사용하여 에코 신호의 상승 및 하강 에지를 효과적으로 감지하고, 타이머를 사용하여 이벤트 발생 시간을 정확하게 기록합니다. 결과적으로 이 시스템은 연속적인 환경에서 물체와의 거리를 실시간으로 모니터링 할 수 있습니다.

 

 

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_USART2_UART_Init();
  MX_TIM3_Init();
  MX_TIM5_Init();
  /* USER CODE BEGIN 2 */

  printf("i:%d l:%d f:%d d:%d\n",sizeof(int),sizeof(long),sizeof(float),sizeof(double));
  ProgramStart("Ultra Sonic using Interrupt");
  HAL_TIM_Base_Start(&htim5);
  HAL_TIM_Base_Start_IT(&htim3);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	  double d = dist*100;//Distance();
	  //printf("\033[2J");		// screen clear
	  //printf("\033[?25l");	// cursor off
	  //printf("\033[?25h");	// cursor on
	  //printf("\033[A");		// cursor up
	  //printf("\033#3");		// double size string upper half
	  //printf("\033#4");		// double size string lower half
	  printf("\033[10;10H\033#3Distance : %.2f cm    ", d);
	  printf("\033[11;10H\033#4Distance : %.2f cm    \033[9;10H\n", d);
	  //microDelay(100000); // 10ms
	  HAL_Delay(100);
  }
  /* USER CODE END 3 */
}

 

HAL_Init(), SystemClock_Config(), GPIO, USART, TIM3, TIM5 등을 구성하고 초기화 작업을 코드에서 먼저 진행합니다. HAL_TIM_Base_Start(&htim5) 코드로 타이머5를 실행하고, HAL_TIM_Base_Start_IT(&htim3) 코드로 TIM3 타이머의 인터럽트를 활성화하여, 설정된 주기마다 HAL_TIM_PeriodElapsedCallback 콜백 함수를 호출하게 합니다.

 

거리 값을 계산하여, ANSI 이스케이프 코드를 사용해 터미널의 특정 위치에 거리를 출력합니다.

 

\033[10;10H\033#3 및 \033[11;10H\033#4는 커서를 화면의 지정된 위치로 이동시키고 텍스트 크기를 조절하는 데 사용됩니다.

 

이 출력은 실시간으로 업데이트되며, HAL_Delay(100);를 사용하여 매 100ms마다 화면을 업데이트합니다.

 

보드와 연결 후 터미널에서 테스트 결과를 확인하도록 합니다.

 

 

 

'하만 세미콘 아카데미 > Embedded (STM32)' 카테고리의 다른 글

[Embedded] STM32 - ADC - 1  (0) 2024.05.31
[Embedded] STM32 - US PWM  (0) 2024.05.31
[Embedded] STM32 - US GPIO  (0) 2024.05.31
[Embedded] STM32 - PWM  (0) 2024.05.31
[Embedded] STM32 - Timer  (0) 2024.05.31