Witamy, Gość. Zaloguj się lub zarejestruj.

Autor Wątek: Minigra na mikrokontroler 8051  (Przeczytany 3987 razy)

0 Użytkowników i 1 Gość przegląda ten wątek.

Abik

Minigra na mikrokontroler 8051
« dnia: Marzec 26, 2012, 18:23:45 »
Myślę, że nikomu z was się to nie przyda i nikogo nie zainteresuje, ale w internecie (zwłaszcza polskim) takich rzeczy jest względnie mało, a na forach graficznych jestem pewny, że nie ma wcale (no bo nie ma sensu, żeby było xd).

To mój wstępny projekt na zaliczenie przedmiotu jednego. Chciałem to jeszcze przykoksić, ale mam darmową wersję Keil uVision i ona nie pozwala na tworzenie kodów dłuższych niż ileś tam, więc dopóki nie znajdę jakiegoś fajnego kompilatora to muszę zrobić przerwę : p
Kod za długi nie jest więc macie jako całość. Jego wartość edukacyjna jest bardzo duża bo starałem się użyć jak najwięcej elementów mikrokontrolera (użyłbym więcej, ale ten pi***zony Keil mi ograniczenie narzucił ;( )
#include <stdio.h>
#include <REGX51.H>
#include <absacc.h>
#define DEFAULT_FREQ 20

//Ekran LCD:
#define LCDWD 0xf081 //bufor zapisu kodow ascii znakow ekranu LCD
#define LCDWC 0xf080 //bufor zapisu rozkazow LCD
#define LCDRC 0xf082 //bufor odczytu konfiguracju LCD

//Wyswietlacz LED:
#define CSDS 0xf030 //wybor segmentu LED
#define CSDB 0xf038 //wybor wskaznikow (pojedyncze diody)

//Klawiatura matrycowa:
#define CSKB0 0xf021 //rejestr klawiszy 0-7
#define CSKB1 0xf022 //rejestr klawiszy 8-enter

//Przetwornik A/C:
#define CSMX 0xf018 // adres rejestru wyboru wejscia mutiplexera przetwornika AC
#define CSAD 0xf010 // adres rejestru wyniku / startu przetwazrania

char r = 0, i = 0, pozycjamenu = 0, trafienia = 0, key = -1, segment = 0, off = 0;
char glos = 1, poziom = 0, rundy = 3, transmisja = 0, wrozbita = 0;//domyslna konfiguracja gry
unsigned char wynik = 0;
unsigned short czas = 0;

unsigned char przerwanie=0, frequency = 20;
unsigned short sekundy;

char rand(){
return TL0%10;
}

minidelay(char delay){
  unsigned short tmpsek = sekundy;
  while(!(tmpsek+delay == sekundy));
}

//FUNKCJE KLAWIATURY ----------------------------------------------------------------------------

char getkey(){
char klawisze;
if(XBYTE[CSKB0]<0xFF){
klawisze = XBYTE[CSKB0];
switch(klawisze){
case 0xFE: return 0; break;
case 0xFD: return 1; break;
case 0xFB: return 2; break;
case 0xF7: return 3; break;
case 0xEF: return 4; break;
case 0xDF: return 5; break;
case 0xBF: return 6; break;
case 0x7F: return 7; break;
}
}
if(XBYTE[CSKB1]<0xFF){
klawisze = XBYTE[CSKB1];
switch(klawisze){
case 0xFE: return 8; break;
case 0xFD: return 9; break;
case 0xFB: return 10; break; //left arrow
case 0xF7: return 11; break; //right arrow
case 0xEF: return 12; break; //up arrow
case 0xDF: return 13; break; //down arrow
case 0xBF: return 14; break; //esc
case 0x7F: return 15; break; //enter
}
}
}

waitkey(){
while(!(XBYTE[CSKB0]==0xFF && XBYTE[CSKB1]==0xFF)); //tak na wszelki wypadek gdyby poprzedni klawisz nie byl puszczony
while(XBYTE[CSKB0]==0xFF && XBYTE[CSKB1]==0xFF); //czeka na wcisniecie klawisza
}


//FUNKCJE LCD ----------------------------------------------------------------------

newlinelcd(){
while(XBYTE[LCDRC]&0x80);
XBYTE[LCDWC] = 0xC0; //ustawienie kursora na poczatku dolnej linii
}

printlcd(char *txt, char clear){
char i = 0;
if(clear) XBYTE[LCDWC] = 0x01; //wyczyszczenie ekranu
while(XBYTE[LCDRC]&0x80); //sprawdzenie bitu zajetosci BF (busy flag)
while(*txt){
XBYTE[LCDWD] = *txt;
while(XBYTE[LCDRC]&0x80);
txt++; //nastepna litera
if(i++==15) newlinelcd(); //jesli cala linia zapelniona to przechodzimy do nastepnej
}
}

printnumlcd(unsigned char num){
if(num>99){
while(XBYTE[LCDRC]&0x80);
XBYTE[LCDWD] = (num/100)+48; //+48 oznacza dodanie kodu ascii cyfry 0, czyli wlasnie 48
}
if(num>9){
while(XBYTE[LCDRC]&0x80);
XBYTE[LCDWD] =(num/10)+48;
}
while(XBYTE[LCDRC]&0x80);
XBYTE[LCDWD] = (num%10)+48;
}

/*clearlcd(){
while(XBYTE[LCDRC]&0x80);
XBYTE[LCDWC] = 0x01; //wyczyszczenie ekranu
} */

//FUNKCJE LED ---------------------------------------------------------------------

/*printled(char cyfra, char numer, char kropka){
char tablica[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //tablica cyfr od 0 d0 9 - odpowiednie segmenty zapalone
P1_6 = 1; //wylaczenie zasilania LED
XBYTE[CSDS] = 1<<(numer-1); //przesuwmy zamiast forow czy tam je***ych switchy
XBYTE[CSDB] = (tablica[cyfra]) | (0x80 * kropka); //albo (kropka << 7) pzresuwamy na najstarszy bit "1"
P1_6 = 0; //wlaczenie zasilania LED
}

diodaled(char dioda){
P1_6 = 1;
XBYTE[CSDS] = 1<<6;
if(dioda)
XBYTE[CSDB] = 0x10; //zapala diode OK
else
XBYTE[CSDB] = 0x20; //zapala diode ERR
P1_6 = 0;
}    */

timer0() interrupt 1{
  TH0 = 76; //co ok. 50ms przerwanie timera
  if(++przerwanie==frequency){ //20*50ms = 1s
    sekundy++;
przerwanie = 0;
  }
}

odbiornik() interrupt 4 {
  if(RI){ //RI=1 po skompletowaniu znkow w SBUF (z bit stop) musi byc poza funkcja przerwaniowa a tu nie
RI = 0;
printf("WYNIKI\nTrafienia: %c%c/%c%c\nCzas: %c%c%c%c\nWynik: %c%c\n---\n\n",
(trafienia/10)+48, (trafienia%10)+48, (rundy/10)+48, (rundy%10)+48, (czas/10)+48, (czas%10)+48, (wynik/10)+48, (wynik%10)+48);
}
}

ocena(unsigned char wynik, char newline){
if(wynik>80)
printlcd("Genialnie! :D", newline);
else if(wynik>60)
printlcd("Niezle ;)", newline);
else if(wynik>40)
printlcd("Cienko :|", newline);
else if(wynik<=40)
printlcd("Katastrofa :(", newline);
}

main(){
EA=1; ET0=1; ET1 = 1;//odblokowanie timera0 i timera1 
TMOD=0x01; TR0=1; TH0=76; PT0 = 1;//konfiguracja timera0
TMOD|=0x10; TR1=1; TH1=254;//konfiguracja timera1

MENU: //glowne
printlcd("1.Zagraj", 1);
newlinelcd();
printlcd("2.Konfiguruj", 0);
waitkey();
if(getkey()==1) goto START;
if(getkey()==2 || getkey()==11) goto DZWIEK;
else goto MENU;

//configuration wizard
DZWIEK:
if(glos){
printlcd("Dzwiek: -1-ON", 1);
newlinelcd();
printlcd("        -2-off", 0);
}
else{
printlcd("Dzwiek: -1-on", 1);
newlinelcd();
printlcd("        -2-OFF", 0);
}
waitkey();
if(getkey()==1){
glos = 1;
goto DZWIEK;
}
else if(getkey()==2){
glos = 0;
goto DZWIEK;
}
else if(getkey()==10) goto MENU;
else if(getkey()==11) goto RUNDY;
else goto DZWIEK;

RUNDY:
printlcd("Ile rund(0-9):", 1);
printnumlcd(rundy);
newlinelcd();
waitkey();
if(getkey()<10 && getkey()>=0){
rundy = getkey()+1;
goto RUNDY;
}
if(getkey()==10) goto DZWIEK;
if(getkey()==11) goto POZIOM;

POZIOM:
printlcd("Poziom trudnosci:", 1);
newlinelcd();
if(poziom) printlcd("-1-easy -2-HARD", 0);
else printlcd("-1-EASY -2-hard", 0);
waitkey();
if(getkey()==1){
poziom = 0;
goto POZIOM;
}
else if(getkey()==2){
poziom = 1;
goto POZIOM;
}
else if(getkey()==10) goto RUNDY;
else if(getkey()==11) goto TRANSMISJA;
else goto POZIOM;

TRANSMISJA:
printlcd("Wyniki na PC: ", 1);
newlinelcd();
if(transmisja) printlcd("-1-ON -2-off", 0);
else printlcd("-1-on -2-OFF", 0);
waitkey();
if(getkey()==1){
transmisja = 1;
TMOD = 0x21; TR1 = 1; TH1 = 250; //9600bit/s - wykorzystanie timera1
SM0 = 0; SM1 = 1; SM2 = 1; REN = 1; //tryb pracy 1, zablokowany odbiornik (REN)
PCON |= 0x80; //SMOD = 1
ES = 1; //odblokowanie przerwania transmisji szeregowej
TI = 1; //na potrzeby printf
goto TRANSMISJA;
}
else if(getkey()==2){
transmisja = 0;
ES = 0;
goto TRANSMISJA;
}
else if(getkey()==10) goto POZIOM;
else if(getkey()==11) goto WROZBITA;
else goto TRANSMISJA;

WROZBITA:
printlcd("Tryb wrozbity:", 1);
newlinelcd();
if(wrozbita) printlcd("-1-ON -2-off", 0);
else printlcd("-1-on -2-OFF", 0);
waitkey();
if(getkey()==1){
wrozbita = 1;
goto WROZBITA;
}
else if(getkey()==2){
wrozbita = 0;
goto WROZBITA;
}
else if(getkey()==10) goto TRANSMISJA;
else goto WROZBITA;
//--------------------

//Start gry
START:
printlcd("Start gry", 1);
if(glos){
P1_5 = 0;
minidelay(1);
P1_5 = 1;
minidelay(1);
P1_5 = 0;
minidelay(1);
P1_5 = 1;
}
sekundy = 0; trafienia = 0; //wyzerowanie zmiennych uzywanych w grze

for(i = 0; i < rundy; i++){
//wylosowanie liczby
printlcd("Losowanie", 1);
frequency = 14; //uwaga z ta wartoscia bo wplywa na losowosc
P1_7 = 0;
minidelay(1);
printlcd(".", 0);
P1_7 = 1;
minidelay(1);
printlcd(".", 0);
P1_7 = 0;
minidelay(1);
printlcd(".", 0);
P1_7 = 1;
frequency = DEFAULT_FREQ;
r = rand();

//poproszenie o wcisniecie wylosowanej liczby
printlcd("Wcisnij: ", 1);
if(!wrozbita) printnumlcd(r);
newlinelcd();

//oczekiwanie na wcisniecie wymaganej liczby (i jej wyswietlenie w nowej linii)
waitkey();
key = getkey();

//przyznanie punktu za dobre wcisniecie i wyswietlenie na LED
if(key==r){
trafienia++;
printlcd("            OK!", 0);
minidelay(1);
}
else{
if(glos) P1_5 = 0; //pik
if(poziom) trafienia--;
printlcd("           ZLE!", 0);
minidelay(1);
P1_5 = 1;
}
}
czas = sekundy; //zapisanie czasu gracza
wynik = (80-czas)+(trafienia*3); //taki wzor punktow spisuje sie calkiem ok
poziom ? wynik : (wynik+=6); //bonus za poziom trudnosci EASY

//prezentacja wyniku
while(1){
if(pozycjamenu==0){
printlcd("Trafienia: ", 1);
printnumlcd(trafienia);
newlinelcd();
printlcd("Czas: ", 0);
printnumlcd(czas);
}
if(pozycjamenu==1){
printlcd("Czas: ", 1);
printnumlcd(czas);
newlinelcd();
printlcd("Wynik: ", 0);
printnumlcd(wynik);
}
if(pozycjamenu==2){
printlcd("Wynik: ", 1);
printnumlcd(wynik);
newlinelcd();
ocena(wynik, 0);
}
if(pozycjamenu==3){
ocena(wynik, 1);
newlinelcd();
printlcd("-ESC-menu glowne", 0);
if(getkey()==14){
pozycjamenu = 0;
goto MENU;
}
}
waitkey();
if(getkey()==13) pozycjamenu++;
if(getkey()==12) pozycjamenu--;
if(pozycjamenu>3) pozycjamenu = 3;
if(pozycjamenu<0) pozycjamenu = 0;
}
}
te biblioteki regx51.h i absacc.h są na pewno dostępne w keilu, nie wiem jak to jest z nimi gdzieś indziej, niedługo się przekonam jak będę szukać jakiegoś alternatywnego kompilatora : p

Moonmaker

  • *****
  • Podziękowania otrzymane: 80
  • Stranger in a strange land
    • Zobacz profil
    • Moonmaker on dA
  • Ostatnie nagrody:
  • Signature of the Week #81
  • Work of the Month #10
Odp: Minigra na mikrokontroler 8051
« Odpowiedź #1 dnia: Marzec 27, 2012, 18:13:53 »


aha xd

Cytuj
I know what you're thinking. "Did he fire six shots or only five?" Well, to tell you the truth, in all this excitement I kind of lost track myself. But being as this is a .44 Magnum, the most powerful handgun in the world, and would blow your head clean off, you've got to ask yourself one question: Do I feel lucky? Well, do ya, punk?
Harry Callahan

CrimeS

  • *
  • Podziękowania otrzymane: 74
    • Zobacz profil
Odp: Minigra na mikrokontroler 8051
« Odpowiedź #2 dnia: Marzec 27, 2012, 18:25:38 »
ehhh, nic nie powinno Cię ograniczać ;p