BASIC4MCU | 질문게시판 | atmega128 소스코드
페이지 정보
작성자 만세에 작성일2018-12-04 16:03 조회8,570회 댓글0건본문
제가 atmega128 소스코드 중에 난수 발생을 해서 실행시키는 소스코드를 공부중에 있습니다. 그중에 하나의 소스코드를 받아서 공부를 해보고 있는데
분명 제대로 된 연결을 했다고 생각이 드는데 자꾸 원하는 값이 안나오네요... 혹시 이 소스코드를 어떤식으로 선으로 연결을 해야 하는지 가르쳐 주시면 감사하겠습니다 ㅠㅠ
소스코드가 좀 많이 길기는 합니다....살려주세요... 사용하는것은 codevisionAVR인데 혹시 이것 때문에 문제가 있는건가요..
#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#include <stdlib.h>void main();
int Hh=0;
int Mm=0;
int Ss=0; // hour, minute, second
int Ra_a=0;
int r2 =0;
int Ra_b=0;
int Ra_c=0; // Random number
int rand_number=0; // 난수에서 3자리 숫자만 받아 들이는 변수
int rand_number2=0;
int led_num; // Led의 불이 켜지는 갯수
int count_num; // 게임에서 숫자를 입력하는 횟수
int strike, ball, out; // strike, ball, out 개수를 저장하는 변수
int i=0;
int count_a, count_b; // 타이머 함수 내에 시계 함수 제어에 필요한 변수
int gamers_count=0; // 게이머가 정답을 맞추기 위해 입력한 횟수
int ranking_count=100; // 랭킹 Reset시 초기값
int loop=1; // while문 안에 진입하기 위한 변수
int loop_2=1; // 또 다른 while문 안에 진입하기 위한 변수
int In_Seg[6]; // 랜덤으로 생성된 난수가 입력되는 배열
int Fi_Seg[6]; // 게이머가 입력한 숫자가 입력되는 배열
int display[6]; // segment 에 문자 및 숫자를 표시하기 위해 필요한 배열
int led_cont=0xff; // led 가 켜졌다 꺼졌다를 반복 시킬때 필요한 변수의 초기값은 전부 켜짐
int base;char nm_a='J';
char nm_b='A';
char nm_c='P'; // 랭킹에 입력되는 이니셜 이름 초기값
int LED2;
unsigned char Numbers[13] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x40, 0x00, 0x12}; // 0~9 + Out + Ball + Strike
unsigned char Seg_Num[6] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20}; // segment 제어용
unsigned char led[9] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; // led가 한 개씩 증가unsigned char LED1[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
interrupt [EXT_INT0] void ext_int0_isr(void) // 스위치 1을 누를 시 정답 숫자가 표시됨
{printf("\n\r\n\r정답은 %d%d%d입니다.",Ra_a,Ra_b,Ra_c);
}
interrupt [EXT_INT1] void ext_int1_isr(void) // 스위치 2를 누를 시 게임 중간에 다시 메뉴로 돌아감
{
loop=0;
loop_2=0;}
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define RX_BUFFER_SIZE0 8
char rx_buffer0[RX_BUFFER_SIZE0];#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif
bit rx_buffer_overflow0;interrupt [TIM0_OVF] void timer0_0vf_isr(void)
{
count_a++;
if(count_a==100) // 게임을 시작한 후 시간이 얼마나 흘렀는지 계산
{
Ss++;
if ( Ss >= 60 )
{
Mm++;
Ss = 0;
if ( Mm >= 60 )
{
Hh++;
Mm = 0;
if ( Hh >= 24 )
{
Hh = 0;
Mm = 0;
Ss = 0;
}
}
}
count_a=0;
}
count_b++;
if(count_b==100000) // 단순히 난수 생성의 seed역할을 해줌
{
count_b=0;
}
if(base==1){
display[0] = 10; // segment 에 O.을 표시
display[1] = out; // out 개수를 표시
display[2] = 11; // segment 에 B.을 표시
display[3] = ball; // ball 개수를 표시
display[4] = 12; // segment 에 S.을 표시
display[5] = strike; // strike 개수를 표시
}for ( i = 0 ; i <6 ; i++ ) // segment에 몇 strike, 몇 ball, 몇 out인지 표시
{
PORTA = Seg_Num[i];
PORTB= Numbers[display[i]];
delay_ms(1);
}
}
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
}#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif#define TX_BUFFER_SIZE0 8
char tx_buffer0[TX_BUFFER_SIZE0];#if TX_BUFFER_SIZE0<256
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
#else
unsigned int tx_wr_index0,tx_rd_index0,tx_counter0;
#endifinterrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (tx_counter0)
{
--tx_counter0;
UDR0=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
};
}#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
++tx_counter0;
}
else
UDR0=c;
#asm("sei")
}
#pragma used-
#endif#include <stdio.h>
void menu();
void main(void)
{PORTA=0x00;
DDRA=0xff;PORTB=0xff;
DDRB=0xff;
PORTC=0xff;
DDRC=0xff;PORTD=0x00;
DDRD=0x00;
PORTE=0x00;
DDRE=0x00;
PORTF=0x00;
DDRF=0xff;
PORTG=0x00;
DDRG=0x00;
ASSR=0x00;
TCCR0=0x06; // 타이머 함수 내에서 시계를 구현하고자 값 설정
TCNT0=50;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;TCCR2=0x00;
TCNT2=50;
OCR2=0x00;
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
EICRA=0x0A;
EICRB=0x00;
EIMSK=0xff;
EIFR=0x03;
SREG=0xff;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
ETIMSK=0x00;
UCSR0A=0x02;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x67;
ACSR=0x80;
SFIOR=0x00;
#asm("sei")while (1)
{
menu();
}
}
void starta()
{
srand(count_b); // count_b를 seed로 받음
rand_number2 = rand()%9;
}void start() // 게임을 시작할 경우 실행되는 함수
{
base=1;
loop=1;
while(loop)
{
srand(count_b); // count_b를 seed로 받음
rand_number = rand()%1000; // rand_number은 3자리 숫자만 받음
Ra_a=rand_number/100; // Ra_a는 난수중 첫 번째 자리 숫자
Ra_b=(rand_number-Ra_a*100)/10; // Ra_b는 난수중 두 번째 자리 숫자
Ra_c=(rand_number-Ra_a*100)-Ra_b*10; // Ra_c는 난수중 세 번째 자리 숫자
In_Seg[0] = 10; // dot
In_Seg[1] = Ra_c; // 난수중 3번째 자리 저장
In_Seg[2] = 10; // dot
In_Seg[3] = Ra_b; // 난수중 2번째 자리 저장
In_Seg[4] = 10; // dot
In_Seg[5] = Ra_a; // 난수중 1번째 자리 저장
if(In_Seg[1] != In_Seg[3] && In_Seg[1] != In_Seg[5] && In_Seg[3] !=In_Seg[5])
{
printf("\n\r\n\r게임이 시작되었습니다!");
loop=0; // while 문을 벗어남
}
}
loop = 1; // 다른 while 문에 진입
while(loop)
{
int i, j, Fi_a, Fi_b, Fi_c; // i, j는 for문에 필요한 변수, Fi는 게이머가 입력한 숫자를 변수 선언
char ch_a,ch_b,ch_c;
loop_2=1; // while문에 진입
while(loop_2)
{
printf("\n\r\n\r숫자를 입력하세요 : ");
ch_a=getchar(); // 게이머가 입력한 첫 번째 숫자를 저장
printf("%c",ch_a);
ch_b=getchar(); // 게이머가 입력한 두 번째 숫자를 저장
printf("%c",ch_b);
ch_c=getchar(); // 게이머가 입력한 세 번째 숫자를 저장
printf("%c",ch_c);
if(ch_a==ch_b || ch_a==ch_c || ch_b==ch_c){ // 입력한 숫자가 다 같으면 다시 입력 받음
printf("\n\r\n\r\n\r숫자를 다시 입력하세요.");
}
else{
loop_2=0; // 입력 받은 숫자가 다르면 게임을 진행
}
}
Fi_a=ch_a-'0';
Fi_b=ch_b-'0';
Fi_c=ch_c-'0'; // character 형식을 interger 형식으로 저장
Fi_Seg[0] = 10; // dot
Fi_Seg[1] = Fi_c; // 입력된 세 번째 숫자를 배열에 저장
Fi_Seg[2] = 10; // dot
Fi_Seg[3] = Fi_b; // 입력된 두 번째 숫자를 배열에 저장
Fi_Seg[4] = 10; // dot
Fi_Seg[5] = Fi_a; // 입력된 첫 번째 숫자를 배열에 저장
printf("\n\r입력한 숫자는 %d%d%d입니다.",Fi_a,Fi_b,Fi_c);
strike=0;
ball=0;
out=0; // strike, ball, out 초기화
for (i = 1; i < 4; i++) {
for (j=1; j < 4; j++) {
if (In_Seg[2*i-1] == Fi_Seg[2*j-1] && i == j) { // 인덱스와 값이 동일해야 strike
strike++;
} else if(In_Seg[2*i-1] == Fi_Seg[2*j-1] && i != j) { // 인덱스의 값이 다르면 ball
ball++;
}
}
}
out = 3-(ball+strike);
printf("\n\r%d Strike~! %d Ball~ %d Out...", strike, ball, out);
count_num++;
led_num++;
if(led_num>8)
led_num=1;
PORTF=led[led_num]; // led가 켜지는 개수가 하나씩 증가
if (strike == 3) // 게이머가 숫자를 맞춘경우
{
printf("\n\r\n\r정답입니다!");
printf("\n\r시도 횟수 : %d회",count_num);
for(i=0; i<15; i++) // led 가 깜빡거림
{
PORTF=led_cont;
delay_ms(20);
led_cont=~led_cont;
PORTF=led_cont;
delay_ms(20);
led_cont=~led_cont;
}
gamers_count=count_num; // 게이머가 몇 번의 시도만에 숫자를 맞추었는지 저장
if( ranking_count>gamers_count) // 시도횟수가 랭킹보다 적을 경우
{
ranking_count=gamers_count; // 랭킹 기록 갱신
printf("\n\r\n\r축하합니다~!");
printf("\n\r기록을 경신했습니다!");
printf("\n\r이니셜을 입력하세요 : ");
nm_a=getchar();
printf("%c",nm_a);
nm_b=getchar();
printf("%c",nm_b);
nm_c=getchar();
printf("%c",nm_c); // 랭킹에 게이머의 이름 이니셜을 등록
}
loop=0;
count_num=0;
led_num=0;
}
}
}
void ranking() // 랭킹에 기재된 게이머의 시도 횟수 및 이름의 이니셜을 보여줌
{
printf("\n\r\n\r현재 1위는 %c%c%c입니다!", nm_a, nm_b, nm_c);
printf("\n\r시도횟수는 %d회입니다.",ranking_count);
}void reset() // 랭킹을 리셋
{
nm_a=0;
nm_b=0;
nm_c=0;
ranking_count=100;
printf("\n\r\n\r기록이 초기화되었습니다.");
}void time() // 게이머가 게임을 시작한지 얼마나 됐는지 보여줌
{
printf("\n\r게임진행시간 %d:%d:%d",Hh,Mm,Ss);
}
void ak();void show_menu() // 메뉴 함수
{
char ch;
printf("\n\r1.게임 시작 "); // 1을 누르면 게임 시작
printf("\n\r2.최고기록 확인 "); // 2을 누르면 랭킹을 확인
printf("\n\r3.기록 초기화 및 재시작 "); // 3을 누르면 랭킹이 리셋
printf("\n\r4.진행시간 확인하기"); // 4을 누르면 게임 진행 시간 확인
printf("\n\r5.해적룰렛 게임하기");
printf("\n\r번호를 선택하세요 : ");
ch = getchar();
if ( ch == '1' )
start();
if ( ch == '2' )
ranking();
if ( ch == '3' )
reset();
if ( ch == '4' )
time();
if ( ch == '5' )
ak();
}
void menu()
{
char ch;
printf("\n\r***** 1.숫자야구게임 *****");
printf("\n\r***** 2.해적룰렛게임 *****");
printf("\n\r게임을 선택하세요 : ");
ch = getchar();
if ( ch == '1' )
show_menu();
if ( ch == '2' )
ak();
}
void ak()
{
char ch_1;
int Fi_1;
int i;
base=0;
starta();
rand_number2 = rand()%8+1;
r2=rand_number2/1;
LED2 = 0xff;
while(1)
{
PORTF=LED2;
printf("\n\r 1~8까지 숫자를 입력하세요.");
printf("\n\r 입력한 숫자 : ");
ch_1=getchar(); // 게이머가 입력한 첫 번째 숫자를 저장
printf("%c",ch_1);
Fi_1=ch_1-'0';
LED2 = LED2-LED1[Fi_1-1];
if(Fi_1 == r2)
{
printf("\n\r당첨~!");
for(i=0;i<8;i++)
{
PORTF= 0xff;
delay_ms(20);
PORTF= 0x00;
delay_ms(20);
}
break;
}
else
printf("\n\r패스!");
}
}
댓글 0
조회수 8,570등록된 댓글이 없습니다.