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

Inicjacja LCD na HD44780 - problem z konfiguracją portów i sygnałów

rafiks 29 Cze 2005 17:31 1893 4
  • #1 1616183
    rafiks
    Poziom 18  
    Posty: 425
    Ocena: 7
    R/W - mam zwarte na stałe do masy

    LCD_Enable:
    RCall Wait_10ms
    Sbi LCD_Port,LCD_E
    RCall Wait_10ms
    Cbi LCD_Port,LCD_E
    Ret


    LCD_Init: ;czekaj 15ms
    RCall Wait_10ms
    RCall Wait_5ms
    ;konfiguruj port
    Ldi Acc,255
    Out LCD_DDR,Acc
    ;krok 1
    Cbi LCD_Port,LCD_E
    Cbi LCD_Port,LCD_RS
    Cbi LCD_Port,LCD_D7
    Cbi LCD_Port,LCD_D6
    Sbi LCD_Port,LCD_D5
    Sbi LCD_Port,LCD_D4
    RCall LCD_Enable
    ;czekaj 5ms i wyslij ponownie
    RCall Wait_10ms
    RCall LCD_Enable
    ;czekaj 100us i wyslij ponownie
    RCall Wait_10ms
    RCall LCD_Enable
    ;opcje inicjacji
    Cbi LCD_Port,LCD_D4
    RCall LCD_Enable
    RCall LCD_Enable
    Cbi LCD_Port,LCD_D5
    sbi LCD_Port,LCD_D7
    sbi LCD_Port,LCD_D6
    RCall LCD_Enable
    Cbi LCD_Port,LCD_D7
    Cbi LCD_Port,LCD_D6
    Cbi LCD_Port,LCD_D5
    Cbi LCD_Port,LCD_D4
    RCall LCD_Enable
    Sbi LCD_Port,LCD_D7
    RCall LCD_Enable
    Cbi LCD_Port,LCD_D7
    RCall LCD_Enable
    Sbi LCD_Port,LCD_D4
    RCall LCD_Enable
    Cbi LCD_Port,LCD_D4
    RCall LCD_Enable
    Sbi LCD_Port,LCD_D6
    sbi LCD_Port,LCD_D5
    sbi LCD_Port,LCD_D4
    RCall LCD_Enable
    Ret


    Nie patrzcie jak ta procedura wyglada bo jak zrozumiem jak ta inicjacja działa to napisze ja inaczej.

    Obsluga 4 bit danych

    Po wlaczeniu procesora wyswietlacz cały sie gasi i koniec nie widac kursora dlaczego? jak chce cos wyswietlic jakis znak na lcd to tez nie dziala cos skopałem ta inicjacje.


    Pisze na procku ATmega8515
  • Pomocny post
    #2 1616227
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Moje, działa, ale przymierzam się do podpięcia pod testowanie bitu "busy" oraz w drugiej odmianie pod timer :
    .cseg
    ; look on http://home.iae.nl/users/pouweha/lcd/lcd0.shtml
    ;Proc Set2Write()
    Set2Write:
    	cbi LCD_CR,LCD_RW      ;Make R/!W low - Write operation
    	sbi LCD_DT_DR, LCD_D4  ;Make the data pins outputs
    	sbi LCD_DT_DR, LCD_D5
    	sbi LCD_DT_DR, LCD_D6
    	sbi LCD_DT_DR, LCD_D7
    	ret
    
    ; Proc Byte2Displ(DataByte) 
    Byte2Displ:				 ; To complete transfer byte, send hiNibble, then loNibble
    	rcall Set2Write
    	mov TempA, DataByte
    	swap TempA
    	rcall Nibble2Displ
    	mov TempA, DataByte
    	rcall Nibble2Displ
    WaitByte2Displ:
    	rcall LCDBusyTest
    	brts WaitByte2Displ
    	ret
    
    ; Proc Nibble2Displ(loNiTempA) 
    Nibble2Displ:
    	andi TempA, $0F   ; Filter loNibble of TempA
    	ror TempA
    	brcs LCD_D4Hi
    	cbi LCD_DT, LCD_D4
    	rjmp gLCD_D5
    LCD_D4Hi: 
    	sbi LCD_DT, LCD_D4
    gLCD_D5:  
    	ror TempA
    	brcs LCD_D5Hi
    	cbi LCD_DT, LCD_D5
    	rjmp gLCD_D6
    LCD_D5Hi: 
    	sbi LCD_DT, LCD_D5
    gLCD_D6:  
    	ror TempA
    	brcs LCD_D6Hi
    	cbi LCD_DT, LCD_D6
    	rjmp gLCD_D7
    LCD_D6Hi: 
    	sbi LCD_DT, LCD_D6
    gLCD_D7:  
    	ror TempA
    	brcs LCD_D7Hi
    	cbi LCD_DT, LCD_D7
    	rjmp LCD_DFin
    LCD_D7Hi: 
    	sbi LCD_DT, LCD_D7
    LCD_DFin: 
    	sbi LCD_CR, LCD_EN     ;Toggle E High
    	nop
    	nop
    	nop
    	nop
    	cbi LCD_CR, LCD_EN     ;Back to Low
    ; & in middle of EN Strobe Signal comes High
    ; & EN Strobe Signal falls down at the end
    	cbi LCD_DT, LCD_D4     ; Cleanup (EN disable, isn't important,
    	cbi LCD_DT, LCD_D5     ; what becomes on in/outputs, but this
    	cbi LCD_DT, LCD_D6     ; saves time for simulation read LCD
    	cbi LCD_DT, LCD_D7     ; lines - no more manual skip)
    	ret
    ;Proc Set2Read()
    Set2Read:
    	cbi LCD_CR, LCD_EN
    	nop
    	nop
    	sbi LCD_CR, LCD_RW	; reading
    	cbi LCD_DT_DR, LCD_D4  ;Make the data pins inputs
    	cbi LCD_DT, LCD_D4     ; & switch off pullups
    	cbi LCD_DT_DR, LCD_D5
    	cbi LCD_DT, LCD_D5
    	cbi LCD_DT_DR, LCD_D6
    	cbi LCD_DT, LCD_D6
    	cbi LCD_DT_DR, LCD_D7
    	cbi LCD_DT, LCD_D7
    	nop
    	nop
    	sbi LCD_CR, LCD_EN     ;Toggle _en High
    	ret
    
    ; Proc Displ2Nibble(loNiTempA) 
    Displ2Nibble:
    ;rgLCD_D4: 
    	clr TempA
    	sbis LCD_IN, LCD_D4
    	rjmp rgLCD_D5
    	sbr TempA, 1<<0 ;
    rgLCD_D5: 
    	sbis LCD_IN, LCD_D5
    	rjmp rgLCD_D6
    	sbr TempA, 1<<1
    rgLCD_D6: 
    	sbis LCD_IN, LCD_D6
    	rjmp rgLCD_D7
    	sbr TempA, 1<<2
    rgLCD_D7: 
    	sbis LCD_IN, LCD_D7 
    	rjmp rLCD_DFin
    	sbr TempA, 1<<3
    rLCD_DFin:
    	ret
    
    ;Proc ReadEnd()
    ReadEnd:
    	cbi LCD_CR, LCD_EN
    	nop
    	nop
    	cbi LCD_CR, LCD_RW	; reading off
    	ret
    ; Proc Displ2Byte(->DataAcc) 
    Displ2Byte:				 ; To complete recive byte, get hiNibble, then loNibble
    	rcall Set2Read
    	nop	; 8* nop ~= 1,09 microsecond wait
    	nop
    	nop
    	nop
    	nop
    	nop
    	nop
    	sbis LCD_CR, LCD_RS
    	rjmp RdAddrAndBusyFlg
    	clr CountBtH
    	ldi	CountBtL, 0x01
    ;	rcall _40delay	; wait multiply CountBtL by _40,15 microseconds delay
    RdAddrAndBusyFlg:
    	rcall Displ2Nibble
    	cbi LCD_CR, LCD_EN
    	nop
    	mov DataAcc, TempA
    	; TempA MSB Nibble Cleared & no Set in Displ2Nibble
    	nop
    	sbi LCD_CR, LCD_EN     ;Toggle _en High
    	nop
    	rcall Displ2Nibble
    	rcall ReadEnd
    	nop	; 8* cycles ~= 1,09 microsecond wait
    	nop
    	nop
    	nop
    	nop
    	swap DataAcc
    	or DataAcc, TempA
    	ret
    
    ; Proc LCDBusyTest(Busy=>T=1) 
    LCDBusyTest:
    	cbi LCD_CR, LCD_RS
    	clt
    	rcall Displ2Byte
    	sbrc DataAcc, 7
    	rjmp LCDBusy
    	clt
    	ret
    LCDBusy:
    	set
    	ret
    
    ; Proc GetLCDAddr(Addr=>DataAcc) 
    GetLCDAddr:
    	rcall LCDBusyTest
    	brtc GetLCDAddrEnd
    	cbr DataAcc, (1<<7)
    GetLCDAddrEnd:
    	ret
    ; Proc GetLCDData(Data=>DataAcc) 
    GetLCDData:
    	sbi LCD_CR, LCD_RS
    	rcall Displ2Byte
    	ret
    ; Proc PrintChar(DataAcc)
    PrintChar:
    	ldi CountBtL, 5; 5	; delay 25=~1 ms
    	rcall _40Delay
    	cbi LCD_CR, LCD_EN
    	nop
    	nop
    	sbi LCD_CR, LCD_RS  ; Writing on display memory - RS high, R/!W low
    	rcall Byte2Displ
    	ret
    
    ; Proc CursHome()
    CursHome:
    ;set mode {+$02} - returns cursor to home position, clears shifting the display
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $02
    	rcall Byte2Displ
    	ret
    
    ; Proc CursReset()
    CursReset:
    ;set mode {+$01} - returns cursor to home position, clears display
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $01
    	rcall Byte2Displ
    	ret
    
    ; Proc CursOff()
    CursOff:
    ;set mode {+$08}, displaying on {+$04}, no cursor on {*$02}, no cursor blinking {*$01}
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $0C
    	rcall Byte2Displ
    	ret
    
    ; Proc CursOffBl()
    CursOffBl:
    ;set mode {+$08}, displaying on {+$04}, no cursor on {*$02}, cursor blinking {+$01}
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $0D
    	rcall Byte2Displ
    	ret
    
    ; Proc CursOn()
    CursOn:
    ;set mode {+$08}, displaying on {+$04}, cursor on {+$02}, no cursor blinking {*$01}
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $0E
    	rcall Byte2Displ
    	ret
    ; Proc CursOnBl()
    CursOnBl:
    ;set mode {+$08}, displaying on {+$04}, cursor on {+$02}, cursor blinking {+$01}
    	cbi LCD_CR, LCD_EN
    	ldi DataAcc, $0F
    	rcall Byte2Displ
    	ret
    ; Proc CursGo(Addr=>DataAcc)
    CursGo:
    	cbi LCD_CR, LCD_EN	; to perform, must be cleared, if forgiven
    	nop
    	nop
    	cbi LCD_CR, LCD_RW	; Write
    	nop
    	nop
    	cbi LCD_CR, LCD_RS    ; Operation on display register
    ;set mode {+$80}, Address {$00 - $7F}
    ;Mode 0x80 - set cursor address, next operation
    ;with _rs High denotes to be putting char on display
    	ori DataAcc, $80
    	rcall Byte2Displ
    	ret
    ; Proc InitDisplay()
    InitDisplay:
    	cbi LCD_CR, LCD_RS
    	nop
    	nop
    	cbi LCD_CR, LCD_RW
    	nop
    	nop
    	cbi LCD_CR, LCD_EN
    	sbi LCD_CR_DR, LCD_EN  ;Make the control pins outputs
    	sbi LCD_CR_DR, LCD_RW
    	sbi LCD_CR_DR, LCD_RS
    	ldi CountBtL, 125   ; 5 ms
    	rcall _40Delay
    	ldi CountBtL, 249   ; 10 ms
    	rcall _40Delay
    	ldi CountBtL, $03   ; 3 times set 8bit mode to be sure so it's becomes
    InitDispl0:
    	push CountBtL
    	ldi TempA, $03
    	rcall Nibble2Displ
    	ldi CountBtL, 5	; delay 25=~1 ms
    ;		ldi CountBtL, 25	; ~1 ms delay
    	rcall _40Delay
    	pop CountBtL
    	dec CountBtL
    	brne InitDispl0
    	ldi TempA, $02    ; clear 8bit mode (it results 4bit mode)
    	rcall Nibble2Displ
    	ldi CountBtL, 5	; delay 25=~1 ms
    	rcall _40Delay
    ;set mode {+$20}, no set 8bit mode {*$10}, 2 lines {+$08}, 5x10 points chars {+$04}
    	ldi DataAcc, $2C
    	rcall Byte2Displ
    WaitInitMode0x20:
    	rcall LCDBusyTest
    	brts WaitInitMode0x20
    ;set mode {+$04}, incrase cursor address after displaying char {+$02}, shift the display {*$01}
    	ldi DataAcc, $06
    	rcall Byte2Displ
    WaitInitMode0x04:
    	rcall LCDBusyTest
    	brts WaitInitMode0x04
    	rcall PLSigns
    	rcall CursReset
    	rcall CursOff ;n ;Bl
    	ret
  • #3 1616357
    rafiks
    Poziom 18  
    Posty: 425
    Ocena: 7
    Light, ja sie pytam co jest nie tak w tej mojej procedurze bo chciał bym zrozumieć działanie tej inicjacji a ty mi wywalasz kilka dziesiąt linijek tekstu.
  • #4 1616429
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    A na czym łatwiej wytłumaczyć, na działającym, czy nie działającym kodzie ? ;)
    1. Ustaw wszystkie linie sterujące na 0 (RW, RS, EN)
    2. Czekaj 15ms
    3. 3 razy wystaw połówki ustawienia dla trybu 8-bit (0x3) i czekaj 15ms.
    4. Wystaw 0x2C w połówkach. Mamy tryb 4-bit, 2 linie, znaki 8x10.
    5. Wystaw 0x06. Mamy zwiększanie adresu po wpisaniu znaku.
    6. Resetujemy ekran i wyłaczamy miganie.
    Jakby co to tutaj jest ładna tabelka od trybów itp. :
    http://home.iae.nl/users/pouweha/lcd/lcd0.shtml
  • #5 1616891
    rafiks
    Poziom 18  
    Posty: 425
    Ocena: 7
    Ja juz niewiem co jest grane ustawiam wszystkie bity sterujace na 0 i czekam 15 ms

    Potem robie taka kombinacje

    RS 0
    R/W 0
    D7 = 0
    D6 = 0
    D5 = 0
    D4 = 0

    Rcall enabled
    Rcall enabled
    Rcall enabled

    D7 = 0
    D6 = 0
    D5 = 1
    D4 = 0

    Rcall enabled
    Rcall enabled
    D7 = 1
    D6 = 1
    D5 = 0
    D4 = 0
    Rcall enabled

    D7 = 0
    D6 = 0
    D5 = 0
    D4 = 0
    Rcall enabled
    D7 = 1
    D6 = 0
    D5 = 0
    D4 = 0
    Rcall enabled

    D7 = 0
    D6 = 0
    D5 = 0
    D4 = 0
    Rcall enabled
    D7 = 0
    D6 = 0
    D5 = 0
    D4 = 1
    Rcall enabled

    D7 = 0
    D6 = 0
    D5 = 0
    D4 = 0
    Rcall enabled
    D7 = 0
    D6 = 1
    D5 = 1
    D4 = 1
    Rcall enabled



    Enabled:
    RCall Wait_10ms
    Sbi PortB,E ;E - enabled wyswietlacza
    RCall Wait_10ms ;czekam bardzo dlugo
    Cbi PortB,E
    Ret



    I po takiej kombinacji dupa nic nie dziala kursor nie miga, ustawienia bitów brałem z dokumentacji
REKLAMA