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.

Atmega16 + LCD - niepewność co do poprawności

andrzejlisek 14 Lis 2010 20:05 687 0
  • #1
    andrzejlisek
    Poziom 28  
    Posiadam symulator układów elektronicznych, przerysowałem do niego pewien układ z Atmegą16 i wyświetlaczem LCD 2x16 na HD44780. Nie posiadam tego układu w rzeczywistości.

    Chciałem napisać procedurę oczekującą na aktywność wyświetlacza LCD (wywoływana bezpośrednio po każdej procedurze wysyłającej rozkaz lub dane na LCD). Zapisanie całego wyświetlacza (32 znaki) z wykorzystaniem trwa pok. 1 sekundę (widać po kolej pojawiające się znaki), a z wykorzystaniem "_delay_us(50)" trwa momentalnie, tak, jak powinno być, a teoretycznie "LcdWait()" powinien trwać krócej niż 50us, bo czeka tylko tyle, ile trzeba, a nie 50us.

    Okazało się, że projekt w symulatorze działa dużo wolniej niż jak było sztywne oczekiwanie pewnego okresu czasu (2ms dla rozkazu "0x01" lub 50ns dla pozostałych rozkazów). Nie mam pewności, czy to opóźnienie, to wina symulatora (duża ilość obliczeń), czy błąd w procedurze oczekiwania.

    Wyświetlacz jest oparty na HD44780 i podłączony do Atmega16 według następującego porządku
    Code:
    LCD - Atmega16
    
    RS  - PORTC.5
    RW  - PORTC.4
    E   - PORTA.3
    D4  - PORTC.0
    D5  - PORTC.1
    D6  - PORTC.2
    D7  - PORTC.3


    Czy podana poniżej procedura oczekiwania na aktywność wyświetlacza jest poprawna? Nie mam jak sprawdzić na rzeczywistym układzie, bo go nie posiadam.

    Code:
    void LcdWait()
    
    {
     unsigned char Test = 1; // Zmienna jako liczba z zakresu od 0 do 255, początkowo wartość różna od 0
     DDRC = 0xF0;            // Linia 0,1,2,3 jako linie wejścia, a linie 4,5,6,7 jako wyjscia
     PORTC = 0x10;           // Jedynka na RW
     while (Test > 0)        // Czy liczba Test większa od 0?
                             // Wartość tej liczby zależy tylko od stanu flagi zajętości
     {
      PORTA |= 0x08;         // Jedynka na linii E
      _delay_us(1);          // Nie wiem, czy potrzeba, ale chodzi o to, żeby wyświetlacz wystawił odpowiednie dane na piny zanim zostanie dokonany odczyt
      Test = PINC;           // Odczyt 4 starszych bitów bajtu określający stan wyświetlacza
      PORTA &= 0xF7;         // Zero na linii E
      PORTA |= 0x08;         // Jedynka na linii E
      _delay_us(1);          // Nie wiem, czy potrzeba, ale chodzi o to, żeby wyświetlacz wystawił odpowiednie dane na piny zanim zostanie dokonany odczyt
      // Tu nastąpiłby odczyt 4 młodszych bitów bajtu określającego stan wyświetlacza, ale nie następuje, bo te bity nie są potrzebne
      PORTA &= 0xF7;         // Zero na linii E
      Test = Test & 0x08;    // Bit flagi zajętości pozostaje niezmieniony, inne bity są zerowane
     }

     // Tu program wejście dopiero wtedy, gdy wyświetlacz LCD może przyjąć nowy rozkaz
     // Poniższe operacje nie są wymagane, ale przywracają stan sprzed wywołania procedury w moim programie
     PORTC = 0x00;
     DDRC = 0xFF;
    }