[펌웨어] 폴링/인터럽트 버튼 & Delay

정재훈·2022년 4월 29일
0

FirmWare

목록 보기
3/7

폴링 방식 토글 버튼

설정

PA5 (내장 LED) : LD2 추가, GPIO Output
PC13 (내장 버튼) : B1 추가, GPIO Input
버튼은 Input Mode의 풀업으로 설정해준다.

코드

main.c의 while문에

while (1)
  {
	  int ret = HAL_GPIO_ReadPin(GPIOC, B1_Pin);

	  if (ret == 0) // 풀업이므로, 버튼 눌릴 때가 0
	  {
		  HAL_GPIO_TogglePin(GPIOA,LD2_Pin);
	  }
      HAL_Delay(100);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

인터럽트 방식 버튼

인터럽트란?

핀 번호에 최대 16 개 Interrupt Pin 으로 설정 가능
Interrupt PIN 들은 같은 PIN 번호를 가지면 안됨 ex) PA0 사용시 PB0 사용불가
포트마다 총 7개의 인터럽트를 사용할 수 있습니다.
0,1,2,3,4,[9:5],[15:10]이다. ex) PA5를 사용하면 PA9를 사용할 수 없다. 하지만 PB9는 사용가능하다.

NVIC

NVIC : 중첩 인터럽트시 우선순위 관한 인터럽트 지정, 우선순위를 CPU 대신 관리해주는 회로

우선순위가 같다면, 인터럽트가 발생되지 않고 먼저 실행되는 것부터 진행한다.

설정

PA5 (내장 LED) : LD2 추가, GPIO Output
PC13 (내장 버튼) : B1 추가, GPIO EXTI(인터럽트)
Rising Edge 및 내부 풀업으로 인터럽트 설정, NVIC도 Enable 시켜준다.

코드

stm~~_it.c 파일 중 EXTI15_10_IRQHandler 하단에

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (GPIO_Pin == GPIO_PIN_13)
	{
		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
	}
}

Delay 함수

Delay 함수에 Break Pointer(좌측 바 더블클릭)걸고 Trace를 해보자!
Trace : F5(함수 진입), F6(다음 브레이크 포인트로 이동), F7(함수에서 빠져나오기)

__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);
  }

# 현재 tick - 초기 tick이 설정한 delay 값보다 크면 끝
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

초기 셋팅을 하지 않고, 인터럽트 내부에 Delay함수를 사용하면 에러가 발생한다. 이는 tick의 우선순위가 15로 낮기 때문입니다. (우선순위 높음(0) ~ 우선순위 낮음(15)

따라서, 초기셋팅에서 우선순위를 다음 이미지와 같이 변경해줍니다.

그러면, 인터럽트 내부에 위치해있는 tick 함수가 정상 작동합니다.

인터럽트에 Delay 함수 사용하기

main.c 내부 : 터미널에 # 반복 찍기

uint8_t buf[10] = "#";
  while (1)
  {
	  HAL_UART_Transmit(&huart2, buf, 10, 100); 
	  HAL_Delay(100);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

stm_it.c : 인터럽트 핸들러 밑에

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (GPIO_Pin == GPIO_PIN_13)
	{
		HAL_Delay(3000);   // 초기설정시 사용가능한 Delay 함수

		// 초기 설정하지 않을시 for문을 사용한 Delay
		for(int j=0; j<2; j++)
		{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);
		for(int i=0; i<100000; i++);
			HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
		for(int i=0; i<100000; i++);
		}
	}
}

채터링

하드웨어적 / 소프트웨어적으로 버튼떨림 현상을 방지한다.

profile
여러 방향으로 접근하는 개발자

0개의 댓글