[ARM] 블루투스 알람시계_2 [EXTI / UART]

2022. 7. 20. 16:48ARM/[Project]블루투스 알람시계

Nucleo 보드의 유저 버튼에 외부인터럽트를 적용하여 사용할 생각이다.

 

생각중인 알람시계는 LCD에서 출력해야 할 부분은 3가지가 있다.

 

각 부분은 지연변수(flag)를 만들어서 값에 따라  LCD 화면에 표시되게 할 생각이다.

 

flag 1.  시간 표시

flag 2. 시간 셋팅

flag 3. 알람 설정

 

또한 2,3번은 화면에 출력된 정보가 1번 화면으로 적용되게 해야한다.

따라서 Nucleo 보드의 유저 버튼이 짧게 클릭이 되면 flag값을 변경시키고

길게 클릭이 되면 LCD 화면에 출력된 정보가 저장되게 할 생각이다.

 

#define LONG_CLICK_MIN 700

typedef struct {
	int time;
	uint8_t level;
} ClickInfoDef;

uint8_t flag;
uint8_t longClick = 0;
ClickInfoDef click[3];

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
	GPIO_PinState pin;

	if (GPIO_Pin == GPIO_PIN_13) {
		current_time = HAL_GetTick();
		time_interval = current_time - last_time;
		last_time = current_time;

		pin = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13);

		if (time_interval <= 4) {
			printf("Noise %d, %d\r\n", pin, time_interval);
		} else {

			click[1].time = click[0].time;
			click[1].level = click[0].level;

			click[0].time = time_interval;
			click[0].level = pin;
		}
         // long click
		if (click[0].level == GPIO_PIN_RESET && click[0].time >= LONG_CLICK_MIN)
		{
			printf("\r\nLong Key\r\n");
			longClick = 1;

		} else if (click[0].level == GPIO_PIN_RESET
				&& click[1].level == GPIO_PIN_SET) {
			printf("\r\nSelect Key, %d\r\n", click[0].time);
			flag++;
		}
	}
}

 

블루투스 알람시계_1 [IOC설정]  글에서 외부인터럽트를 상승과 하강 모두 검출하도록 설정하였기 때문에

HAL_GetTick(); 함수와 조합하여 롱클릭과 짧은 클릭을 구분할 수 있게 작성할 수 있었다.

그리고 노이즈로 인해 버튼이 중복해서 동작하는 경우가 있는데 이 경우를 막기위해서 

시간 간격이 너무 짧을 경우 동작하지 않도록 작성하였다.

 

longClick 변수는 1이면 값을 저장하고 0이면 저장하지 않도록 하기 위해서 추가하였다.

지금와서 생각하지만 자료형 bool을 이용해서 작성했으면 싶다.

 

 

위의 코드에는 클릭 값이 정상적으로 나오는지 확인하기 위해서 printf 함수를 사용하였다.

STMCUBEIDE에서 그냥 printf 함수를 사용할 수 없다.

나는 UART와 __io_putchar 함수를 이용해서 printf 함수를 사용하였다.

 

int __io_putchar(int ch) {
	HAL_UART_Transmit(&huart3, (uint8_t*) &ch, 1, 100);
	return ch;
}

main함수 위에 해당 코드를 사용하면 된다.