BASIC4MCU | 질문게시판 | 답변 : Codevision에서 avr studio4 변환 질문입니다
페이지 정보
작성자 master 작성일2018-12-21 00:42 조회5,983회 댓글0건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=7170
본문
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2018-12-21 오전 12:47:32// by Ok-Hyun Park/*******************************************//*nwarm.c: 지렁이 게임*//*2008.6 by 고광현*//******************************************/// warm.c#include <avr/io.h>#include <avr/interrupt.h>#include <stdio.h>#define F_CPU 16000000UL // 16 MHz#include <util/delay.h>#include <stdlib.h>//#define SIZE 16 // 오목판(LDM)사이즈#define LINE_ADDR PORTG // Line Address#define RED_1 PORTA|=1 // Red LED Data PA0#define RED_0 PORTA&=~1 // Red LED Data PA0#define GREEN_1 PORTA|=2 // Green LED Data PA1#define GREEN_0 PORTA&=~2 // Green LED Data PA1#define ENABLE_1 PORTA|=4 // Output Enable PA2#define ENABLE_0 PORTA&=~4 // Output Enable PA2#define LATCH_1 PORTA|=8 // Latch PA3#define LATCH_0 PORTA&=~8 // Latch PA3#define CLOCK_1 PORTA|=0x10 // Clock PA4#define CLOCK_0 PORTA&=~0x10 // Clock PA4#define UP_SW (PINC&1) // Up 이동 스위치 PC0#define DOWN_SW (PINC&2) // Down 이동 스위치 PC1#define LEFT_SW (PINC&4) // Left 이동 스위치 PC2#define RIGHT_SW (PINC&8) // Right 이동 스위치 PC3#define PUT_SW (PINC&0x10) // Put 스위치(사용 안함)PC4#define START_SW (PINC&0x20) // Start 스위치 PC5#define UP 1 // 지렁이 움직이는 방향 위#define DOWN 2 // 지렁이 움직이는 방향 아래#define LEFT 3 // 지렁이 움직이는 방향 왼쪽#define RIGHT 4 // 지렁이 움직이는 방향 오른쪽// 사용 변수int dot_i=0; // 타이머 오버플로우(1ms)인터럽트 함수에서// 다음에 표시할 라인 번호int h_x,h_y; // 머리 x,y 좌표int o_x,o_y; // 먹이 x,y 좌표char dir; // 지렁이 이동 방향int tcnt=0;int length=0; // 지렁이 마디 수int kk; // 꼬리 배열 번호(새로운 머리 좌표 저장할 배연 번호)int lent_time,st=0;char dot_red[SIZE][SIZE]; // LDM 제어신호에서 사용할 R성분char dot_green[SIZE][SIZE]; // LDM 제어신호에서 사용할 G성분char w_x[256],w_y[256]; // 마디 좌표 저장 배열 변수char buf_x[256],buf_y[256]; // 마디 좌표 일시 저장 작업 배열 변수// 7-세그먼트 숫자 출력 패턴char seg_pat[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};char w_init[3][2]={{ 0,0},{ 1,0},{ 2,0} }; // 지렁이 시작 마디 좌표char sijak[16][16]={ // "웜게임" 문자 패턴{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{ 0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1},{ 0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,1},{ 0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,1},{ 0,0,1,1,0,0,0,1,0,0,0,1,1,1,0,1},{ 0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,1},{ 0,1,1,1,1,1,0,1,0,0,1,0,0,1,0,1},{ 0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1},{ 0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0},{ 0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1},{ 0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1},{ 0,1,1,1,1,1,1,1,0,1,0,0,0,1,0,1},{ 0,1,0,0,0,0,0,1,0,0,1,1,1,0,0,1},{ 0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1},{ 0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1},{ 0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1}};char end[16][16]={ // "END" 문자 패턴{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{ 1,1,1,1,0,1,0,0,0,1,0,1,1,1,0,0},{ 1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,1,0,1,0,1,0,0,1,0},{ 1,1,1,1,0,1,0,1,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,1,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,1,0,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0},{ 1,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0},{ 1,1,1,1,0,1,0,0,0,1,0,1,1,1,0,0},{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};//void disp_init(void){ // LDM "웜게임" 출력 표시int i,j;for(j=0; j<SIZE; j++){for(i=0; i<SIZE; i++){dot_green[j][i]=sijak[j][i]; // 도트매트릭스 클리어dot_red[j][i]=sijak[j][i];}}}//void disp_end(void){ // LDM "END" 출력 표시int i,j;for(j=0; j<SIZE; j++){for(i=0; i<SIZE; i++)dot_red[j][i]=end[j][i]; // 도트매트릭스 클리어}}//void warm_init(void){ // 게임 초시 상태 설정int i,j,x,y;// 도트매트릭스 클리어for(j=0; j<SIZE; j++){for(i=0; i<SIZE; i++){dot_green[j][i]=0;dot_red[j][i]=0;}}// 지렁이 초기 상태의 마디 좌표 설정(길이 3)for(i=0; i<3; i++){x=w_init[i][0];y=w_init[i][1];w_x[i]=x; // 마디 x좌표w_y[i]=y; // 마디 y좌표dot_green[y][x]=1; // 녹색 LED on(지렁이 몸체)}h_x=w_init[2][0]; // 머리 x 좌표h_y=w_init[2][1]; // 머리 y 좌표length=3; // 길이 3kk=0; // 꼬리 배열 번호dot_i=0; // 타이머 인터럽트 함수에서 표시할 라인 초기 번호o_x=12; // 초기 먹이 위치o_y=12;LINE_ADDR=0; // 표시할 라인 초기 어드레스=0RED_0; // Red LED offGREEN_0; // Green LED offLATCH_1; // Latch highENABLE_0; // Output Enable lowCLOCK_0; // Clock lowdot_red[o_y][o_x]=1; // 먹이 적색 표시lent_time=500-length*5; // 게임 진행 속도 딜레이 계산}//void seg_out(){ // 지렁이 마디 수 7-세그먼트 표시int n100,n10,n1,buf;n100=length/100; // 100자리 추출buf=length%100; // 100으로 나눈 나머지n10=buf/10; // 10자리 추출n1=buf%10; // 1자리 추출PORTF=0b11100000; // 1자리 세그먼트 ONPORTB=seg_pat[n1]; // 1자리 출력_delay_us(50);PORTF=0b11010000; // 10자리 세그먼트 ONPORTB=seg_pat[n10]; // 10자리 출력_delay_us(50);PORTF=0b10110000; // 100자리 세그먼트 ONPORTB=seg_pat[n100]; // 100자리 출력_delay_us(50);}//void sw_input(){ // 스위치 입력 처리seg_out(); // 지렁이 마디수 출력if(dir!=DOWN&&UP_SW==0)dir=UP; // 이동 방향 위로else if(dir!=UP&&DOWN_SW==0)dir=DOWN; // 아래 이동 스위치else if(dir!=RIGHT&&LEFT_SW==0)dir=LEFT; // 왼쪽 이동 스위치else if(dir!=LEFT&&RIGHT_SW==0)dir=RIGHT; // 오른쪽 이동 스위치}//ISR(TIMER0_OVF_vect){ // 타이머/카운터0(256-0)*64/16 us=1.024msint bx,by,i,di;dot_i=(dot_i+1)%SIZE; // LDM 표시라인 1증가tcnt++; // 게임 진행속도 조절 카운터for(di=0; di<SIZE; di++){ // 한 라인 데이터 출력if(dot_red[dot_i][di])RED_1; else RED_0; // 적색 먹이 데이터if(dot_green[dot_i][di])GREEN_1; else GREEN_0; // 녹색 먹이 데이터CLOCK_1; // 클럭 ON_delay_us(1);CLOCK_0; // 클럭 OFF_delay_us(1);}_delay_us(1);ENABLE_1; // Enable 비트 셋LATCH_0;_delay_us(1);LATCH_1;LINE_ADDR=dot_i; // 출력 라인 설정_delay_us(1);ENABLE_0; // 인에이블 비트 리셋// 게임 진행속도에 맞춰 지렁이 이동방행으로 1칸 이동 처리if(tcnt>=lent_time&&st==1){tcnt=0;if(dir==UP){ // 이동방향=위?if(h_y>0)h_y--; // 머리 Y좌표 1감소else st=0; // 윗쪽 벽 충돌 게임종료}else if(dir==DOWN){ // 이동방향=아래?if(h_y<15)h_y++; // 머리 Y좌표 1증가else st=0; // 아래쪽 벽 충돌 게임종료}else if(dir==LEFT){ // 이동방향=왼쪽?if(h_x>0)h_x--; // 머리 X좌표 1감소else st=0; // 왼쪽 벽 충돌 게임종료}else{ // 이동방향=오른쪽?if(h_x<15)h_x++; // 머리 X좌표 1감소else st=0; // 오른쪽 벽 충돌 게임종료}if(st==0)return; // 게임종료if(o_x==h_x&&o_y==h_y){ // 먹이좌표=새로운 머리좌표// 지렁이 마디 좌표 재정렬 저장for(i=0; i<length; i++){buf_x[i]=w_x[kk];buf_y[i]=w_y[kk];kk=(kk+1)%length;}for(i=0; i<length; i++){w_x[i]=buf_x[i];w_y[i]=buf_y[i];}w_x[length]=h_x; // 머리부분 좌표w_y[length]=h_y;kk=0; // 꼬리부분 배열 번호length=length+1; // 길이 1증가if(length<50)lent_time=500-length*5; // 길이에 따라 점점 빠르게dot_red[o_y][o_x]=0; // 현재 먹이 제거dot_green[h_y][h_x]=1; // 먹이 부분 추가// 새 먹이 발생while(1){o_x=rand()%16;o_y=rand()%16;if(dot_green[o_y][o_x]!=0)continue; // 지렁이 없는 위치에 생성dot_red[o_y][o_x]=1;break;}}else{ // 지렁이 단순 이동(먹이 먹지 않은 이동)bx=w_x[kk]; // 꼬리 좌표 백업by=w_y[kk];w_x[kk]=h_x; // 현재의 머리좌표 kk번째 배열에 저장w_y[kk]=h_y;dot_green[by][bx]=0; // 현재 꼬리부분 클리어kk=(kk+1)%length; // 새로운 꼬리부분 배열 번호 갱신if(dot_green[h_y][h_x]==1)st=0; // 몸부분과 충돌 체크else dot_green[h_y][h_x]=1; // 새 머리 부분 추가}}}//int main(void){int i;DDRA=0x1F; // 포트A 출력 설정(LDM 제어핀)DDRG=0x1F; // 포트G 출력설정(LDM 어드레스 A0-A3)DDRC=0x00; // 포트C 입력 설정(스위치)DDRB=0xFF; // 포트B 출력 설정(패턴값 출력)DDRF=0xFF; // 포트F 출력 설정(구동 7-Segment 선택)PORTA=0b00001100; // Enable HighPORTG=0x0F; // A0-A3=1111PORTA=0b00001000; // Enable LowASSR=0x00; // 타이머/카운터0 타이머 모드TCCR0=0x04; // 일반모드,프리스케일=CK/64TCNT0=0x00; // 타이머/카운터0 레지스터 초기값TIMSK=0x01; // TOIE0=1,타이머/카운터0 인터럽트 인에이블SREG=0x80; // 전역 인터럽트 인에이블 비트 I 셋while(1){disp_init(); // 시작을 위한 초기설정dir=RIGHT; // 지렁이 이동방향 오른쪽 설정while(START_SW)seg_out(); // 시작 스위치가 눌려질 때까지 대기warm_init(); // 지렁이 게임 시작 상태 설정st=1; // 게임 진행srand(TCNT0); // TCNTO값 랜덤 seed값으로 이용while(st)sw_input(); // 스위치 입력 체크disp_end(); // "END" 표시for(i=0; i<30000; i++)seg_out(); // 일시 대기}}
댓글 0
조회수 5,983등록된 댓글이 없습니다.