HBE-MCU-All in One 에서 '블럭 피하기 게임'을 구현하였고, 그를 동영상 촬영하였습니다.






블럭 피하기 게임(부제: 미니언 러쉬)


사용한 모듈: 2x16 Text LCD, 2Color DotMatrix, Push Button, Piezo


1) 밑에 초록색 바가 움직이게 하여 내려오는 빨간색 블럭을 피하게 함. 

2) 초록색 바에는 '점프' 기능이 있음. 점프 기능을 이용해서 빨간색 블럭을 피하는 것도 가능함.

(점프하고 있는 중이면 주황색으로 바뀌게 됨. 실제로 초록색+빨간색 = 주황색이 되므로, 그냥 점프하는 모습도 주황색으로 보여지고, 빨간색 블럭들을 넘어서 점프하고 있는 모습도 주황색으로 보이게 됨.)

3) 시간이 지남에 따라 레벨이 오르고 점수도 오르게 됨. 레벨이 오를 수록 내려오는 빨간 블럭의 속도나 숫자도 더 많아짐.

4) 빨간 블럭과 부딪혀서 죽게 되는 경우, 2Color DotMatrix 모듈이 전체 빨간색으로 점멸하게 되며 실패 음악이 나옴.

5) 중간에 Pause를 누르게 되면 2Color DotMatrix 모듈이 전체 주황색으로 표시됨. 


※ 특이사항


1) 버튼들을 누르거나 특정 액션에 대해서 소리를 낼 수 있도록 Piezo 모듈을 사용함.

2) 블럭 피하기 게임에서 '점프' 기능을 구현.


이전에 동영상으로 소개를 드린 비밀번호 시스템 만들기 소스 코드를 공개합니다.

EEPROM을 사용하여 비밀번호를 저장하고,

비밀번호를 확인하는 간단한 MCU 시스템을 만들게 한 c 소스 코드입니다.


#include <avr/io.h> #include <avr/interrupt.h> #include <avr/eeprom.h> // for eeprom #include "EEPROM.h" int main(void) { unsigned char password[4]; unsigned char input[4]; unsigned char i=0; int check = 0; int step = 0; int count = 0; DDRB = 0xFF; DDRG = 0xFF; DDRF = 0x00; DDRE = 0xFF; PORTB = 0x00; PORTG = 0xFF; Init_Timer(); sei(); // 제일 처음에는 FND에 아무것도 표시되지 않는다. digit3=digit2=digit1=digit0=16; while(1) { if(KeyPressed) { KeyPressed = FALSE; switch(key) { case 0x0A: // * 키 // 비밀번호 입력 부분. step = 2; count = 0; digit3=digit2=digit1=digit0=3; // 3333 표시. break; case 0x0C: // # 키 // 비밀번호 설정 부분. step = 1; // 비밀번호 설정 시작! if(check == 0) { digit3=digit2=digit1=digit0=0; // 0000 표시 check = 1; // check가 1이어야 입력 받기 가능. } // 비밀번호 설정이 종료. else { digit3=digit2=digit1=digit0=2; // 2222 표시. /* Write password to eeprom */ write_eeprom(0, password[0]); write_eeprom(1, password[1]); write_eeprom(2, password[2]); write_eeprom(3, password[3]); check = 0; } break; default: // *,# 키 말고 일반 숫자키를 누르는 경우 if(step == 1 && check==1) // 비밀번호 설정시 입력 { password[3] = password[2]; password[2] = password[1]; password[1] = password[0]; password[0] = key; digit3 = digit2; digit2 = digit1; digit1 = digit0; digit0 = 1; } else if(step == 2) // 비밀번호 체크시 입력 { count ++; input[3] = input[2]; input[2] = input[1]; input[1] = input[0]; input[0] = key; if(count == 4) // 4번 눌렀을 때, 비밀번호 체크. { count = 0; // EEPROM에 저장된 비밀번호를 불러옴. for(i=0; i<4; i++) password[i] = read_eeprom(i); /* 이 strcmp는 제가 직접 만든 함수입니다. * 같으면 TRUE를 반환 합니다. */ if(strcmp(input, password)) // 문을 여는 데 성공. digit3=digit2=digit1=digit0=7; // 7777 표시. else // 문을 여는 데 실패. digit3=digit2=digit1=digit0=4; // 4444 표시. } } break; } // switch(key) end } // if(KeyPressed) end } // Infinite loop end. }


EEPROM 기능을 이용해서 구현한 Door Lock 구현 동영상입니다.


선명하게 보이지는 않는데, FND Display 에 숫자가 바뀌어 출력되는 정도는 확인하실 수 있으실 거라고 생각합니다.


아쉽게도 폰에서 찍은 동영상이 왼쪽으로 회전되어서 저장이 되었네요;;;


물론 동영상 인코딩으로 다시 재회전시키는 방법도 있지만... 귀찮아서 ^^;;


다음에 기회가 되면 다시 올리도록 하겠습니다.





영상만 보면 상황이 잘 이해 안갈 수도 있어서 부가 설명을 덧 붙이자면,


1) #키를 눌러서 비밀번호를 설정

2) *키를 눌러서 비밀번호 입력-> 맞으면 7777 틀리면 4444


제일 처음 #키 누르고 1234 입력해 비밀번호 1234로 설정 (비밀번호 입력중에는

어떤 숫자인지 알지 못하게 1이 계속해서 뜹니다. 그리고 비밀 번호 설정 후엔 2222가 뜹니다.)


그 후 *키를 누릅니다. 그러면 3333이 뜹니다. 그리고 1234를 순서대로 누르면 맞다고 7777이 뜨고,

