-두더지게임-
-두더지게임 ATMEGA 부분-
==================================================================
==========================사진====================================
==================================================================
====================================================================
===============================소스=================================
====================================================================
#include<avr/io.h>
#include<avr/signal.h>
#include<avr/interrupt.h>
#include<stdlib.h>
#define CPU_CLOCK 16000000 //CPU clock=16000000Hz
#define TICKS_PER_SEC 1000 //Ticks per sec =1000
#define PRESCALER 128 //클럭의 배수
#define BAUD_RATE 19200 //통신시 이용할 속도
#define BAUD_RATE_L (CPU_CLOCK/(16l*BAUD_RATE))-1
#define BAUD_RATE_H ((CPU_CLOCK/(16l*BAUD_RATE))-1)>>8
unsigned char USART_Receive(void); //recv설정
void Protocall(void); //직렬포트설정
volatile unsigned int g_elapsed_time; //시간변수
unsigned char Pnum; //PINC 번호
void uart_send_byte(unsigned char byte); // send설정
void intiLED(void); //LED초기화
void setTCCR0(void); //TCCR0설정
void initTCNT0(void); //TCNT0초기화
void setTIMSK(void); //TIMSK 설정
void sleep(unsigned int elapsed_time); //1/1000초대기
SIGNAL(SIG_OVERFLOW0); //timer0의 오버플로우 함수
unsigned char USART_Receive(void) //recv설정
{
while(!(UCSR1A&(1<<RXC))); //UCSR1A 7번비트가 1될때까지 계속 봄
return UDR1; //1이되면 return UDR1의 수신확인
}
void Protocall(void) //직렬통신설정
{
UBRR1L = (unsigned char)BAUD_RATE_L; //baud rate 설정
UBRR1H =(unsigned char)BAUD_RATE_H;
//parity설정 1stop bit설정,문자사이즈 8bit 설정
UCSR1C=(0<<UPM1)|(0<<UPM0)|(0<<USBS)|
(1<<UCSZ1)|(1<<UCSZ0);
//송신수신 interrupt설정(PORTD27번28번사용), 문자사이즈 8bit설정
UCSR1B=(1<<TXEN)|(1<<RXEN)|(0<<UCSZ2);
}
void uart_send_byte(unsigned char byte) //send설정
{
while(!(UCSR1A&(1<<UDRE))); //UCSR1A의 5번비트가 1될때까지 대기
UDR1=byte ; //1이되면 1byte 크기만큼 송신
}
void intiLED(void) //각각의 포트 입출력모드 설정/초기화
{
DDRF=0xFF;
PORTF=0xFF;
DDRC=0x00;
DDRE=0xFF;
PORTF=0x00;
}
void setTCCR0(void) //클럭의배율 등 설정
{
TCCR0=(TCCR0|(1<<2));
TCCR0=(TCCR0|(1<<0));
TCCR0=(TCCR0&(~(1<<1)));
}
void initTCNT0(void)
{
TCNT0 =256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER); //TCNT0로 오버플로우할 초기값설정
}
void setTIMSK(void) //사용할인터럽터 설정(오버플로우인터럽터사용)
{
TIMSK=(TIMSK)|(1<<0);
}
void sleep(unsigned int elapsed_time) //오버플로우로 증가된 g_elapsed_time를
{ //1/1000로 생성되어서 시간조절가능함수
g_elapsed_time=0;
while(g_elapsed_time<elapsed_time);
}
SIGNAL(SIG_OVERFLOW0) //오버플로우인터럽터생성이 진입
{
initTCNT0();
g_elapsed_time++;
}
int main()
{
unsigned char j; //게임 5번할 횟수
unsigned char fnd1=0x00; //FND의 값 변수
unsigned char cnt; //LED값 수신
unsigned char recvcnt; //switch와 led가 같은지 수신
unsigned char ch=0; //시작할 문자수신
Protocall(); //직렬통신
intiLED(); //각각의 포트 입출력모드 설정/초기화
setTCCR0(); //클럭의배율 설정
initTCNT0(); //TCNT0로 오버플로우할 초기값설정
setTIMSK(); //사용할인터럽터 설정(오버플로우인터럽터사용)
SREG=0x80; //인터럽터 사용초기화
ch=USART_Receive(); //수신된 내용을 ch에 저장
while(1)
{
if('y'==ch) //ch의값이 y이면 시작
{
PORTE=0x00; //FND초기값 00 출력
fnd1=0x00; //fnd1의 초기값 00입력
PORTF=0x00; //LED를 전부켜는 초기화
for(j=0;5>j;++j) //게임횟수를 5번으로 설정
{
cnt=USART_Receive(); //LED 값을 recv
PORTF=cnt; //recv한 LED값을 출력
sleep(800); //0.8초 대기
recvcnt=255-PINC; //누른 switch값을 recvcnt에 대입
uart_send_byte(recvcnt); //recvcnt값을 전송
recvcnt=USART_Receive(); //다시 LED와 switch값이 같은지아닌지 recv
if(recvcnt=='x') //같다면 x를 받음
{
if(fnd1&0x0a==0x0a) //FND1의값이 10되면 16진수이기때문에
{ //0A가 나온다 그래서 5~10~15~20씩올라가게증가
fnd1=fnd1+6;
}
fnd1=fnd1+0x05;
PORTE=fnd1;
}
else
{
PORTE=fnd1; //같지않으면 그냥 이전값 출력
}
PORTF=0xFF; //LED켠후 잠시 0.2초당안 점등
sleep(200);
}
if('A'==USART_Receive()) //5번전부다 맞추게 되면 LED 켜기 끄기 반복
{
PORTF=0xFF;
sleep(500);
PORTF=0x00;
sleep(500);
PORTF=0xFF;
sleep(500);
PORTF=0x00;
sleep(500);
PORTF=0xFF;
sleep(500);
PORTF=0x00;
sleep(500);
PORTF=0xFF;
sleep(500);
PORTF=0x00;
sleep(500);
PORTF=0xFF;
}
}
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
송수신할 C모드
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
int main()
{
FILE *OPEN; //FILE입출력 설정
char szPort[15]; //포트명을 저장할 변수
wsprintf(szPort,"COM%d",1); //포트 2번으로 통신
HANDLE m_hComn =NULL; //HANDLE생성후 초기값 NULL
m_hComn = CreateFile(szPort,GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hComn==INVALID_HANDLE_VALUE) //포트접속실패시 에러
{
printf("(!) Failed to create a Comm Device file \n");
return FALSE;
}
DCB dcb; //DCB 구조체생성
dcb.DCBlength=sizeof(DCB); //포트의 크기 비트레이 바이트크기 등을
GetCommState(m_hComn,&dcb); //GetCommState 설정
dcb.BaudRate=19200; //속도설정
dcb.ByteSize=8; //문자사이즈 설정
dcb.Parity=0; //패러디비트 설정
dcb.StopBits=0; //스톱비트설정
SetCommState(m_hComn,&dcb); //SetCommState 설정
OVERLAPPED osWrite,osRead; //송신용 객체 생성,수신용 객체 생성
osWrite.Offset=0;
osWrite.OffsetHigh=0;
osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); //송신용이벤트설정
osRead.Offset=0;
osRead.OffsetHigh=0;
osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); //수신용이벤트설정
unsigned char i; //게임시작을 입력을받을 변수
unsigned char j=0; //스위치와 일치하는 갯수
unsigned char xnum='x'; //LED와 FND가 값이 일치하면 전송할 변수
unsigned char znum='z'; //LED와 FND가 값이 틀리면 전송할 변수
unsigned char anum='A'; //5번 전부 맞출경우 전송할 변수
unsigned char jnum; //5번 돌리기위한 변수
unsigned char lednum; //LED숫자표시
unsigned char conum; // rand()함수 대입변수
unsigned char swit; //ATMEGA에서 받을 값
printf("게임을 시작하시겠습니까?(y)\n");
i=getche(); //시작값을 받기
printf("\n");
if(i=='y') // 입력된값이 'y'이면 시작
{
OPEN=fopen("result.txt","w"); //FILE OPEN
if(OPEN==NULL) //FILE OPEN실패시 종료
{
return 0;
}
j=0; //맞춘갯수 초기화
srand((int)time(NULL)); //rand()함수의 값을변경할 srand함수설정
WriteFile(m_hComn,&i,1,NULL,&osWrite); //시작입력값인 'y'을 전송
for(jnum=0;jnum<5;++jnum) //5번횟수만큼 돌 반복문
{
conum=rand()%8; //난수함수에 생성된값을 conum에 대입
lednum=conum; //conum의 값을 lednum에 대입
switch(conum) //conum값에 따라 전송할 LED값을 설정
{
case 0: //순서대로 켜기위해서 바꿔야함
conum=254;
break;
case 1:
conum=253;
break;
case 2:
conum=251;
break;
case 3:
conum=247;
break;
case 4:
conum=239;
break;
case 5:
conum=223;
break;
case 6:
conum=191;
break;
case 7:
conum=127;
break;
}
WriteFile(m_hComn,&conum,1,NULL,&osWrite); //LED값을 전송
Sleep(800); //잠시 대기
ReadFile(m_hComn,&swit,1,NULL,&osRead); //PINC값을 받음
if(swit==128) //받은PINC값에 따라서
{ //스위치번호 변경
swit=8;
}
else if(swit==64)
{
swit=7;
}
else if(swit==32)
{
swit=6;
}
else if(swit==16)
{
swit=5;
}
else if(swit==8)
{
swit=4;
}
else if(swit==4)
{
swit=3;
}
else if(swit==2)
{
swit=2;
}
else if(swit==1)
{
swit=1;
}
else
{
swit=0;
}
if(lednum+1==swit) //LED와 스위치가 같은경우
{
printf("LED[%d]\tSWITCH[%d]성공 \n",lednum+1,swit); //성공출력
fprintf(OPEN,"LED[%d]\tSWITCH[%d]성공\n",lednum+1,swit);//파일에저장
j++; //맞춘회수 증가
WriteFile(m_hComn,&xnum ,1,NULL,&osWrite); //맞췄기때문에 FND에 'x' 값보냄
}
else if (conum!=swit) //LED와 스위치가 다른경우
{
printf("LED[%d]\tSWITCH[%d]실패 \n",lednum+1,swit); //실패출력
fprintf(OPEN,"LED[%d]\tSWITCH[%d]실패 \n",lednum+1,swit);//파일에저장
WriteFile(m_hComn,&znum,1,NULL,&osWrite); //틀려도 FND에 값을 'z'를 보냄
}
}
if(j==5) //다맞춘경우
{
WriteFile(m_hComn,&anum,1,NULL,&osWrite); // LED값을위해서 'A'를 전송
}
Sleep(800); //잠시대기
printf("최종점수는 [%d]점입니다\n",j*5); //최종점수출력
fprintf(OPEN,"최종점수는 [%d]점입니다\n",j*5); //최종점수 파일에 저장
fclose(OPEN); //파일닫기
}
CloseHandle(m_hComn);
return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------
-결과값-
------------------------------------------------------------------------------------------------------------------------------------------
-동영상-
=실패시=
====성공시====
------------------------------------------------------------------------------------------------------------------------------------------
-파일소스-