;*************************************************************************
; Tutorial 3.1h - Nigel Goodwin 2002
; Translated & adapted - Mickey5 2010
;*************************************************************************
; LCD szöveges demó (4 bites mód)
;*************************************************************************
     PROCESSOR 16F628A        ; Processzor típusát közli az assemblerrel.
     INCLUDE P16F628A.INC     ; Alapértelmezett beállítások a chip-hez.
     ERRORLEVEL 0,-302        ; Elnyomja a bank-váltás üzeneteit.
     ERRORLEVEL 0,-306        ; Elnyomja a lapváltás üzeneteit.
     RADIX HEX                ; Alapértelmezett számformátum.
     __IDLOCS H'0100'
     __config _CP_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
     ; Konfigurációs értékek.
                              ; (_BODEN_OFF _WDT_OFF _LVP_OFF _MCLRE_OFF)
                              ; (_INTRC_OSC_NOCLKOUT)

     cblock  0x20             ; Az általános célú regiszterek kezdőcíme.
             count            ; Számláló a ciklus-rutinokhoz.
             count1           ; Számlálók a késleltető rutinhoz.
             counta
             countb
             tmp1             ; Átmeneti tárolás.
             tmp2
             templcd          ; Átmeneti tároló a 4 bites módhoz.
             templcd2
     endc

LCD_PORT Equ PORTB
LCD_TRIS Equ TRISB
LCD_RS   Equ 0x04             ; A Register Select (RS) vonal változója.
LCD_RW   Equ 0x06             ; A Read/Write      (RW) vonal változója.
LCD_E    Equ 0x07             ; Az Enable         (E)  vonal változója.

     org 0x0000               ; Beállítja a 16F628-as kezdeti címét
                              ; (itt indul a program).

Start
     movlw   0x07             ; Kikapcsoljuk a komparátort
     movwf   CMCON            ; (így a 16F84-re hasonlít).

Initialise                    ; Inicializálás (kezdeti értékek beállítása).
     clrf    count
     clrf    PORTA
     clrf    PORTB

SetPorts                      ; Portok beállítása.
     bsf     STATUS,RP0       ; Kiválasztjuk a Register Page 1-et.
     movlw   0x00             ; Összes kapu kimenet.
     movwf   LCD_TRIS
     bcf     STATUS,RP0       ; Vissza a Register Page 0-ra.
     call    Kesleltet100     ; Várakozás az LCD inicializálására.
     call    LCD_Init         ; LCD beállítása.
     clrf    count            ; Számláló regiszter törlése.

Message                       ; Üzenetek kezelése.
     movf    count,W          ; Számláló értéke a W regiszterbe.
     call    Szoveg1          ; Beolvas egy karaktert az 1. táblázatból.
     xorlw   0x00             ; Zéró a státuszbit értéke?
     btfsc   STATUS,Z
     goto    NextMessage
     call    LCD_Char
     call    Kesleltet255
     incf    count,f
     goto    Message
NextMessage
     call    LCD_Line2        ; A 2. sor 1. oszlopába állítja a kurzort.
     clrf    count            ; Számláló regiszter törlése.
Message2
     movf    count,W          ; Számláló értéke a W regiszterbe.
     call    Szoveg2          ; Beolvas egy karaktert a 2. táblázatból.
     xorlw   0x00             ; Zéró a státuszbit értéke?
     btfsc   STATUS,Z
     goto    EndMessage
     call    LCD_Char
     incf    count,f
     goto    Message2
EndMessage     
     
Stop
     goto    Stop             ; Végtelen hurok.


; Szubrutinok és szövegtáblák

; LCD rutinok

; Alaphelyzetbe állítja az LCD-t (inicializál)
LCD_Init
     movlw   0x20             ; A 4 bites mód beállítása.
     call    LCD_Cmd

     movlw   0x28             ; Shift (betűemelés) beállítása.
     call    LCD_Cmd

     movlw   0x06             ; Karakter mód beállítása.
     call    LCD_Cmd

     movlw   0x0d             ; Kijelző ki/be és kurzor parancs.
     call    LCD_Cmd

     call    LCD_Clr          ; Kijelző törlése.

     retlw    0x00

; Parancs-üzemmód beállítása.
LCD_Cmd
     movwf   templcd
     swapf   templcd,W        ; Elküldi a felső nibble-t.
     andlw   0x0f             ; Törli a felső 4 bitet a W regiszterből.
     movwf   LCD_PORT
     bcf     LCD_PORT,LCD_RS  ; RS vonalat nullára állítja.
     call    Pulse_e          ; Magas impulzust küld az Enable lábra.

     movf    templcd,W        ; Elküldi a alsó nibble-t.
     andlw   0x0f             ; Törli a felső 4 bitet a W regiszterből.
     movwf   LCD_PORT
     bcf     LCD_PORT,LCD_RS  ; RS vonalat nullára állítja.
     call    Pulse_e          ; Magas impulzust küld az Enable lábra.
     call    Kesleltet5
     retlw   0x00

