logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Kod w asemblerze do wyświetlania 'A' na LCD HD44780 - co poprawić?

y0yster 09 Cze 2007 08:45 4853 39
Najlepsze odpowiedzi

Jak poprawnie zainicjalizować wyświetlacz LCD HD44780 w asemblerze i wysłać na niego znak, skoro zamiast litery A pojawia się tylko czarna linia albo nic się nie wyświetla?

Trzeba poprawić mapowanie linii i samą inicjalizację: w końcu okazało się, że były ustawiane bity 7, 6 i 5, a sterowanie szło po bitach 2, 1, 0, więc LCD dostawał złe dane [#3970465] Dane należy wystawić na liniach najpierw, a dopiero potem podać impuls na EN, bo wyświetlacz zatrzaskuje dane opadającym zboczem EN [#3970206] Jeśli masz podłączone RW, po zakończeniu inicjalizacji lepiej odczytywać flagę busy zamiast opierać się wyłącznie na opóźnieniach [#3969200] Po komendzie `clear display` trzeba jeszcze odczekać około 5 ms, bo ta operacja może trwać do 4,9 ms; dopiero wtedy znak pozostaje na ekranie [#3970465]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 3967040
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Witam.

    Zacząłem sobie pisać prosty program, który wyświetlił bym mi literkę 'A' na lcd. Lecz jak zawsze to bywa w początkach troszkę się pogubiłem i mam problem z wyświetleniem tej literki.

    Załączam kod programu. Prosił bym o sprawdzenie co jest w nim żle. Z góry dziękuję i pozdrawiam.

    Dodam, że piszę w asemblerze. Plik został skompresowany 7-zipem, tylko rozszerzenie zostało zmienione.
    Załączniki:
    • main.zip (1.33 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • #2 3967115
    deseng
    Poziom 22  
    Posty: 263
    Pomógł: 68
    Ocena: 10
    Nie bardzo to się daje rozpakować (przynajmniej u mnie).
  • #3 3967405
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Ok. Skompresowałem zipem.

    Proszę o pomoc. może kod troszkę nie jasny, ale na pewno, będzie się dało to odczytać. Jeśli miał by ktoś jakiś przykład, który by wyświetlał jakąś jedną literkę :P to proszę, żeby wrzucił kod tutaj.
    Załączniki:
    • main.zip (1.33 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #4 3967418
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Nie piszesz co nie działa. Jeśli masz cały czas ciemne kwadraty na wyświetlaczu
    LCD to masz problem z inicjalizacją. Moim zdaniem masz tą procedurę do
    poprawy. Poczytaj sobie cykl artykułów o alfanumerycznych wyświetlaczach LCD:
    http://www.edw.com.pl/index.php?module=ContentExpress&func=display&ceid=68&meid=-1
    O inicjalizacji i sterowaniu też tam jest. Nie przedstawiłeś też schematu połączeń
    bo może tam też masz jakiś błąd.
  • #5 3967441
    migol
    Poziom 18  
    Posty: 313
    Pomógł: 4
    Ocena: 5
    Jasne ze masz skopana funkcja inicjalizująca. Nie pamiętam już jak dokładnie się to obsługiwało, bodaj trzeba 3 razy wyslac 30h jako komende, po kazdym razie czekajac ileśtam czasu i wtedy dopiero to odpalało.
  • #6 3967456
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Niestety nawet nie mam wszystkich czarnych prostokącików. Nie wiem, czy to coś zmienia jak nie mam wogóle podłączonego potencjometra do regulacji kontrastu w lcd'ku. Wszystko testuje z testboardzie. http://www.dg7xo.de/selbstbau/avrboard.html.


    Może ma ktoś przykładowy kod?
  • REKLAMA
  • #7 3967465
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Dlaczego nie podłączysz tego potencjometru od kontrastu? Nic dziwnego że
    nic nie ma. Bez niego nie będziesz nic widział na wyświetlaczu. Po włączeniu
    zasilania powinny być chociaż zaciemnione pola w LCD.
  • #8 3967481
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Ok jestem w trakcie wlutowywanie potencjometru. Muszę troszkę go zmodyfikować ;).


    --edit

    Potencjometr wlutowałem. Na górze mam pasek, podświetlona jest pierwsza linia.
  • REKLAMA
  • #9 3967549
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Czyli jest wszystko ok. Teraz musisz napisać poprawny program sterujący.
    Poczytaj artykuł w czterech częściach o LCD do którego link Ci podesłałem.
    Jest tam dokładnie opisane jak przebiega inicjalizacja. Napiszesz procedurę
    według tego i zaciemnione kwadraty powinny zniknąć.
  • #10 3967653
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Zabardzo nie chce mi się tego czytać :P. Wiem jak działa lcd, ale nie potrafię tego ująć w kodzie. To jest troszkę denerwujące :/.
  • #11 3967890
    darrrrek
    Poziom 22  
    Posty: 733
    Pomógł: 4
    Ocena: 98
    Szczere ale pomysl...Tobie sie nie chce przeczytac ciekawych informacji na temat LCD a komus ma sie chciec tlumaczyc i wysylac gotowe kody jak to zrobic...Musisz troche wsadzic w to wlasnych checi a nie rezygnowac po kilku probach. Na forum jest mnustwo takich tematów wystarczy wpisac "LCD" i grzebac mozna do jutra :))

    Pozdrawiam
  • #12 3968345
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Pobawiłem się trochę tym lcd'kiem. Przeczytałem artykuły w EDW, napisałem program i dalej nic. Zamieszczam obecną wersję programu. Mam pytanie co do niego. Co robię źle z inicjalizacją. Cały czas mam czarną pierwszą linię na wyświetlaczu.


    Pozdrawiam.


    (kod w załączniku)
    Załączniki:
    • main.zip (1.4 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #13 3968452
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Nie ma schematu to nieco utrudnia i trzeba się wypytywać. RW wyświetlacza
    masz do masy? Jak masz podłączone linie D4 - D7 od LCD? Żeby było mniej
    problemów powinny być podłączone np. D4 - PD4 do D7 - PD7. Wszystkie ustawienia startowe
    typu ustawienie portów na wejście lub wyjście zrób na początku po etykiecie
    reset. Będzie mniej zagmatwane.
    Co do samej inicjalizacji to powinno być tak (zakładając połączenia jak pisałem wcześniej):
    * ustawiasz na D4 - D7 liczbę 30h
    * po ustawieniu czekasz minimum 140ns
    * dajesz impuls enable minimum 450ns
    * czekasz 5ms
    * znów ta sama liczba, odczekanie i enable
    * czekasz 5ms
    * jeszcze raz liczba 30h, odczekanie i impuls enable
    * czekasz 5ms
    * przełączasz na tryb 4 bitowy - 20h, odczekanie i enable
    * czekasz 5ms
    Teraz ustawiasz wyświetlacz jak potrzebujesz a te dane wysyłasz w dwóch bajtach
    * np. 20h, impuls enable, 80h, impuls enable, odczekanie na przetwarzanie
    LCD lub sprawdzenie flagi busy. To ustawi wyświetlacz na 4 bity, 2 linie
    i pole 5x7 punktów.
    Dalej ustawiasz włączenie wyświetlacza, kursora, przesuwanie napisu itp.

    Chyba nie przeczytałeś uważnie tych pdf-ów...
  • #14 3968542
    McRancor
    VIP Zasłużony dla elektroda
    Posty: 5326
    Pomógł: 479
    Ocena: 124
    y0yster piszesz tutaj, jakby LCD na HD44780 był najrzadszym sterownikiem LCDków i nikt jeszcze nigdy go nie uruchamiał, na dodatek na AVRach!

    Że w ogóle użytkownikowi szod chciało się pisać jak zainicjować ten LCD...

    Weś poszukaj trochę...
  • REKLAMA
  • #15 3968623
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Dzięki szod, ale już to zrobiłem szybciej, a i tak mi to nie działa. Robie to według pdf'ów McRancor.

    Zmieniłem na 2 linie, a dalej pali mi się tylko linia 1, a nie obie co mama zrobić. Wrzucam nowy kod, który jest już troszkę przerobiony.

    Ja robie to ogólnie według takiego schematu:
    -czekam 25 ms
    -function set
    -czekam 5 ms
    -function set
    -czekam 1ms
    -function set
    -function set (moje ustawienia)
    -display off
    -display on
    -entry mode set

    -wyświetlam literkę A

    Z tym, że po każdej komendzie robie coś takiego. Podciągam port dla pinu E, czekam 40us, i przechodzę w niski stan na tej linii.

    Co źle robię w takim razie?
    Załączniki:
    • main.zip (1.08 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #16 3968746
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Bo tylko jedna linia będzie przyciemniona. Tak ma być. I dlaczego dajesz
    reti na końcach procedur? Reti jest dla procedur przerwań. I przeczytaj co
    pisałem o inicjalizacji bo dalej byki robisz. W pewnym momencie masz przesyłać
    dane w dwóch bajtach. Jeden po drugim bez pętli opóźniających. Zobacz u
    siebie. Po drugie nie odpisałeś na pytania i dalej nie wiadomo co i jak jest
    podłączone. Jeśli jest tak jak napisałem to złe dane wystawiasz na D4 - D7.
    Po prostu nie te końcówki ustawiasz. Zobacz do których masz podłączone
    wyprowadzenia D4 - D7 wyświetlacza LCD. Wysyłając drugi bajt, młodszy półbajt
    musisz przesunąć na miejsce starszego. I nie musisz za każdym razem
    zerować RS, RW i EN. Wystarczy raz. Jak jakaś funkcja LCD będzie wymagać
    zmiany którejś z tych końcówek to wtedy to zrobisz. I gdzie są impulsy enable?
    Nie widzę ich.
  • #17 3968873
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Dorzucam tutaj schemat podłączeń atmegi i lcd.

    Zaraz dokładniej sprawdzę to o czym mówisz.


    --edit

    Ja posługuję się 8-bitami. A impulsy enable są w procedurze czekaj_na_odbior.

    Mógłbyś mi dać jakiś przykładowy program na to?
    Załączniki:
    • Kod w asemblerze do wyświetlania 'A' na LCD HD44780 - co poprawić? schemat_podlaczen.gif (17.78 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #18 3968980
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Nie używam trybu 8 bitowego. Nie miałem takiej potrzeby. Wszystko mi
    zawsze ładnie śmigało na 4 bitach. Jeśli chcesz używać 8 bitów to wysyłanie
    w dwóch bajtach Ciebie nie dotyczy. Inicjalizacja też będzie nieco inna. Zwróć
    też uwagę że używasz pinu RW wyświetlacza LCD. A więc powinieneś sprawdzać
    flagę busy. Zobacz tutaj, nawet podałem gotowy przykład na AVR:
    https://www.elektroda.pl/rtvforum/topic628731.html
    Tak więc szukaj na forum, bo dużo tematów było już poruszanych.
    Dodam tylko, że praktycznie wszystkie informacje potrzebne do uruchomienia
    LCD są w pdf-ach które Ci podałem.
    A przy impulsach enable nie możesz normalnie skorzystać z sbi i cbi? Zobacz
    przykład który podałem w linku.
  • #19 3969125
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Zastanawiam się teraz dlaczego zainteresowałeś się flagą busy. Dodam, że R/S cały czas ma niską wartość logiczną, więc nie ma potrzeby bawienia się flagą busy, przynajmniej tak sądzę. Równie dobrze mógłbym ją podłączyć do masy. A program jak nie chodził tak nie chodzi dalej.

    Dodam jeszcze, że przez działanie całego programu nie zmieniam stanu R/W, więc nie ma żadnej potrzeby na razie na sprawdzanie stanu flagi busy.
  • #20 3969200
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Dlatego że lepiej moim zdaniem używać flagi busy niż domyślnych opóźnień
    które się przydają na początku inicjalizacji bo inaczej nie można. Jakiego
    używasz kwarcu? Przeanalizuj procedurę inicjalizacji pod kątem opóźnień.
    Wyświetlacz może nie wyrabiać. Zobacz na moją listę kolejnych kroków
    inicjalizacji. Podałem czasy. Jak masz szybki kwarc to będziesz musiał dać
    trochę opóźnienia np. nop-ów. Jak nie chcesz bazować na fladze busy to
    niestety musisz dokładnie dobrać opóźnienia. Lepiej żeby były za duże jak za
    małe.
  • #21 3969253
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Już próbowałem dawać różne opóźnienia. Zwiększałem, zmniejszałem. Nawet dawałem 1 sekundę ale to i tak nic mi nie dawało. Kwarc z tego co się orientuję w atmedze8 standardowo jest ustawiony na 4MHz.

    Co w moim kodzie może być nie tak. Poprawiłem troszkę kod i zoptymalizowałem. Wrzucam go jeszcze raz. Może teraz będzie jaśniejsza sprawa.

    Zaczyna mi powoli brakować pomysłów co do tej inicializacji. Zdaje mi się, że próbowałem już bardzo wielu rzeczy. Dochodzę powoli do wniosku, że coś musi być nie tak z podłączeniami, ale je sprawdzałem wielokrotnie. Styki na pewo są dobrze podłączone. Myślę, że to może wyświetlacz padł, albo coś w tym stylu. Ale to raczej mało prawdopodobne.
    Załączniki:
    • main.zip (1.09 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #22 3969310
    darrrrek
    Poziom 22  
    Posty: 733
    Pomógł: 4
    Ocena: 98
    standardowo jest ustawiony 1 MHz o ile sie nie myle, ale nigdy z atmegą nie mialem doczynienia.
  • #23 3969475
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    Chyba nie czytasz tego co piszę. Przeczytaj co wypisałem o inicjalizacji i
    porównaj z tym co ty powypisywałeś. Dlaczego ustawiasz EN w stan wysoki,
    ustawiasz dane na liniach D0 - D7 a potem zerujesz EN? Ja tak na pewno
    nie napisałem. Impuls EN ma być po ustawieniu danych na liniach D0 - D7 i
    to z odpowiednim opóźnieniem. Pisałem o tym. Wróć do tego postu. Po drugie
    wraz używasz reti na końcach procedur które nie są procedurami przerwania.
    Popraw to i zobaczymy co dalej. Mogłem jeszcze coś przegapić.
  • #24 3969879
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Co do reti zabardzo nie masz racji. Mi wszystko działa. Na innych moich przykładach wszystko grało. Co do tego impulsu enable próbowałem już takie kombinacje:
    -podciągnięcie na portach DB0..DB7, następnie E = 1, opóźnienie, E = 0
    -podciągnięcie na portach DB0..DB7, następnie E = 1, E = 0, opóźnienie


    Czy jest może jakaś inna opcja. Jak byś popatrzył na kod źródłowy to tam widać dokładnie czego próbowałem.
  • #25 3970206
    McRancor
    VIP Zasłużony dla elektroda
    Posty: 5326
    Pomógł: 479
    Ocena: 124
    Co do reti to jednak ma całkowitą rację. Nie stosuje się reti w taki sposób jak Ty to robisz.

    Dane do LCD zatrzaskuje się opadającym zboczem na linii EN.

    Jeśli masz podłączony interfejs z linią RW to zrób odczytywanie flagi zajętości zamiast oczekiwania, jest pewniejsze i szybsze.

    Jeśli po tej iinicjalizacji którą robisz nadal na wyświetlaczu jest jedna linia to skopane masz połączenia do wyświetlacza.
  • #26 3970253
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Co do połączenia to jest na 100% dobre. Bo odpaliłem program napisany w c, który wyświetlił napis. Jedno mnie tylko zastanawia, dlaczego każdy przykład, który uda mi się znaleźć jest na 4-bitach, a nie na ośmiu, coś musi być z tym skopane. Co do flagi zajętości to nie można jej odczytywać podczas inicjalizacji. Tak jest w EDW. Chodzi mi tutaj o początkową fazę inicjalizacji.

    Co do reti, to będę dalej tak robił ponieważ nie znalazłem innego sposobu jak narazie, nie chce mi się teraz szukać innego rozkazu. Jestem jak narazie zajęty tym wyświetlaczem, który nie chce ani drgnąć.
  • #27 3970269
    dziechu
    Poziom 27  
    Posty: 1609
    Pomógł: 27
    Ocena: 71
    Rozkaz RETI jest powrotem z przerwania a nie zwyklej procedury. Widac ze nie masz pojecia o programowaniu, wiec kiedy ktos ci pisze ze zle robisz, to nie pisz 'nie masz racji'. To ze blaednie napisane programiki jakosc ci dzialaly, nie znaczy ze napisane sa dobrze, tylko 'w przyblizeniu' dobrze. Zacznij moze od prostszych rzeczy, skoro nie potrafisz uruchomic wyswietlacza LCD, gwarantuje ci ze jest to jedna z najprostszych rzeczy. Robile wiele procedur (wlasnych) na LCD dla Z80, '51, AVR, PIC i to bardziej skomplikowane - z czytanie flagi BUSY i wyswietlaniem polskich literek i nigdy zadnych problemow nie bylo - dlaczego? Bo bralem dokumentacje i czytalem dokladnie co i jak robic, a tobie jakby sie nie chcialo, najlepiej zeby ktos dal ci gotowce do wklejenia - tak nic sie nie nauczysz, bo nawet jak wkleisz gotowca to i tak nie bedziesz wiedzial dlaczego ten gotowiec dziala a twoja procedura nie. Szukanie i samodzielne rozwiazywanie bledow to najlepsza metoda nauki.

    Dodano po 3 [minuty]:

    Moze zamiast RETI uzyj zwyklego RET??? A moze napisac RET zamiast RETI tez ci sie po prostu nie chce?
  • #28 3970366
    y0yster
    Poziom 19  
    Posty: 471
    Pomógł: 9
    Ocena: 76
    Dobra. Zmieniłem reti na ret. Ale nie wiem po co zajmować się takimi szczegółami. Temat postu to wyświetlacz lcd, a nie używanie ret, czy reti. Ma możę ktoś przykładowy kod w asemblerze dla tego lcd'ka? Pisany z użyciem 8-bitów nie 4.
  • #29 3970409
    szod
    Poziom 33  
    Posty: 1663
    Pomógł: 215
    Ocena: 120
    :arrow: y0yster - z twoich wypowiedzi wynika że nawet nie znasz rozkazów
    asemblera. Od tego chyba powinieneś zacząć. Trochę to dziwnie wygląda gdy
    na swojej stronie www piszesz, że piszesz programy na zamówienie oraz na
    zaliczenie dla AVR w asemblerze. Zastanawiam się jak Ty to robisz nie znając rozkazów.
    Chcesz tutaj dla swojej działalności dostać gotowce? Powiem Ci tyle, że mi wystarczyły
    te pdf-y które Ci podałem żeby napisać sobie całą bibliotekę do sterowania LCD
    z wszystkimi bajerami jak np. przesuwanie napisów, czytaniem flagi busy itp.,
    i jak dotąd żaden wyświetlacz mi się nie oparł. A pisałem w asemblerze
    zarówno na '51 jak i AVR.
  • #30 3970431
    dziechu
    Poziom 27  
    Posty: 1609
    Pomógł: 27
    Ocena: 71
    y0yster napisał:
    Dobra. Zmieniłem reti na ret. Ale nie wiem po co zajmować się takimi szczegółami. Temat postu to wyświetlacz lcd, a nie używanie ret, czy reti. Ma możę ktoś przykładowy kod w asemblerze dla tego lcd'ka? Pisany z użyciem 8-bitów nie 4.


    No chyba sobie zartujesz. To moze zamiast call uzyj goto, a zamiast add uzyj mov albo ldi ??? Gdyby RETI i RET mily robic to samo, to po co bylyby dwa rozne??? Czasem moze byc tak ze program nie dziala bo przyczyna jest nie w 50 linijkach akurat tej sekwencji, ale w zupelnie innym miejscu, bo procesor w czasie wykonywania tych 50 linijek moze byc np. odwolany do przerwania, ktore zle skonfigurowane moze zepsuc dzialanie poprawnie napisanych 50 linijek. Programowanie jest troche jak matematyka - drobny blad, przecinek w zlym miejscu i caly program do d...

Podsumowanie tematu

✨ Dyskusja dotyczy problemów z inicjalizacją i wyświetlaniem znaku 'A' na alfanumerycznym wyświetlaczu LCD sterowanym kontrolerem HD44780, programowanym w asemblerze na mikrokontrolerze Atmega8. Główne trudności obejmowały błędy w procedurze inicjalizacji, nieprawidłowe podłączenie potencjometru do regulacji kontrastu, niepoprawne przypisanie linii danych (bity sterujące), a także nieodpowiednie opóźnienia po komendzie clear display. Wskazano, że inicjalizacja powinna uwzględniać wielokrotne wysłanie komendy 0x30 (tryb 8-bitowy) z odpowiednimi opóźnieniami, a następnie przejście do trybu 4-bitowego lub kontynuację w 8-bitach, zależnie od konfiguracji. Zwrócono uwagę na konieczność prawidłowego generowania impulsów na linii Enable (EN) po ustawieniu danych na liniach D0-D7 lub D4-D7. Dyskutowano także o stosowaniu flagi busy do synchronizacji zamiast opóźnień, co jest bardziej niezawodne. Autor ostatecznie rozwiązał problem, poprawiając przypisanie bitów i dodając odpowiedni czas oczekiwania po komendzie czyszczenia wyświetlacza. Poruszono również zagadnienia dotyczące adresowania pamięci programu w asemblerze AVR (mnożenie adresu przez 2 ze względu na 16-bitową organizację pamięci) oraz prawidłowego podłączania wyświetlacza podczas programowania mikrokontrolera. Wskazano, że większość przykładów i bibliotek korzysta z trybu 4-bitowego, który jest powszechnie stosowany ze względu na oszczędność linii I/O, ale tryb 8-bitowy również jest możliwy. Podkreślono znaczenie dokładnego czytania dokumentacji i samodzielnego debugowania kodu asemblerowego.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA