2010년/프로젝트

-두더지게임-

뽀얀햄스터 2010. 4. 26. 12:50


-두더지게임 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;
}

------------------------------------------------------------------------------------------------------------------------------------------
-결과값-


------------------------------------------------------------------------------------------------------------------------------------------
-동영상-
=실패시=



====성공시====

------------------------------------------------------------------------------------------------------------------------------------------
-파일소스-