; Karakter-üzemmód beállítása.
LCD_CharD
     addlw   0x30
LCD_Char
     movwf   templcd
     swapf   templcd,W        ; Elküldi a felső nibble-t.
     andlw   0x0f             ; Törli a felső 4 bitet a W regiszterből.
     movwf   LCD_PORT
     bsf     LCD_PORT,LCD_RS  ; RS vonalat egyre állítja.
     call    Pulse_e          ; Magas impulzust küld az Enable lábra.

     movf    templcd,W        ; Elküldi a alsó nibble-t.
     andlw   0x0f             ; Törli a felső 4 bitet a W regiszterből.
     movwf   LCD_PORT
     bsf     LCD_PORT,LCD_RS  ; RS vonalat egyre állítja.
     call    Pulse_e          ; Magas impulzust küld az Enable lábra.
     call    Kesleltet5
     retlw   0x00

; Kurzor pozicionálása.
LCD_Line1
     movlw   0x80             ; Az 1. sor 1. oszlopába helyezi a kurzort.
     call    LCD_Cmd
     retlw   0x00

LCD_Line2
     movlw   0xc0             ; A 2. sor 1. oszlopába helyezi a kurzort.
     call    LCD_Cmd
     retlw   0x00

LCD_Line1W
     addlw   0x80             ; Az 1. sor W oszlopába helyezi a kurzort
     call    LCD_Cmd
     retlw   0x00

LCD_Line2W
     addlw   0xc0             ; A 2. sor W oszlopába helyezi a kurzort.
     call    LCD_Cmd
     retlw   0x00

LCD_CurOn
     movlw   0x0d             ; Kijelző ki/be és kurzor parancs.
     call    LCD_Cmd
     retlw   0x00

LCD_CurOff
     movlw   0x0c             ; Kijelző ki/be és kurzor parancs.
     call    LCD_Cmd
     retlw   0x00

LCD_Clr
     movlw   0x01             ; Törli a kijelzőt.
     call    LCD_Cmd
     retlw   0x00

LCD_HEX
     movwf   tmp1
     swapf   tmp1,w
     andlw   0x0f
     call    HEX_Table
     call    LCD_Char
     movf    tmp1,W
     andlw   0x0f
     call    HEX_Table
     call    LCD_Char
     retlw   0x00

Kesleltet255
     movlw   0xff             ; A késleltetés 255ms.
     goto    K0
Kesleltet100
     movlw   d'100'           ; A késleltetés 100ms.
     goto    K0
Kesleltet50
     movlw   d'50'            ; A késleltetés 50ms.
     goto    K0
Kesleltet20
     movlw   d'20'            ; A késleltetés 20ms.
     goto    K0
Kesleltet5
     movlw   0x05             ; A késleltetés 5.000 ms (4 MHz órajel).
K0
     movwf   count1
K1
     movlw   0xC7             ; A késleltetés 1ms.
     movwf   counta
     movlw   0x01
     movwf   countb
Kesleltet_0
     decfsz  counta,f
     goto    $+2
     decfsz  countb,f
     goto    Kesleltet_0

     decfsz  count1,f
     goto    K1
     retlw   0x00

Pulse_e
     bsf     LCD_PORT,LCD_E   ; Magasra állítja az LCD Enable bemenetét.
     nop                      ; Egy óraciklus idejére magasan tartja.
     bcf     LCD_PORT,LCD_E   ; Törli az E bemenetet (alacsony szint).
     retlw   0x00

; LCD rutinok vége.

HEX_Table
     addwf   PCL,f
     retlw   0x30
     retlw   0x31
     retlw   0x32
     retlw   0x33
     retlw   0x34
     retlw   0x35
     retlw   0x36
     retlw   0x37
     retlw   0x38
     retlw   0x39
     retlw   0x41
     retlw   0x42
     retlw   0x43
     retlw   0x44
     retlw   0x45
     retlw   0x46

Szoveg1
     addwf   PCL,f
     retlw   'H'
     retlw   'e'
     retlw   'l'
     retlw   'l'
     retlw   'o'
     retlw   0x00

Szoveg2
     addwf   PCL,f
     retlw   'R'
     retlw   'e'
     retlw   'a'
     retlw   'd'
     retlw   'y'
     retlw   '.'
     retlw   '.'
     retlw   '.'
     retlw   0x00


     end