Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Odczyt danych z LCD. Zapis danych do komórek pamięci RAM.

pawel129 10 Dec 2004 01:19 2613 7
  • #1
    pawel129
    Level 16  
    Witam,
    posiadam LCD 2x16znaków, kontroler zgodny z HD44780 sterowany przy pomocy AT89S52. Potrzebuje w pewnym momencie odczytać znaki które on aktulanie wyświetla i zapisać je do komórek pamięci procka (narazie tylko w RAMie procka). Zapewne chodzi tu o odczyt RAMu wyświetlacza... tylko jak to zrobić? Wiem, że należy ustawić linie RS na 1 i RW na 1, podać adres znaku wyświetlanego aktualnie na LCD.... ale co dalej? Jak to zapisać do komórek pamięci RAM procka? Jakoś kompletnie nie moge sobie tego wyobrazić ... ;/

    Bardzo bym prosił o posłużenie się jakimś przykładem w oparciu o kod.

    Programuje w ASM. Pierwsza linia LCD zaczyna się od 80h a druga od C0h. Tryb 8bitowy.
  • #3
    GienekS
    Level 32  
    Masz napewno ten LCD podpięty do procka liniami D0...D7 Po wykonaniu tych czynności, które opisałeś wcześniej i jak są zgodne z danymi katologowymi sterownika LCD, przez linie te odczytujesz wartość tego bajtu. Pozostaje Ci tylko odczytać w programie wartość portu procka do którego są te linie podpięta i masz upragniony bajt w procku.
    A jeszcze jedno najważniejsze. Przed rozpoczęciem całej procedury odczytu nie zapomnij przełączyć tego portu procka w tryb wejściowy bo inaczej będzie "BUM" na magistrali.
  • #4
    pawel129
    Level 16  
    @LightHouser,
    Quote:
    ...Pierwsza linia LCD zaczyna się od 80h a druga od C0h. Tryb 8bitowy.


    Wyświetlacz mam podpięty do portu P0.
    Do odczytu zrobiłem taki podprogram:
    Code:
    READ_DATA:
    
       
       SETB RS
       SETB RW
       NOP
       NOP
       ACALL CZEKAJ
       MOV P0,A
       NOP
       NOP
       ACALL CZEKAJ
       SETB EN
       NOP
       NOP
       NOP
       MOV A,P0
       NOP
       ACALL CZEKAJ
       NOP
       CLR EN
       NOP
       RET

    Przyczym CZEKAJ to króciutka pętla czasowa.

    A to przykładowy podprogram: polecenie zapisu 3 pierwszych znaków z LCD do komórek ramu 30h (ZNAK1),31h(ZNAK2),32h(ZNAK3):

    Code:
    ZAPISZ_TEXT:
    
             MOV A,#80H
       LCALL READ_DATA
       NOP
       NOP
       MOV ZNAK1,A

       MOV A,#81H
       LCALL READ_DATA
       NOP
       NOP
       MOV ZNAK2,A

       MOV A,#82H
       LCALL READ_DATA
       NOP
       NOP
       MOV ZNAK3,A

    Niestety, gdy próbuje później wyświetlić zawartość tych 3 komórek pamięci RAMu , pojawiają mi się na LCD 3 takie same czarne kwadraty z 2 pustymi pixelami.

    Ogólnie zasada działania odczytu LCD (przedstawiona przeze mnie) wygląda tak:
    1.Kopiuj do akumulatora adres komórki DD_RAM LCD.
    2.Ustaw RW i RS na "1"
    3.Poczekaj chwile
    4.Kopiuj akumulator na linie P0
    5.Poczekaj chwile
    6.Potraktuj EN
    7.Poczekaj chwile
    8.Kopiuj zawartość linii P0 do akumulatora
    9.Poczekaj chwile
    10.Wyłącz EN
    11.Zapisz akumulator do komórki pamięci (np. ZNAK1 - 30h)

    To jest program do odczytu tych 3 komórek pamięci procka i wyświetlenie ich na LCD:
    Code:
    WYSWIETL_TEXT:
    
             LCALL LCD_INIT_EDYTOR    ;wyłącza kursor,zwiększa adres LCD po każdym odczytanym znaku
       MOV A,#1                         
       LCALL DELAY_50MS            ;pętla czasowa: A*DELAY_50MS=czas
       LCALL LCD_CLR                 ;czyści LCD
       MOV A,ZNAK1                    ;kopiuje zawartość komórki pamięci ZNAK1 do akumulatora
       LCALL WRITE_DATA           ;wyświetla zawartość akumulatora na LCD
       MOV A,#1
       LCALL DELAY_50MS            ;odczekaj 50ms
       
       MOV A,ZNAK2                    ;pobierz zawartość ZNAK2 do akumulatora
       LCALL WRITE_DATA           ;wyświetl akumulator na LCD
       MOV A,#1
       LCALL DELAY_50MS           ;czekaj 50ms

       MOV A,ZNAK3
       LCALL WRITE_DATA
       MOV A,#1
       LCALL DELAY_50MS

    Czy może ktoś inny ma jakiś ciekawy pomysł? Bo mój własnie nie bardzo chce działać... :( Adres całego programu zaczyna się od 60h..
  • #5
    LuznyTomasz
    Level 15  
    Podejrzewam że potrafisz zapisać znak do pamięci LCD (RS=0 r/w=1) a potem na lidiach D7-D0 wystawiasz znak. Odczyt jest analogiczny tylko RS=1 r/w=1. Tylko musisz ustawić adres kursora (RS =0 r/w=0 i na liniach D7-D0 wystawić powiedzmy 80H - pierwszy znak pierwsza linia) i odczytać linie D7-D0.
    CO do zapisu do pamięci RAM to nie wiem w czym problem.
    ----------------------------------------------------------------------
    Trochę trudno mi ogarnąć czyjś program...

    Quote:
    READ_DATA:

    SETB RS
    SETB RW
    NOP
    NOP
    ACALL CZEKAJ
    MOV P0,A

    rozumiem że w tym miejscu chcesz ustawić adres komórki pamięci ram wyświetlacza, którą chcesz potem odczytać??? jeśli tak to zamiast SRTB RS i SETB RW powinno być CLR RS i CLR RW[/b]
  • #6
    pawel129
    Level 16  
    a czy mógłby ktoś posłużyć się przykładowym programem do odczytu danych z LCD? Albo chociaż napisać krok po kroku co trzeba robić.... Niby wszystko robie jak trzeba (albo mi się tak wydaje) a nadal nie działa jak trzeba:(

    Napisałem takie coś (oczywiście jakoś nie dobrze działa):
    Code:

    najpierw wpisuje do A adres komórki RAMu wyswietlacza, np. MOV A,#80h

    READ_DATA:
       
       CLR RS
       CLR RW
       NOP
       NOP
       ACALL CZEKAJ
       MOV P0,A
       NOP
       NOP
       ACALL CZEKAJ
       SETB EN
       NOP
       NOP
       ACALL CZEKAJ
       CLR EN
       ACALL CZEKAJ
       CLR A
       SETB RS
       SETB RW
       NOP
       NOP
       ACALL CZEKAJ
       SETB EN
       NOP
       NOP
       ACALL CZEKAJ
       MOV A,P0
       NOP
       NOP
       ACALL CZEKAJ
       CLR EN
       NOP
       RET

    Potem kopiuje A do jakiejś komórki pamięci w procku, np. MOV ZNAK1,A
  • #7
    olekewaagata
    Level 25  
    najpierw wpisuje do A adres komórki RAMu wyswietlacza, np. MOV A,#80h

    READ_DATA:

    CLR RS
    CLR RW
    MOV P0,A
    SETB EN
    NOP
    NOP
    CLR EN
    ;-------- ustawiłeś adres do odczytu pierwszego znaku w pierwszej lini
    SETB RS
    SETB RW
    MOV P0,#0FFH ;jeśli chcesz odczytywać przez P0 musisz go ustawić na same jedynki czyli FF, jesli tego nie zrobisz i z poprzednich działań na P0 będą gdzieś zera to odczyt będzie zły.
    SETB EN
    NOP
    NOP
    MOV A,P0 ;teraz do akumulatora pobieram to co wystawił LCD
    CLR EN
    RET

    Zwróć uwagę jeszcze na jeden szczegół, port P0 jest typu otwarty kolektor czyli nie ma podciągnięcia do plusa i jesli robisz operacje odczyt/zapis powinienes ten port (wszystkie jego bity) podciągnąć do plusa przez rezystory np 5 do 10 kiloomów.
  • #8
    pawel129
    Level 16  
    @olekewaagata,
    spoko o rezystory zadbałem, inaczej nic by mi nie wyświetlał :)
    Zaraz sprawdzę twój pomysł...

    ------------------------------------------------
    @olekewaagata,dzięki!! wszsytko działa git. Na początku były problemy (wstawienie odstępu czasowego DELAY_50MS pomiedzy odczytami każdej z komórek zamazywało akumulator w którym był znak z LCD). Ale teraz jest wszystko git.