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.

Wyświetlanie na LCD liczby z rejestru (integer)

02 Wrz 2005 13:17 2299 4
  • Poziom 40  
    Witam,

    Mam taki problem - napisałem sobie procedury do obsługi wyświetlacza LCD, nie mogę tylko poradzić sobie z wyświetleniem na LCD zawartości rejestru (16 bitowy). Procesor ATmega 8.
    Próbowałem takie coś:

    Code:
    void pisz_int(unsigned int t)
    
    {
       unsigned char bufor[20];
       itoa(t,bufor,10);
       pisz_text(bufor);   
    }


    ale nie działa przy wyświetlaniu rejestru (próbuję wyświetlić zawartość TIMER1)...


    Wiem że w rejestrze jest wartość 63034 (11110110 00111010).
    Jeżeli wyświetlam tak:
    Code:
    pisz_int(TCNT1)
    to otrzymuję wynik -2502.

    Jeżeli wyświetlam tak:
    Code:
    pisz_int(TCNT1H);
    
    pisz_int(TCNT1L);

    to otrzymuję 0 oraz 58.

    Przypuszczam że dzieję się tak ponieważ najstarszym bitem jest 1 co jest traktowane jako zapis liczby ujemnej.
    Być może źle wywołuję procedurę...

    Jeżeli wyświetlam to w systemie binarnym lub szesnastkowym (zmiana parametru przy itoa) to wynik jest prawidłowy - tyle że binarnie albo szesnastkowo :D

    Próbowałem tez najpierw przepisaćliczbędo zmiennej (unsigned int i; i=TCNT1 albo i=63000) i potem pisz_int(i); ale wynik znowu był liczbą ujemną...
    Proszę o wskazówki , może ktoś wklei gotową (sprawdzoną) procedurę do pisania liczby typu integer??


    Pozdrawiam...

    PS. Gdyby było potrzebne zamieszczam pozostałe procedury wyświetlacza:
    Code:
    //--------------------------------Procedury obsługi wyświetlacza LCD-------------------------------------------
    

    // procedura zapisu bajtu do wyświetlacza LCD bez rozróżnienia instrukcja/dana
    void lcd_pisz(unsigned char x)
    {
       unsigned char y;
       
       SET_E;             // ustaw na E stan wysoki
    //na linie DB4..7 wystawia starszy półbajt liczby x
       y=x>>4;
       if (y % 2) SET_D4;         //jeżeli reszta z dzielenia x przez 2 wynosi 1 to ustawia bit, jeżeli 0 - kasuje
       else CLR_D4;
       y>>=1;                  //przesuwa o jedną pozyję w lewo i sprawdza kolejny bit
       if (y % 2) SET_D5;         
       else CLR_D5;
       y>>=1;            
       if (y % 2) SET_D6;      
       else CLR_D6;
       y>>=1;            
       if (y % 2) SET_D7;         
       else CLR_D7;   
       asm("nop");
       asm("nop");
       asm("nop");
        CLR_E;             // opadające zbocze na E -> zapis do wyświetlacza
       
       asm("nop");
       asm("nop");
       asm("nop");

        SET_E; // ustaw na E stan wysoki   
    //czyści pola bitowe DB4..7 a następnie dodaje tam młodszy półbajt liczby x       
       if (x % 2) SET_D4;         //jeżeli reszta z dzielenia x przez 2 wynosi 1 to ustawia bit, jeżeli 0 - kasuje
       else CLR_D4;
       x>>=1;                  //przesuwa o jedną pozyję w lewo i sprawdza kolejny bit
       if (x % 2) SET_D5;         
       else CLR_D5;
       x>>=1;            
       if (x % 2) SET_D6;      
       else CLR_D6;
       x>>=1;            
       if (x % 2) SET_D7;         
       else CLR_D7;   
       asm("nop");
       asm("nop");
       asm("nop");

        CLR_E;             // opadające zbocze na E -> zapis do wyświetlacza
       
       czekaj(1000);       // czekaj 1ms
    }

    //zapis instrukcji do LCD
    void pisz_instrukcje(char x)
    {
       CLR_RS;             // niski stan na RS -> zapis instrukcji
       lcd_pisz(x);           // zapis do LCD
    }

    //procedura czyszczenia wyświetlacza
    void czysc_lcd(void)
    {   
       lcd_pisz(0x01);      //polecenie wyczyszczenia wyświetlacza
       czekaj(2000);         //należy odczekać min. 1,64ms
    }

    // procedura inicjalizacji wyświetlacza LCD
    void lcd_init(void)
    {
       czekaj(30000);          // czeka 30ms na wyzerowanie sterownika LCD
       CLR_E;                // E = 0
       CLR_RS;             // RS = 0

       for(i=0; i<3; i++)
         {
            SET_E;              // E = 1
            CLR_D7; CLR_D6; SET_D5; SET_D4;      // przesyła $3X (0011x bin) do wyświetlacza
            asm("nop");                  
            asm("nop");
            asm("nop");
            CLR_E;              // E = 0
            czekaj(5000);       // czekaj 5ms
         }

       SET_E;                // E = 1
       CLR_D7; CLR_D6; SET_D5; CLR_D4;         // przesyła $2X (0010x bin) do wyświetlacza
       asm("nop");
       asm("nop");
       asm("nop");
       CLR_E;                // E = 0
       czekaj(1000);          // czekaj 1ms
       
       pisz_instrukcje(0x28);       // interfejs 4-bity, 2-linie, znak 5x7
       pisz_instrukcje(0x08);       // wyłącz LCD, kursor i miganie
       czysc_lcd();            // czyści LCD
       pisz_instrukcje(0x06);       // bez przesuwania w prawo
       pisz_instrukcje(0x0C);       //włącz LCD, bez kursora i mrugania
    }

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

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

    //procedura wyświetla na ekranie liczbę integer
    void pisz_int(unsigned int t)
    {
       unsigned char bufor[20];
       itoa(t,bufor,10);
       pisz_text(bufor);   
    }

    //własna procedura która tłumaczy zapis "matrycowy" (wiersz x kolumna) na adres wyświetlacza
    //i umieszcza kursor we wskazanym miejscu na wyświetlaczu
    void ustaw_kursor(unsigned char w, unsigned char k)
    {
       switch (w)
       {
          case 1: pisz_instrukcje(((w-1)*0x40+k-1)|0x80); break;      //wstawia w pierwszym rzędzie
          case 2: pisz_instrukcje(((w-1)*0x40+k-1)|0x80); break;    //wstawia w drugim rzędzie
          case 3: pisz_instrukcje((((w-3)*0x40+k-1)|0x80)+0x14); break;   //3 rząd jest przedłużeniem 1-go
          case 4: pisz_instrukcje((((w-3)*0x40+k-1)|0x80)+0x14); break;   //4 rząd jest przedłużeniem 2-go   
       }   
    }         
    //-------------------------------------------------------------------------------------------------------------
  • Pomocny post
    Poziom 17  
    Jezeli masz taka funkcje jak sprint to zrob tak
    sprintf(Buffer,"WYSWIETLAMY LICZBE =%d ",LICZBA);
    %d - oznacza ze jest to format dziesietny ze smienna iloscia znakow
    LICZBA - rejestr typu int do wyswietlenia
    Buffer - bufot tekstowy w ktory otrzymasz dla liczby 6453 " WYSWIETLAMY LICZBE= 6453"
    czyli tekstowy czysto, latwy do wyslania na LCD

    Pozdrawiam Grzegorz
  • Poziom 40  
    OK, problem rozwiązany. Funkcja itoa() działała na INTEGER, co dla tego kompilatora (avr-gcc) oznaczało zakres -32767...32768 (czy coś koło tego :D). Zmieniłem tą funkcję na ltoa() i już śmiga.
    PS. Czy moze ktoś wrzucić linka z zakresem poszczególnych zmiennych bo coś nie mogę znaleźć? :D
  • Pomocny post
    Poziom 19  
    char: -128..127
    unsigned char 0..255
    int -32768..32767
    unsigned int 0..65535
    long -2147483648..2147483647
    unsigned long 0..4294967295
  • Poziom 40  
    Dziekuje za pomoc, temat zamkniety.