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.

Atmega32 LCD+ klawiatura, dlaczego program się sypie?

30 Mar 2008 23:06 1449 2
  • Poziom 11  
    Witam.
    Zacznę od konfiguracji.Do portu A atmegi32 mam podłączone wyświetlacz LCD 4x16 w trybie 4 bitowym bez odczytu flagi co powoduje że zarządzam także sygnałami E i RS(r/w do masy).Oczywiście piny danych wyświetlacza są podłączone do bitów najstarszych uC. Do tych samych pinów (PA7, PA6,PA5,PA4) mam podłączone 4 linie od klawiatury matrycowej które są zwarte do masy przez rezystor 4k7.Problem polega na tym że nie mogę zrobić pętli opóźniającej gdy przycisnę przycisk tzn. gdy nacisnę na czas krótszy niż ok 2 s jest wszystko OK; jeśli natomiast na czas dłuższy podczas trzymania przycisku na LCD zostają wyświetlone znaki których nie chce. I teraz pytanie dlaczego się tak dzieje skoro dla czasu krótszego jest wszystko ok, natomiast dla czasu dłuższego program się sypie? Dlaczego prosta pętla tu nie pomaga( podczas tej pętli także się wyświetlają znaki?

    DDRA = 0x0f; //ustawiane portu A w stan wejścia //rs=1 ie=1
    PORTA = 0x0f;
    PINA = 0x0f;

    switch(PINA){

    case (0X8f):
    while(PINA & 1<<7)czekajms(255);

    .....
    zapis_text("A");
    .......
  • Poziom 38  
    Pokaż kawałek więcej kodu.

    Dodano po 1 [minuty]:

    Na pewno nie ruszasz linią Enable w trakcie odczytu klawiatury?
  • Poziom 11  
    no linią E i RS ruszam poprzez komendy :

    DDRA = 0x0f; //ustawiane portu A w stan wejścia //rs=1 ie=1
    PORTA = 0x0f;
    PINA = 0x0f;

    Na starszej połówce mam klawiature i dane LCD a na młodszej mam E i RS i 2 linie sterujące jednak nie są one ważne.

    Dodano po 3 [minuty]:

    Code:
     //#include <until\delay.h>
    
     #include <avr/io.h>
     #define LCD  PORTA
     #define HD44780_DDRAM_SET            0x80
     #define E  3
     #define RS  2
     //
     #define SET_E   LCD |= _BV(E)
     #define CLR_E   LCD &= ~_BV(E)
     //
     #define SET_RS  LCD |= _BV(RS)
     #define CLR_RS  LCD &= ~_BV(RS)
     #define HD44780_DDRAM_SET 0x80
     #define HD44780_CGRAM_SET            0x40
     
     
     


     ////////////////////////////// Obsługa WYŚWITLACZA LCD /////////////////////////////////
     
     // funkcja opóźniająca o x*1ms
     void czekajms(char x){
     
       unsigned char a, b;                           // zmnienne licznikowe
          for( ; x > 0; --x)                       // ta pętla zostanie wykonana x-razy
             for(b = 10; b > 0; --b)              // a ta 10 razy
                for(a = 100; a > 0; --a)         // natomiast ta 100 razy
                   __asm("nop");                 // dodatkowa instrukcja opóźniająca o 1 cykl
                                                  
       
       // razem to da opóźnienie ok. x * 1ms
       // x od 0 do 255
       
     }

     
     
     
     
     // pcodedura zapisu bajtu do wyświetlacza LCD
     // bez rozróżnienia instrukcja/dana
     void zapis_do_LCD(char x){
     
       SET_E;                                  // ustaw na E stan wysoki
       LCD = ((LCD & 0x0F) | (x & 0xF0));          // zapis pierwszej połówki bajtu
       CLR_E;                                  // opadające zbocze na E -> zapis do wyświetlacza
       SET_E;                                  // ustaw na E stan wysoki
       LCD = ((LCD & 0x0F) | ((x & 0x0F) << 4));    // zapis drugiej połowki bajtu
       CLR_E;                                 // opadające zbocze na E -> zapis do wyświetlacza
       
       czekajms(1);                               // czekaj 1ms
     }

       

     
     
     
     
     // procedura zapisu instrukcji do wyświetlacza LCD
     void zapis_komenda(char x){
       
       CLR_RS;                                 // niski stan na RS -> zapis instrukcji
       zapis_do_LCD(x);                         // zapis do LCD
     
     }


     
     
     
     
     
     // procedura zapisu danej do wyświetlacza LCD
     void zapis_znak(char x){
     
       SET_RS;                               // wysoki stan na RS -> zapis danej
       zapis_do_LCD(x);                         // zapis do LCD
                      
     }



     
     
     
     
     // procedura zapisu tekstu do wyświetlacza LCD
     void zapis_text(char * s){
     
       while(*s){                                     // do napotkania 0
          
          zapis_znak(*s);                      // zapisz znak wskazywany przez s na LCD
          s++;                               // zwiększ s (przygotuj nastepny znak)
       }
       
     }



     
     
     
     
     // procedura skoku na ustalone miejsce wyświetlacza LCD
     void Skok_LCD(unsigned char x, unsigned char y){
     
       zapis_komenda(HD44780_DDRAM_SET | (x + (0x40 * y)));
                                                     
     }



     
     
     
     
     // procedura inicjalizacji wyświetlacza LCD
     void lcd_init(void){
     
       czekajms(15);                            // czekaj 15ms na ustabilizowanie się napięcia zasilającego
       CLR_E;                                  // E = 0
       CLR_RS;                               // RS = 0
       char i;                               // zmianna licznikowa
       for(i = 0; i < 3; i++){                   // trzykrotne powtórzenie bloku instrukcji
       
          SET_E;                               // E = 1
          LCD &= 0x3F;                         //
          CLR_E;                               // E = 0
          
          czekajms(5);                            // czekaj 5ms
        }
       
       SET_E;                                  // E = 1
       LCD &= 0x2E;                            //
       CLR_E;                                  // E = 0
     
       czekajms(1);                               // czekaj 1ms

       zapis_komenda(0x28);                      // interfejs 4-bity, 2-linie, znak 5x7
       zapis_komenda(0x08);                     // wyłącz LCD, kursor i miganie
       zapis_komenda(0x01);                      // czyść LCD
       zapis_komenda(0x06);                      // bez przesuwania w prawo
       zapis_komenda(0x0C);                      // włącz LCD, bez kursora i mrugania

     }


     
     
     
     
     // procedura ustawiająca LCD
     void moje(void){
     
       czekajms(15);                            // czekaj 15ms na ustabilizowanie się napięcia zasilającego
       CLR_E;                                  // E = 0
       CLR_RS;                               // RS = 0
       char i;                               // zmianna licznikowa
          for(i = 0; i < 3; i++){                // trzykrotne powtórzenie bloku instrukcji
       
             SET_E;                            // E = 1
             LCD &= 0x3F;                      //
             CLR_E;                            // E = 0
             
             czekajms(5);                         // czekaj 5ms
          }
             
       SET_E;                                  // E = 1
       LCD &= 0x2E;                            //
       CLR_E;                                  // E = 0
       czekajms(10);                            // czekaj 1ms
       
     }



     
     
     ////////////////////////// koniec procedury obsługi wyświetlacza LCD ////////////////////




       
       

     ////////////////////////////////// Obsługa KLAWIATURY////////////////////////////////////
     
     // procedura naprzemiennego ustawiania "potru A" jako wejścia i wyjścia
     void przygotuj(int zapis){
     
       
       if(zapis == 1){
          
          //przygotowanie LCD do przyjecia znaków; stabilizacja poziomów zasialania;
          //ustawienie portu A jako wyjścia
     
          czekajms(255);                  
          DDRA = 0xFF;
          PORTA = 0xFF;
          //zapis_komenda(HD44780_DDRAM_SET);
          //zapis_komenda(HD44780_CGRAM_SET);
          czekajms(100);
          moje();
          Skok_LCD(0,0);
       }
       
       else {
       
          //przygotowanie klawiatury do obsługi; stabilizacja poziomów zasialania;
          //ustawienie portu A jako wejścia
          
          //zapis_komenda(HD44780_DDRAM_SET);
          czekajms(100);
          DDRA = 0X0f;
          PORTA = 0x0f;
          PINA = 0x0f;
       }
     }
     
     
     
     
     // procedura detekcji klawiszy
     void klawiatura(void){
       
       while(1){
       
       DDRA = 0x0f;                      //ustawiane portu A w stan wejścia 4 najstarsze bity
       PORTA = 0x0f;
       PINA = 0x0f;
       
          
          PORTC = 0x80;
          switch(PINA){
                      
             case (0X8f):
             while(PINA & 1<<7){  //<------------------------
                czekajms(255);  //<------------------------
                      }
             
                
             przygotuj (1);
             zapis_text("A");
             przygotuj (0);
                
                
                
                
             przygotuj (0);

             break;
             
             case (0X4f): //0100 1001 =0
                //while(PINA ==0X4f);
                przygotuj (1);
                zapis_text("Litera nr B");
                przygotuj (0);

             break;
             
             case (0X2f): //0100 1001 =0
                while(PINA ==0X2f);
                przygotuj (1);
                zapis_text("LiteraC");
                przygotuj (0);

             break;
             
             case (0X1f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera ");
                przygotuj (0);

             break;
       
       
       default:

    PORTC = 0x40;

       switch(PINA){

             case (0X8f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr t                     ");
                przygotuj (0);

             break;
             
             case (0X4f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr y                     ");
                przygotuj (0);

             break;
             
             case (0X2f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr u                     ");
                przygotuj (0);

             break;
             
             case (0X1f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr i                     ");
                przygotuj (0);         
             break;
       
       
       default:
       PORTC = 0x20;
          
          switch(PINA){

             case (0X8f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr p                     ");
                przygotuj (0);

             break;
             
             case (0X4f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr v                     ");
                przygotuj (0);
             break;
             
             case (0X2f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr m                     ");
                przygotuj (0);
             break;
             
             case (0X1f): //0100 1001 =0
          
                przygotuj (1);
                zapis_text("Litera nr k                     ");
                przygotuj (0);

             break; 
       default:
       break;   
       
       }

     
       
       }
       
       
             }
             
          }}


     
     /////////////////////////// koniec procedury obsługi klawiatury ///////////////////////////////////
     
     
     

     

    // procedura pierwszego uruchomienia
     void Inicjuj(void){
     
      int a;
     
        zapis_text("        Witaj       ");
       
       for(a=2 ; a > 0; --a)
          czekajms(255);
        
       zapis_text("  Wproawdza kod :       ");
       
       
       
       
       
       klawiatura();
       
       
     }

       





    // program główny
     int main(void){
     
    // konfiguracja portów we/wy
     DDRA = 0xFF;
     PORTA = 0xFF;
     DDRC = 0xff;
     PORTC = 0x80;


    //inicjacja wyświetlacza
     lcd_init();

    //pierwsze uruchomienie
     Inicjuj();


    return 0;
    }


    Zaznaczyłem interesujące mnie miejsce na listingu.

    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]