Forum graficzne Burning-Brushes.pl

Minigra na mikrokontroler 8051

Abik

  • VIP
  • *****
    • Amerykański plastik
      • Zobacz profil
    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

    • VIP
    • *****
      • Stranger in a strange land
        • Zobacz profil
        • Moonmaker on dA


      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