답변 : 답변 : 답변 : Codevision에서 avr studio4 변환 질문입니다
페이지 정보
작성자 master 작성일18-12-23 07:17 조회3,966회 댓글0건본문
// MCU BASIC: https://www.basic4mcu.com
// DateTime : 2018-12-23 오전 7:21:15
// by Ok-Hyun Park
//
#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 PORTE // Line Address
#define RED_1 PORTD|=1 // Red LED Data PA0
#define RED_0 PORTD&=~1 // Red LED Data PA0
#define GREEN_1 PORTD|=2 // Green LED Data PA1
#define GREEN_0 PORTD&=~2 // Green LED Data PA1
#define ENABLE_1 PORTD|=4 // Output Enable PA2
#define ENABLE_0 PORTD&=~4 // Output Enable PA2
#define LATCH_1 PORTD|=8 // Latch PA3
#define LATCH_0 PORTD&=~8 // Latch PA3
#define CLOCK_1 PORTD|=0x10 // Clock PA4
#define CLOCK_0 PORTD&=~0x10 // Clock PA4
//
#define UP_SW (PINB&2) // Up 이동 스위치 PB1
#define DOWN_SW (PINB&4) // Down 이동 스위치 PB2
#define LEFT_SW (PINB&8) // Left 이동 스위치 PB3
#define RIGHT_SW (PINB&1) // Right 이동 스위치 PB0
//
#define PUT_SW (PINF&0x20) // Put 스위치(사용 안함)PF4
#define START_SW (PINF&0x10) // Start 스위치 PF0
//
#define UP 1 // 지렁이 움직이는 방향 위
#define DOWN 2 // 지렁이 움직이는 방향 아래
#define LEFT 3 // 지렁이 움직이는 방향 왼쪽
#define RIGHT 4 // 지렁이 움직이는 방향 오른쪽
// 사용 변수
volatile int dot_i=0; // 타이머 오버플로우(1ms)인터럽트 함수에서 다음에 표시할 라인 번호
volatile int h_x,h_y; // 머리 x,y 좌표
volatile int o_x,o_y; // 먹이 x,y 좌표
volatile char dir; // 지렁이 이동 방향
volatile int tcnt=0;
volatile int length=0; // 지렁이 마디 수
volatile int kk; // 꼬리 배열 번호(새로운 머리 좌표 저장할 배연 번호)
volatile int lent_time,st=0;
volatile char dot_R[SIZE][SIZE]; // LDM 제어신호에서 사용할 R성분
volatile char dot_G[SIZE][SIZE]; // LDM 제어신호에서 사용할 G성분
volatile char w_x[256],w_y[256]; // 마디 좌표 저장 배열 변수
volatile char buf_x[256],buf_y[256]; // 마디 좌표 일시 저장 작업 배열 변수
//
volatile char w_init[3][2]={{0,0},{1,0},{2,0}}; // 지렁이 시작 마디 좌표
volatile char seg_pat[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 7-세그먼트 숫자 출력 패턴
//
volatile 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}
};
volatile 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_G[j][i]=sijak[j][i]; // 도트매트릭스 클리어
dot_R[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_R[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_G[j][i]=0; dot_R[j][i]=0; }
}
//
for(i=0; i<3; i++){ // 지렁이 초기 상태의 마디 좌표 설정(길이 3)
x=w_init[i][0]; w_x[i]=x; // 마디 x좌표
y=w_init[i][1]; w_y[i]=y; // 마디 y좌표
dot_G[y][x]=1; // 녹색 LED on(지렁이 몸체)
}
h_x=w_init[2][0]; h_y=w_init[2][1]; // 머리 좌표
length=3; // 길이 3
kk=0; // 꼬리 배열 번호
dot_i=0; // 타이머 인터럽트 함수에서 표시할 라인 초기 번호
o_x=12; o_y=12; // 초기 먹이 위치
LINE_ADDR=0; // 표시할 라인 초기 어드레스=0
RED_0; GREEN_0; // Red LED off // Green LED off
LATCH_1; // Latch high
ENABLE_0; // Output Enable low
CLOCK_0; // Clock low
dot_R[o_y][o_x]=1; // 먹이 적색 표시
lent_time=500-length*5; // 게임 진행 속도 딜레이 계산
}
//
void sw_input(){ // 스위치 입력 처리
// 지렁이 마디수 출력
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.024ms
int bx,by,i,di;
dot_i=(dot_i+1)%SIZE; // LDM 표시라인 1증가
tcnt++; // 게임 진행속도 조절 카운터
for(di=0; di<SIZE; di++){ // 한 라인 데이터 출력
if(dot_R[dot_i][di])RED_1; else RED_0; // 적색 먹이 데이터
if(dot_G[dot_i][di])GREEN_1; else GREEN_0; // 녹색 먹이 데이터
CLOCK_1; _delay_us(1); CLOCK_0; _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; // 인에이블 비트 리셋
//
if(tcnt>=lent_time&&st==1){ // 게임 진행속도에 맞춰 지렁이 이동방행으로 1칸 이동 처리
tcnt=0;
if (dir==UP ){ if(h_y> 0)h_y--; else st=0; } // 이동방향=위? // 머리 Y좌표 1감소 // 윗쪽 벽 충돌 게임종료
else if(dir==DOWN){ if(h_y<15)h_y++; else st=0; } // 이동방향=아래? // 머리 Y좌표 1증가 // 아래쪽 벽 충돌 게임종료
else if(dir==LEFT){ if(h_x> 0)h_x--; else st=0; } // 이동방향=왼쪽? // 머리 X좌표 1감소 // 왼쪽 벽 충돌 게임종료
else { if(h_x<15)h_x++; else st=0; } // 이동방향=오른쪽? // 머리 X좌표 1감소 // 오른쪽 벽 충돌 게임종료
//
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_R[o_y][o_x]=0; // 현재 먹이 제거
dot_G[h_y][h_x]=1; // 먹이 부분 추가
//
while(1){ // 새 먹이 발생
o_x=rand()%16; o_y=rand()%16;
if(dot_G[o_y][o_x]!=0)continue; // 지렁이 없는 위치에 생성
dot_R[o_y][o_x]=1;
break;
}
}
else{ // 지렁이 단순 이동(먹이 먹지 않은 이동)
bx=w_x[kk]; by=w_y[kk]; // 꼬리 좌표 백업
w_x[kk]=h_x; w_y[kk]=h_y; // 현재의 머리좌표 kk번째 배열에 저장
dot_G[by][bx]=0; // 현재 꼬리부분 클리어
kk=(kk+1)%length; // 새로운 꼬리부분 배열 번호 갱신
if(dot_G[h_y][h_x]==1)st=0; // 몸부분과 충돌 체크
else dot_G[h_y][h_x]=1; // 새 머리 부분 추가
}
}
}
//
int main(void){
int i;
DDRD=0x1F; // 포트D 출력 설정(LDM 제어핀)
DDRE=0x1F; // A0-A3=1111 // 포트E 출력설정(LDM 어드레스 A0-A3)
//DDRB=0x00; // 포트B 입력 설정(스위치)
//DDRF=0x00; // 포트F 입력 설정(스위치)
PORTD=0x0C; PORTE=0x0F; PORTD=0x08; // 포트D 출력 설정(LDM 제어핀) // Enable High // Enable Low
//
TCCR0=0x04; TIMSK=0x01; // 프리스케일=CK/64
SREG=0x80;
while(1){
disp_init(); // 시작을 위한 초기설정
dir=RIGHT; // 지렁이 이동방향 오른쪽 설정
while(START_SW)_delay_ms(1); // 시작 스위치가 눌려질 때까지 대기
warm_init(); // 지렁이 게임 시작 상태 설정
st=1; // 게임 진행
srand(TCNT0); // TCNTO값 랜덤 seed값으로 이용
while(st)sw_input(); // 스위치 입력 체크
disp_end(); // "END" 표시
_delay_ms(4500); // 일시 대기
}
}
원 소스가 정상동작 했던 것인지 확인하시고요
volatile 선언 추가했으니 이 소스로 다시 돌려보세요
댓글 : 0
조회수 : 3,966
등록된 댓글이 없습니다.