다른 숫자(4444)를 누르면 틀렸다고 4444가 뜹니다.


CPU 리셋 이후에 다시 * 키를 눌러서 1234를 눌러도 그대로 맞다고 7777을 띄우는 것을 보면,

EEPROM에 정확하게 비밀번호가 저장되었음을 확인할 수 있습니다.



HBE-MCU-All in One 키트에는 'Push Button'과 'LED' 에 대한 포트가 있습니다.

이번 포스팅에서는 Push Button 을 누를 때마다 LED가 다양하게 제어되는 형태의 프로그램에 대한 코드를

설명하려고 합니다. 각각 Push Button 에 대해서 LED는 다음과 같은 반응을 보일 수 있습니다.


그리고 소스 코드는 다음과 같습니다.


#include <avr/io.h> void my_delay(unsigned long x) { while(x--); } int main(void) { int i; unsigned char state, tmp; /* Push Button - 포트 D */ DDRD = 0x00; // 입력 /* LED - 포트 B */ DDRB = 0xFF; // 출력 while(1) { state = PIND; switch(state) { case 0x01: // 0번 버튼 PORTB = 0xFF; // 모든 LED가 켜진다. break; case 0x02: // 1번 버튼 PORTB = 0xAA; // 짝수번째 LED가 켜진다. break; case 0x04: // 2번 버튼 PORTB = 0x55; // 홀수번째 LED가 켜진다. break; case 0x08: // 3번 버튼 // 다른 스위치가 눌릴때까지 모든 LED를 깜빡인다. while(1) { PORTB = 0x00; // 모든 LED 꺼진다. my_delay(50000); if(PIND != 0x08 && PIND != 0x00) // 다른 스위치가 눌리는지 확인. break; PORTB = 0xFF; // 모든 LED 켜진다. my_delay(50000); if(PIND != 0x08 && PIND != 0x000) break; } break; case 0x10: // 4번 버튼 // 다른 스위치가 눌릴때까지 LED 1개 켜서 좌로 이동 while(1) { tmp = 128; for(i=0; i<8; i++) { PORTB = tmp; tmp = tmp >> 1; my_delay(50000); if(PIND != 0x10 && PIND != 0x00)// 다른 스위치가 눌리는지 확인. goto Finish1; } PORTB = 0x00; } Finish1: break; case 0x20: // 5번 버튼 // 다른 스위치가 눌릴때까지 LED 1개 켜서 좌로 이동 while(1) { tmp = 1; for(i=0; i<8; i++) { PORTB = tmp; tmp = tmp << 1; my_delay(50000); if(PIND != 0x20 && PIND != 0x00)// 다른 스위치가 눌리는지 확인. goto Finish2; } PORTB = 0x00; } Finish2: break; case 0x40: // 6번 버튼 PORTB = 0xF0; // 상위 4비트(LED4~LED7)만 켠다. break; case 0x80: // 7번 버튼 PORTB = 0x0F; // 하위 4비트(LED0~LED3)만 켠다. break; default: // 아무런 버튼도 누르지 않은 경우. PORTB = 0x00; // 모든 LED가 꺼진다. } } }


다음은 각각 결과에 대한 사진입니다.



▲ 0번 버튼을 누른 경우, LED가 전부 켜진다.


▲ 1번 버튼을 누른 경우, LED가 짝수 번째만 켜진다.


▲ 2번 버튼을 누른 경우, LED가 홀수 번째만 켜진다.


▲ 3번 버튼을 누른 경우, LED가 깜빡인다.


▲ 4번 버튼을 누른 경우, LED가 1개씩만 좌로 이동한다.


▲ 5번 버튼을 누른 경우, LED가 1개씩만 우로 이동한다.


▲ 6번 버튼을 누른 경우, LED가 상위 4비트(LED4~LED7)만 켜진다.


▲ 7번 버튼을 누른 경우, LED가 하위 4비트(LED0~LED3)만 켜진다.


#include <avr/io.h>

void my_delay(unsigned long x)		// 시간 딜레이 함수.
{
	while(--x);
}

// 포트 B 8개는 LED0~7까지,
// 포트 D 8개는 LED8~15까지 연결한 상태입니다.
int main(void){

	int i;
	unsigned char tmp;
	
	DDRB = 0xFF;
	DDRD = 0xFF;

	while(1){

		tmp=1;
		/* [포트 B] LED 윗 줄(LED0~LED7)에 대한 반복문 */
		for(i=0;i<8;i++)
		{	
			PORTB = tmp;
			tmp = tmp << 1;
			my_delay(500000);
		}
		PORTB = 0x00;		// LED7 끄기 위함.

		/* [포트 D] LED 아랫 줄(LED8~LED15)에 대한 반복문 */
		tmp=1;
		for(i=0;i<8;i++)
		{	
			PORTD = tmp;
			tmp = tmp << 1;
			my_delay(500000);
		}
		PORTD = 0x00;		// LED15 끄기 위함.
	}
	return 0;
}


위 소스 코드는 HBE-MCU-AllinOne 보드에 있는 LED 16개 (LED0~LED15) 를 순차적으로 켤 수 있도록 만든 코드입니다. 크게 어려운 부분이 없으므로 설명은 생략하겠습니다.



▲ LED 포트가 하나씩 불이 들어오는 모습


각 LED 포트 하나씩 불들어오는 거 다 찍었으면 더 예뻤을 텐데 시간이 없었네요 ㅎㅎㅎ;;;


p.s 궁금한 점 있으면 댓글이나 이메일 보내주시면 감사하겠습니다 ^^ :)

+ Recent posts