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

LCD 2x16 - wyświetla tylko 'p', problem z inicjalizacją programu

Zaquadnik 26 Gru 2005 15:26 2193 20
REKLAMA
  • #1 2116726
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Bardzo proszę o pomoc. Już nie wiem co mam nie tak. Napisałem program do obsługi LCD 2x16. Po uruchomieniu wyświetla tylko literkę 'p' na początku i to wszystko. Co więcej, dzieje się też tak wówczas, gdy wykomentuję wywołanie procedur odpowiedzialnych za czyszczenie LCD i wyświetlanie znaków, więc coś nie tak jest w procedurze inicjalizującej.
    
    ;------------------------------------
    ;Obsluga LCD, kwarc 12 MHz
    ;tryb pracy - 4 linie danych
    ;znak przekazywany w R2
    ;------------------------------------
    
    RS equ P1.2
    E equ P1.3
    DB4 equ P1.4
    DB5 equ P1.5
    DB6 equ P1.6
    DB7 equ P1.7
    
    	ljmp Program
    	
    	org 100h
    	
    tablica: DB 'D','z','i','e','n',' ','d','o','b','r','y'
    	
    	org 120h
    Program:
    	lcall LCDinit
    	lcall LCDclear
    	mov DPTR,#tablica
    	mov B,#00h
      Wyswietl:
      	mov A,B
      	movc A,@A+DPTR
      	mov R2,A
      	inc B
      	lcall LCDznak
      	mov A,B
      	xrl A,#0Eh
      	jnz Wyswietl
    
    LCDinit:
    	mov P1,#00h
    	clr RS
    	clr E
    	setb E
    	orl P1,#20h
    	clr E
    	mov A,#14h
    	lcall Pauza
    	anl P1,#0Fh
    	orl P1,#20h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#80h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#0E0h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#60h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	ret
    	
    LCDclear:
    	mov P1,#00h
    	clr RS
    	orl P1,#00h
    	setb E
    	clr E
    	mov P1,#00h
    	orl P1,#10h
    	setb E
    	clr E
    	mov A,#14h
    	lcall Pauza
    	setb RS
    	ret
    
    LCDznak:
    	mov P1,#00h	
    	setb RS
    	mov A,R2
    	anl A,#0F0h
    	orl P1,A
    	setb E
    	clr E
    	mov A,R2
    	anl A,#0Fh
    	swap A
    	orl P1,A
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	ret
    	
    Pauza:	
      Petla:
      	mov B,#07Bh	;2 cykle
      	djnz B,$	;2 cykle
      	djnz ACC,Petla	;2 cykle
      	ret
    	
    end
    

    Z góry dziękuję i pozdrawiam.
  • REKLAMA
  • Pomocny post
    #2 2116910
    olekewaagata
    Poziom 25  
    Posty: 638
    Pomógł: 64
    Ocena: 28
    Nie analizowałem całego twojego programu ale co rzuciło mi sie od razu w oczy to brak umiejscowienia stosu (nie wiem jaki procesor) np. MOV SP,#50 (stos jest od ramu o adresie 50).
    Brak jest opóznień czasowych w inicjalizacji.
    Sam program po wykonaniu rozkazu JNZ WYSWIETL idzie do wykonania LCDinit (nastepny rozkaz) a pewnie nie o to ci chodzi, myślę że chcesz żeby sie zatrzymał.
    I to można zrobić na wiele sposobów, jednym to po JNZ WYSWIETL dać rozkaz SJMP $, lub ustawic odpowiedni bit w SFR (PCON) żeby procesor przeszedł w stan stendby.
    Podrzucam też trochę literatury po polsku, warto się zapoznać, są tam opisane zależności czasowe podczas inicjalizacji.
    Załączniki:
    • LCD-cz3.pdf (547.3 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #3 2117261
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Wywołanie procedury Pauza z generuje opóźnienia. Zależy co wpiszesz do akumulatora. Ogólnie wzór na opóźnienie można przedstawić tak: ACC*250us. A wywoływanie procedur przez lcall działało bez ręcznej inicjalizacji stosu, ale mogę spróbować.
  • Pomocny post
    #4 2117439
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Nie napisałeś na jakim sterowniku pracuje Twój LCD.Domyślam się , że chodzi o HD44780.Jeśli tak jest w rzeczywistości , to procedurka inicjująca jest niezgodna ze specyfikacją.Spójrz na str.47 (Figure 26 4-Bit Interface) rzeczonej specyfikacji i porównaj ze swoim kodem.

    Piotrek
  • #5 2117720
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Tak, chodzi o HD44780. Pisałem ten program wzorując się na źródłach już napisanych. Głównie jeśli chodzi o procedurę inicjującą LCD. Pierwsza komenda jest powtórzona 2 razy, aby wprowadzić kontroler w tryb 4-ro bitowy (z tego, co mi tłumaczono). Ustawia LCD w trym dwóch linii, znaki 5x7 punktów no i włącza tryb 4-ro bitowy. Druga (0Eh) włącza LCD i kursor, a trzecia (06h) ustawia kierunek przesuwu kursora. Znalazłem to i widzę, że jest coś nie tak... tylko nie wiem, czemu takie coś przedstawiają jako działający kod :] W każdym razie dzięki :)
  • #6 2118955
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    No i właśnie teraz zastosowałem procedurę inicjalizacji taką jak w podanym artykule. Dalej nic, z tą różnicą, że teraz wyświetlacz jest czysty, bez żadnych dziwnych znaków...
    
    ;------------------------------------
    ;Obsluga LCD, kwarc 12 MHz
    ;tryb pracy - 4 linie danych
    ;znak przekazywany w R2
    ;------------------------------------
    
    RS equ P1.2
    E equ P1.3
    DB4 equ P1.4
    DB5 equ P1.5
    DB6 equ P1.6
    DB7 equ P1.7
    
    	ljmp Program
    	
    	org 100h
    	
    tablica: DB 'D','z','i','e','n',' ','d','o','b','r','y'
    	
    	org 120h
    Program:
    	lcall LCDinit
    	lcall LCDclear
    	mov DPTR,#tablica
    	mov B,#00h
      Wyswietl:
      	mov A,B
      	movc A,@A+DPTR
      	mov R2,A
      	inc B
      	lcall LCDznak
      	mov A,B
      	xrl A,#0Eh
      	jnz Wyswietl
      	jmp $
    
    LCDinit:
    	mov A,#3Ch
    	lcall Pauza
    	
    	mov P1,#00h
    	clr RS
    	clr E
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#14h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    		
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#20h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#20h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#080h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#80h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#10h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#60h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	ret
    	
    LCDclear:
    	mov P1,#00h
    	clr RS
    	orl P1,#00h
    	setb E
    	clr E
    	mov P1,#00h
    	orl P1,#10h
    	setb E
    	clr E
    	mov A,#14h
    	lcall Pauza
    	setb RS
    	ret
    
    LCDznak:
    	mov P1,#00h	
    	setb RS
    	mov A,R2
    	anl A,#0F0h
    	orl P1,A
    	setb E
    	clr E
    	mov A,R2
    	anl A,#0Fh
    	swap A
    	orl P1,A
    	setb E
    	clr E
    	mov A,#02h
    	lcall Pauza
    	ret
    	
    Pauza:	
      Petla:
      	mov B,#07Bh	;2 cykle
      	djnz B,$	;2 cykle
      	djnz ACC,Petla	;2 cykle
      	ret
    	
    end
    

    Pozdrawiam.
  • REKLAMA
  • #7 2119002
    maxiu25
    Poziom 16  
    Posty: 190
    Pomógł: 16
    Ocena: 3
    spróbuj przy inicjalizacji wpisac te wartosci {0x32,0x28,0x6,0xc,0x3}
  • #9 2119130
    maxiu25
    Poziom 16  
    Posty: 190
    Pomógł: 16
    Ocena: 3
    mialem ten sam problem i niestety go nie rozwiazalem
    ale juz mozesz wypisac to co chcesz tylko po literce
  • Pomocny post
    #10 2119227
    piotr_go
    Konstruktor DIY elektronika
    Posty: 2910
    Pomógł: 94
    Ocena: 3350
    B potrzebne przy "wyświetl" niszczone jest w "pauza"
  • REKLAMA
  • #12 2127419
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Heh.. a teraz kolejny problem... nie mogę uaktywnić drugiej linii wyświetlacza :/
    Oto kod procedury inizjalizującej:
    
    LCDinit:
    	mov A,#3Ch
    	lcall Pauza
    	
    	mov P1,#00h
    	clr RS
    	clr E
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#14h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    		
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#20h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#0A0h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#20h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#80h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#60h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#0D0h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    	
    	anl P1,#0Fh
    	orl P1,#00h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    
    	ret
    
    Pauza:	
      Petla:
      	mov B,#07Bh
      	djnz B,$
      	djnz ACC,Petla
      	ret
    
    

    Nie wiem co się dzieje... :/
  • #13 2127680
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Zaquadnik napisał:
    Heh.. a teraz kolejny problem... nie mogę uaktywnić drugiej linii wyświetlacza :/
    Oto kod procedury inizjalizującej:
    
    ...
    	anl P1,#0Fh
    	orl P1,#30h
    	setb E
    	clr E
    	anl P1,#0Fh
    	orl P1,#0A0h
    	setb E
    	clr E
    	mov A,#01h
    	lcall Pauza
    ...
    

    Nie wiem co się dzieje... :/

    A co ma znaczyć powyższe :?:
    Po co robisz wszystko na piechotę , skorzystaj z udogodnień jak np. podprogram, pętla.Przekonj się jak skróci się Twój kod , będzie bardziej ... czytelny , itd... ;)

    Piotrek
  • #14 2129171
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Na razie to tylko "prototyp". Pisałem na zasadzie kopiuj -> wklej. Nie problem przerobić to na mniejsze jeszcze procedury. Ale nie to jest istotne. Dalej nie wiem dlaczego nie uruchamia mi się druga linia wyświetlacza =]
  • REKLAMA
  • #15 2129564
    maxiu25
    Poziom 16  
    Posty: 190
    Pomógł: 16
    Ocena: 3
    0xc0
    0x80
    to sa adresy od których powinno sie wypisywac odpowiednie dane na wyswietlacz
  • #17 2129597
    maxiu25
    Poziom 16  
    Posty: 190
    Pomógł: 16
    Ocena: 3
    ja zaczynam wpisywanie na odpowiednie miejsce wyswietlacz i robire to tak write_lcd(0xc0+a); gdzie a to miejsce od 0 do 15
  • #19 2131153
    olekewaagata
    Poziom 25  
    Posty: 638
    Pomógł: 64
    Ocena: 28
    Ale się męczysz. A nie lepiej byłoby wklejenie tu paru linijek twojego programu gdzie robisz to wysyłanie na LCD. Wtedy ktoś ci pomoże.
  • #20 2131754
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Zaquadnik napisał:
    Dalej zonk :/ Wygląda jakby druga linia była w ogóle nieaktywna :/ Skończyły mi się pomysły :/

    Skoro działa pierwsza linia to , to spróbuj wpisać do LCD np. 200 razy jakiś znak i sprawdź czy wyświetli się na drugiej lini.

    Piotrek

