Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Jak napisać program? Klawiatura 3x3, wyświetlanie numeru przycisku.

16 Kwi 2006 08:19 2022 5
  • Poziom 9  
    Prosze o pomoc przy napisaniu programu w jzyku C który powinien dzialac w nastepujacy sposób: Przy uzyciu klawiatury kodoanej 3x3 ma wyswietlic mi na wyswietlaczu numer przyciskanego pzycisku który przycisne na klawiaturze.
    Z góry dziekuje
  • Poziom 15  
    Musisz podać więcej szczegółów:
    - jaki procesor,
    - jaki wyświetlacz,
    - jak podłączony wyświetlacz,
    - jak podłączona klawiatura,
    - ...
    Najlepiej bedzie jak załączysz schemat

    Poniżej masz przykład obsługi klawiatury matrycowej 4x4 z książki "Mikrokontrolery AVR w praktyce"

    Code:

    /****************************************************************/
    /* Ćwiczenie 5 - Obsługa klawiatury matrycowej z wykorzystaniem */
    /*               przerwań timera0                               */
    /*             - wykorzystanie wyświetlacza LCD 16*2            */
    /*             - prosta gra zręcznościowa                       */
    /* J.D. '2003                                                   */
    /****************************************************************/
    #include <io.h>
    #include <interrupt.h>
    #include <signal.h>

    #define lcd_rs 2       //definicja bitu portu dla linii RS
    #define lcd_e 3        //definicja bitu portu dla linii E
    #define tau0 247       //stała czasowa timera0
    #define vliczt0 113    //stała wpisywana do licznika wejść do
                           //do przerwania timera0
    #define vlkursor 10    //wartość wpisywana do zmiennej lkursor

    //********************  zmienne globalne  *******************
    unsigned char liczt0;  //Licznik wejść do przerwania timera0.
                           //Klawisz jest badany, gdy liczt0=0
    unsigned char lkursor; //licznik wejść do przerwania timera0 dla
                           //ustawienia flagi zmiany położenia "lisa"       
    volatile unsigned char kodklaw;  //kod naciśniętego klawisza;
    volatile unsigned char fklaw;    //flaga wykrycia naciśnięcia klawisza;
    volatile unsigned char fkursor;  //flaga zmiany położenia "lisa"
    unsigned char wiersz=0;          //pozycja umieszczenia znaku na LCD
    unsigned char kolumna=0;         //pozycja umieszczenia znaku na LCD

    void czekaj(unsigned long zt) //procedura wytracania czasu
    {
    #define tau 10.38      //przybliżony przelicznik argumentu na ms
     unsigned char zt1;
     
     for(;zt>0;zt--)
     {
      for(zt1=255;zt1!=0;zt1--);
     }
    }

    SIGNAL (SIG_OVERFLOW0)  //obsługa przerwania od przepełnienia timera0
    {
     unsigned char kkolumna,kwiersz; //zmienne pomocnicze
     TCNT0=tau0;            //odśwież stałą czasową w TCNT0
     
     if(--liczt0==0)        //czy już czytać klawisze?
     {                      //tak
      for(kkolumna=0xfe;kkolumna!=0xfb;kkolumna=(kkolumna<<1)+1)
      {
       PORTD=(PORTD|0x03)&(kkolumna);    //podaj "0" na linię sterującą aktywną kolumną
       kwiersz=PIND&0x0f;  //pozostaw tylko linie obsługujące klawiaturę
       if((kwiersz&0x0c)^0x0c)    //czy jest odpowiedź na jakiejś linii wierszy?
       {                          //tak, ustaw flagę gotowości klawiatury
        fklaw=1;
        break;                    //i zakończ przepatrywanie
       }
      }
      if(fklaw)
      {
       kodklaw=kwiersz;    //jeśli wykryto wciśnięcie klawisza, podaj jego kod       
      }
      else
      {
       kodklaw=0xff;       //jeśli nie, ustaw kod neutralny
      }
      liczt0=vliczt0;      //odśwież stan liczt0
      if(--lkursor==0)     //czy można ustawić flagę zmiany "lisa"?
      {
       fkursor=1;          //tak (minęło ok. 300ms)
       lkursor=vlkursor;   //odśwież stan lkursor
      }
     }
    }

    void piszilcd(unsigned char instr) //zapisz instrukcję sterującą do LCD
    {
     cbi(PORTB,lcd_rs);
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|(instr&0xf0);  //przygotuj starszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD ok. 100us
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|((instr&0x0f)<<4);  //przygotuj młodszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD ok. 100us
    }

    void piszdlcd(char dana)           //zapisz daną do LCD
    {
     sbi(PORTB,lcd_rs);
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|(dana&0xf0);   //przygotuj starszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|((dana&0x0f)<<4); //przygotuj młodszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD
    }

    void czysclcd(void)                //czyść ekran
    {
     piszilcd(0x01);      //polecenie czyszczenia ekranu dla kontrolera LCD
     czekaj(1.64*tau);    //rozkaz 0x01 wykonuje się 1.64ms
     wiersz=0;
     kolumna=0;
    }

    void lcdxy(unsigned char w, unsigned char k)    //ustaw współrzędne kursora
    {
     piszilcd((w*0x40+k)|0x80);  //standardowy rozkaz sterownika LCD
                                 //ustawiający kursor w określonych współrzędnych
    }

    void piszznak(char znak)    //procedura umieszcza znak na wyświetlaczu
    {
     piszdlcd(znak);            //wyświetl znak na LCD
    }

    unsigned char incwiersz(unsigned char w)  //inkrementuj wiersz LCD
    {
     return w==1?0:1;
    }

    unsigned char decwiersz(unsigned char w)  //dekrementuj wiersz LCD
    {
     return w==0?1:0;
    }

    unsigned char inckolumna(unsigned char k) //inkrementuj kolumnę LCD
    {
     return k==15?0:++k;
    }

    unsigned char deckolumna(unsigned char k) //dekrementuj kolumnę LCD
    {
     return k==0?15:--k;
    }

    int main(void)         //program główny
    {
     unsigned char r,i;    //zmienne pomocnicze
     unsigned char xg=0;   //kolumna wyświetlania kursora gracza
     unsigned char yg=0;   //wiersz wyświetlania kursora gracza
     
     liczt0=vliczt0;
     lkursor=vlkursor;
     PORTD=0xff;           //z podciąganiem
     PORTB=0x03;           //z podciąganiem wejść
     DDRD=0x03;            //PD0-PD1 wy, pozostałe wejścia
     DDRB=0xff;            //PORTB - wy
     TIMSK=1<<TOIE0;       //zezwolenie na przerwania od TC0
     TCNT0=tau0;           //wpisz stałą czasowa do TCNT0
     TCCR0=4;              //preskaler XTAL/256,
                           //kwant mierzonego czasu = 32<m>s
     fklaw=0;
      //>>>>>>>>>>>>>>>>>>   inicjacja wyświetlacza LCD   <<<<<<<<<<<<<<<<<<<<<<
     czekaj(45*tau);        //opóźnienie ok. 45ms dla ustabilizowania się napięcia
                            //zasilania LCD (katalogowo min. 15 ms)
                            //lcd_rs już wcześniej było ustawione w stanie "0"
     for(i=0;i<3;i++)       //3-krotne wysłanie 3-
     {
      sbi(PORTB,lcd_e);
      PORTB=(PORTB&0x0f)|0x30; //wyślij 3- do LCD
      asm("nop");
      asm("nop");
      asm("nop");
      cbi(PORTB,lcd_e);
      czekaj(5*tau);      //ok. 5ms
     }
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|0x20;  //wyślij 2- do LCD
     asm("nop");               //wymagane wydłużenie impulsu
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);     //impuls strobujący
     czekaj(10L);
     piszilcd(0x28);       //interfejs 4-bitowy, 2 linie, znak 5x7
     piszilcd(0x08);       //wyłącz LCD, wyłącz kursor, wyłącz mruganie
     piszilcd(0x01);       //czyść LCD
     czekaj(1.64*tau);     //wymagane dla instrukcji czyszczenia ekranu opóźnienie
     piszilcd(0x06);       //bez przesuwania w prawo
     piszilcd(0x0c);       //włącz LCD, bez kursora, bez mrugania
     sei();                //odblokuj globalne przerwania
     i=0;

     piszznak('S');        //wyświetl napis "Start"
     piszznak('t');
     piszznak('a');
     piszznak('r');
     piszznak('t');
     
     do
     {
      i++;                 //zmienna "i" będzie wykorzystana później do zainicjowania
                           //generatora pseudolosowego
     }while(!fklaw);       //naciśnięcie klawisza zapewnia losowy start generatora
     srand(i);             //inicjuj generator liczb pseudolosowych
     czysclcd();           //czyść ekran
     piszznak('+');        //umieść znak gracza na ekranie
     
     while(1)              //główna pętla programu
     {
      if(fkursor)          //czy można przemieścić "lisa"?
      {
       lcdxy(wiersz,kolumna);  //tak...
       if((wiersz==yg)&&(kolumna==xg))
       {
        piszznak('+');      //wymaż starą pozycję pozostawiając gracza
       }
       else
       {
        piszznak(' ');      //wymaż starą pozycję
       }   
       r=rand();           //losuj nowe położenie
       if((r<37)&&(r>18))  //wylicz nową pozycję
       {
        wiersz=incwiersz(wiersz);
       }
       if(r<19)
       {
        wiersz=decwiersz(wiersz);
       }
       if(((r>12)&&(r<19))||((r>30)&&(r<147)))
       {
        kolumna=inckolumna(kolumna);
       }
       if((r<7)||((r<25)&&(r>18))||(r>146))
       {
        kolumna=deckolumna(kolumna);
       }   
       lcdxy(wiersz,kolumna);     //ustaw nowe współrzędne
       piszznak('.');      //umieść "lisa" w nowym położeniu
       fkursor=0;
      }
     
      if(fklaw)
      {                    //wykryto naciśnięcie klawisza
       fklaw=0;
       lcdxy(yg,xg);       //ustaw współrzędne znaku gracza...
       piszznak(' ');      //... i wymaż go
       switch (kodklaw)    //reakcja na klawisz
       {
        case 0x09:  xg=inckolumna(xg);      //SW4 - w prawo z zawijaniem
                    break;
        case 0x05:  xg=deckolumna(xg);      //SW3 - w lewo z zawijaniem
                    break;
        case 0x06:  yg=1;                   //SW2 - na dół bez zawijania
                    break;           
        case 0x0a:  yg=0;                   //SW1 - do góry bez zawijania
       }                               
       lcdxy(yg,xg);       //ustaw nowe współrzędne znaku gracza
       if((wiersz==yg)&&(kolumna==xg))
       {
        piszznak('*');     //znak, jeśli trafiony
        czekaj(200);        //przytrzymaj chwilę na ekranie
       }
       else
       {
        piszznak('+');     //znak jeśli "pudło"
       }
      }
     }
    }




    Z pozdrowieniami
    Marek
  • Poziom 9  
    Witam
    O to dokladnie mi nie chodzilo. Mam tutaj program ktory wyswietla numer klawisza na diodach w kodzie binarnym. prosilbym o przeksztalcenie tego programu aby zamiast na diodach to na wyswietlaczu wyswietlal mi numer klawisza.
    Z gory dziekuje
  • Poziom 9  
    Prosze o pomoc jak mam to zrobic albo jakas podpowiedz
  • Poziom 32  
    Na jakim wyświetlaczu ?
  • Użytkownik usunął konto