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.

Symulacja Proteus Atmega32 LCD

04 Paź 2010 19:18 3039 10
  • Poziom 11  
    Witam

    Mam zbudowany układ zgodnie z schematem w Proteus. Rzeczywisty układ działa, natomiast w symulowanym nie działa wyświetlacz. Co mam zrobić, aby działał mi również w symulatorze?

    Symulacja Proteus Atmega32 LCD
  • Poziom 10  
    Nie znam się na tym programie, ale chyba nie masz podłączonego zasilania pod wyświetlacz?
  • Poziom 11  
    Po podłączeniu zasilania wyświetlacz również nic nie pokazuje.
  • Poziom 10  
    Potencjometr do VREF też podłączyłeś? Kiedyś w realu też się zastanawiałem czemu nie działa i okazało się ze nie ustawiłem kontrastu potencjometrem ;)
  • Poziom 11  
    Podłączenie potencjometru i zasilania do wyświetlacza nie daje żadnego efektu.

    Symulacja Proteus Atmega32 LCD
  • Poziom 10  
    A spróbuj jescze VREF dać całkiem do masy. Jeśli ten wyświetlacz ma "sterownik" HD44780 to zaraz po poprawnym podłączeniu go choćby samego do zasilania powinny się pojawić czarne prostokąty w pierwszej linijce
  • Poziom 12  
    Jeśli chodzi schemat to jest wszystko ok, u mnie w symulacji działa na prostym programiku napisanym w bascomie (bo C nie znam). Radzę więc posprawdzać od strony programowej.
  • Poziom 19  
    _lukas masz wszystko dobrze w kodzie (jeśli działa w rzeczywistości tak jak napisałeś to w poście).

    Nie jest to tak jak napisał:

    Remus napisał:
    Jeśli chodzi schemat to jest wszystko ok, u mnie w symulacji działa na prostym programiku napisanym w bascomie (bo C nie znam). Radzę więc posprawdzać od strony programowej.


    Wszystko za sprawą owego programu, w którym symulujesz. Zapewne _lukas odczytujesz flagę zajętości, a to w Proteus'ie nie przejdzie. Sam kiedyś to próbowałem zrobić :). Wytłumaczenie jest proste. Otóż Bascom domyślnie działa na opóźnieniach i pin E jest nie używany, więc LCD działa.

    Rozwiązanie twojego problemu może być następujące, tak jak w moim przypadku. Umieść sobie w programie dyrektywy na czas symulacji. Jeśli masz zamiar symulować to po prostu wklepujesz definicję:

    Code:
    #define lcd_symulacja


    W funkcji, w której odczytujesz wyżej wspomnianą flagę po prostu dajesz opóźnienie. To wszystko co musisz zrobić.
  • Poziom 11  
    Po wprowadzeniu programu napisanego w bascomie do symulatora od Remusa wyświetlacz działa.

    Co i gdzie mam wprowadzić w kodzie napisanym w C, aby wyświetlacz działał w symulatorze? y0yster mógłbyś pokazać przykład swojego programu do obsługi LCD, gdzie wprowadzasz tą dyrektywę?
  • Poziom 19  
    Program w Bascom'ie działa dlatego, że w ogóle nie odczytuje flagi zajętości, chociaż można go do tego zmusić wykorzystując jakąś bibliotekę. Wszystko to jest opisane w pomocy.

    Przepraszam za wprowadzenie w błąd. Rzecz nie tkwi w odczekiwaniu ale w sposobie odczytywania busy flag. Oczywiście rozpatrując wyżej wymienioną konfigurację.

    Ja odczytuję busy flag tak (przypadek rzeczywisty):
    Code:

            do
            {

                //czekamy chwilke, az zaskoczy
                _delay_us( 2 * F_CPU / 1000000 + 2);

                //pierwszy impuls
                sbi( lcd_wire_port, lcd_E_wire);

            }while( bit_is_set( lcd_data_bus_pin, lcd_busy_flag));

            //odbieramy dane (MSB)
            lcd_address = lcd_data_bus_pin;

            //moze delay ??? na 1us
            _delay_us( 3);

            //stan niski na E
            cbi( lcd_wire_port, lcd_E_wire);

            //czekamy chwilke
            _delay_us( 3);

            //przetwarzamy dane, obcinajac busy flag
            lcd_address &= 0b01110000;

            //drugi impuls
            sbi( lcd_wire_port, lcd_E_wire);

            //czekamy chwilke
            _delay_us( 3);

            //pobieramy dane (LSB)
            lcd_address = lcd_address | (lcd_data_bus_pin >> 4);

            //stan niski na E
            cbi( lcd_wire_port, lcd_E_wire);
       
            //_delay_us( 3);

            //przelaczamy sie na wyjscie
            lcd_data_bus_ddr |= 0b11110000;   

            cbi( lcd_wire_port, lcd_RW_wire);


    W przypadku symulacji pod Proteusem sprawa wygląda następująco.

    Code:

            do
            {
                //pierwszy impuls
                sbi( lcd_wire_port, lcd_E_wire);

                //czekamy chwilke, az zaskoczy
                _delay_us( 2 * F_CPU / 1000000 + 2);

                //odbieramy dane (MSB)
                lcd_address = lcd_data_bus_pin;

                //stan niski na E
                cbi( lcd_wire_port, lcd_E_wire);

                //czekamy chwilke
                _delay_us( 3);
                //przetwarzamy dane, obcinajac busy flag
                lcd_address &= 0b01110000;

                //drugi impuls
                sbi( lcd_wire_port, lcd_E_wire);

                //czekamy chwilke
                _delay_us( 3);

                //pobieramy dane (LSB)
                lcd_address = lcd_address | (lcd_data_bus_pin >> 4);

                //stan niski na E
                cbi( lcd_wire_port, lcd_E_wire);
       
                _delay_us( 3);

            }while( bit_is_set( lcd_data_bus_pin, lcd_busy_flag));

            //przelaczamy sie na wyjscie
            lcd_data_bus_ddr |= 0b11110000;   

            cbi( lcd_wire_port, lcd_RW_wire);



    Jak wygląda sprawa z dyrektywami:

    Code:


    #ifdef lcd_symulacja
    lcd_wait_until_ready()
    {
    //kod odpowiedzialny za poprawne działanie podczas symulacji
    }

    #endif

    #ifndef lcd_symulacja
    lcd_wait_until_ready()
    {
    //kod odpowiedzialny za poprawne działanie podczas normalnej pracy
    }


    Domyślnie jak widzisz wykona się druga funkcja. Natomiast kiedy w programie umieścisz:

    #define lcd_symulacja

    Skompilowana zostanie pierwsza funkcja :).

    Mam nadzieję, że pomogłem.
    Pozdrawiam.
  • Poziom 11  
    Skorzystałem z innych bibliotek do obsługi LCD i symulacja działa właściwie, tak jak na rzeczywistym układzie.