Podsumowanie tematu

✨ Problem dotyczy inicjalizacji wyświetlacza LCD 2x16 opartego na kontrolerze HD44780 pracującego w trybie 4-bitowym z kwarcem 12 MHz. Po uruchomieniu program wyświetla tylko literę 'p' lub same litery 'D' w pierwszej linii, a druga linia pozostaje nieaktywna. Przyczyną problemu jest nieprawidłowa procedura inicjalizacyjna, brak opóźnień czasowych wymaganych przez specyfikację HD44780 oraz potencjalne niszczenie rejestru B w procedurze Pauza. Zalecane jest stosowanie zgodnej z dokumentacją sekwencji inicjalizacji, uwzględniającej odpowiednie opóźnienia i poprawne ustawienie linii danych i sygnałów sterujących (RS, E, DB4-DB7). Wskazano także konieczność umiejscowienia stosu (np. MOV SP,#50) oraz zatrzymania programu po wyświetleniu danych (np. SJMP $). Dodatkowo podkreślono, że adresy 0x80 i 0xC0 odpowiadają początkom pierwszej i drugiej linii wyświetlacza i należy je wykorzystać do aktywacji drugiej linii. Wskazano, że kod można uprościć przez użycie podprogramów i pętli. Po poprawkach i uwzględnieniu tych zaleceń wyświetlacz działa poprawnie, jednak nadal występują trudności z aktywacją drugiej linii, co może wynikać z błędów w adresowaniu lub sekwencji poleceń.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA