이글의 전부 또는 일부, 사진, 소스프로그램 등은 저작자의 동의 없이는 상업적인 사용을 금지합니다. 또한, 비상업적인 목적이라하더라도 출처를 밝히지 않고 게시하는 것은 금지합니다.



전 글에 이어서 KCC426V와 ATtiny2313으로 FM radio 만들기를 계속합니다. 이번 글에서는 KCC426V radio에 부착한 엔코더의 push switch를 활용하는 방법을 탐구해 봅니다.

전자 기기들을 사용하다 보면 같은 버튼을 단순 click했을 때와 double click 했을 때 또는 길게 눌렀을 때에 각각 다른 역할을 하도록 하는 경우가 많습니다. 이 글에서도 엔코더의 push switch의 단순 click, double click, long click을 구분해서 각각 다른 용도로 활용할 수 있도록 하겠습니다. 본 글에서 구현한 논리는 어떤 자료를 보고 학습한 것이 아니라, 필자의 생각으로만 구현한 것이라서 일반적 방법이 아닐 수도 있다는 점을 참고해 주시기 바랍니다.

다음은 대략의 순서도입니다.

 

Click, Long Click , Double Click 구현 순서도

 


이 순서도에서는 push switch 처리를 인터럽트로 하지 않고 polling 방식으로 합니다. 위 순서도를 간단히 설명하면 다음과 같습니다.

1) 스위치가 눌렸는가? 안 눌렸으면 Encoder_sw에 0을 넣고 돌아감.
2) LongClickTime 이상 스위치를 누르고 있으면, Long Click으로 판단하고 스위치를 놓을 때까지 기다렸다가 종료

3) LongClickTime 이전에 스위치를 놓으면, DoubleClickTime 이전에 다시 스위치가 눌리면 Double Click으로 판단하고 스위치를 놓을 때까지 기다렸다가 종료

4) 3)단계에서 DoubleClickTime이 경과해도 스위치를 누르지 않으면 그냥 Click으로 판단하고 종료

 

위의 순서도에 따라 AVR 어셈블리어로 작성한 소스프로그램입니다.

대부분 순서도에 따라 프로그래밍 했으나, 함수명이나 변수명이 조금 다릅니다.

그래도 함수명이나 변수명을 보면 그 역할을 쉽게 알 수 있을 것이며, 간단히 주석도 달아 놓았습니다.

ENCODER_SW_PRESSED:
	LDS	AL,NO_CLICK
	SBIC	KCC426V_PIN,ENCODER_SW_BIT
	RJMP	ENCODER_SW_PRESSED_QUIT				// if SW released
	PUSH	AH
	PUSH	YL
	PUSH	YH
	PUSH	ZL
	PUSH	ZH
	LDI	AL,SHORT_CLICK
	LDI	YL,LOW(LONG_CLICK_TIME)
	LDI	YH,HIGH(LONG_CLICK_TIME)
	LDI	ZL,0									// ZH:ZL LapTIme = 0
	LDI	ZH,0
ENCODER_SW_PRESSED_WAIT_RELEASE1:
	SBIC	KCC426V_PIN,ENCODER_SW_BIT
	RJMP	ENCODER_SW_PRESSED_RELEASED1		// if SW released
	RCALL	DELAY_1MS							// Delay 1ms
	ADIW	Z,1									// LapTime += 1
	CP	ZL,YL
	CPC	ZH,YH
	BRLO	ENCODER_SW_PRESSED_WAIT_RELEASE1	// if LapTime < LongClickTime
	LDI	AL,LONG_CLICK
	RJMP	ENCODER_SW_PRESSED_WAIT_RELEASE_SAVE_SW
ENCODER_SW_PRESSED_RELEASED1:
	LDI	ZL,0
	LDI	ZH,0									// LapTime = 0
	LDI	YL,LOW(DOUBLE_CLICK_TIME)
	LDI	YH,HIGH(DOUBLE_CLICK_TIME)
ENCODER_SW_PRESSED_WAIT_DOUBLE:
	CP	ZL,YL
	CPC	ZH,YH
	BRSH	ENCODER_SW_PRESSED_SAVE_SW			// if LapTime >= DoubleClickTime
	RCALL	DELAY_1MS							// Delay 1ms
	ADIW	Z,1									// LapTime += 1
	SBIC	KCC426V_PIN,ENCODER_SW_BIT
	RJMP	ENCODER_SW_PRESSED_WAIT_DOUBLE		// if SW not pressed
	LDI	AL,DOUBLE_CLICK
ENCODER_SW_PRESSED_WAIT_RELEASE_SAVE_SW:
	SBIS	KCC426V_PIN,ENCODER_SW_BIT
	RJMP	ENCODER_SW_PRESSED_WAIT_RELEASE_SAVE_SW	// if SW not released
ENCODER_SW_PRESSED_SAVE_SW:
	POP	ZH
	POP	ZL
	POP	YH
	POP	YL
	POP	AH
ENCODER_SW_PRESSED_QUIT:
	STS	ENCODER_SWITCH,AL
	RET

ENCODER_SW_PRESSED 함수를 호출한 다음에 AL 값 또는 ENCODER_SWITCH 값을 읽어서 필요한 조치를 취하면됩니다.

 

지금까지 완성한 소스프로그램을 압축 파일 KCC426V_2313(1).zip을 첨부합니다.

압축 파일 안에 KCC426V_2313.asm, CLCD.asm, Delay8MHz.asm 등 3개의 소스프로그램들이 있습니다. 메인 프로그램은 KCC426V_2313.asm이고 나머지 두 프로그램은 파일명에서 알 수 있는 기능을 하는 루틴들을 담아 놨습니다.

 

KCC426V-2313.asm 안에 DO_ENCODER_SWITCH 함수 안에

DO_CLICK, DO_LONG_CLICK, DO_DOUBLE_CLICK에 각각의 클릭에 따라 원하는 동작을 하는 기능을 넣으면 됩니다.

예를 들어 단순 클릭시에는 현 주파수 값을 EEPROM에 기록하고, LONG_CLICK을 하면 방송을 검색하고, LONG_CLICK을 하면 메뉴를 표시하게 하는 등 다양하게 응용할 수 있습니다.

현재는 LCD 2행 1열에 CLICK시에는 문자 A, LONG CLICK시에는 문자 B, DOUBLE CLICK시에는 문자 C를 출력하도록 해 두었습니다.

KCC426V_2313(1).zip
0.01MB

블로그 이미지

엠쿠스

Microprocessor(STM32, AVR)로 무엇인가를 만들어 보고자 학습 중입니다.

,