18f1320 and lcd troubles

Thread Starter

tryingtolearn

Joined Apr 4, 2010
17
Hello everyone. I have been studying and practicing on the 18f1320 and have gotten LEDs to blink and do different things. However, I am trying to implement a LCD screen and am having problems and based on what I have read everywhere on the internet I think it is with the initialization or with the setting of my internal oscillator but haven't been able to resolve it regardless of what I try. It turns on but shows black squares all the way across the top. I have the 44780 LCD set up as 8 bit with D0-D7 as B0-B7 and E-A2, RW-A1, RS-A0. I know it may be alot to ask but I would be really thankful if someone would take a look at the code I put together and maybe see if they see something. I am using MPLAB ASM and have no errors or warnings but still can't get it to work. Thanks.

Rich (BB code):
#include<p18f1320.inc>

    __config    _CONFIG1H, _INTIO2_OSC_1H
    __config    _CONFIG2L,  _PWRT_ON_2L
    __config    _CONFIG2H, _WDT_OFF_2H
    __config    _CONFIG3H, _MCLRE_OFF_3H
    __config    _CONFIG4L, _LVP_OFF_4L

    
;set ports
LCD_DATA        EQU    PORTB           ; LCD data lines interface
LCD_DATA_TRIS   EQU    TRISB
LCD_CTRL        EQU    PORTA           ; LCD control lines interface

;misc
LCD_TEMP        EQU    0x020           ; LCD subroutines internal use
TABLE_INDEX        EQU    0x021            ; Index to table strings
COUNT            EQU    0x022            ; A counter
DELAY           EQU    0x023           ; Used in DELAYxxx routines
X_DELAY         EQU    0x024           ; Used in X_DELAYxxx routines

;PORTA Bits
LCD_E           EQU    2               ; LCD Enable control line
LCD_RW          EQU    1               ; LCD Read/Write control line
LCD_RS          EQU    0               ; LCD Register-Select control line
    
;PORTB Bits
DB7        EQU    7        ; LCD dataline 7 (MSB)
DB6        EQU    6        ; LCD dataline 6
DB5        EQU    5        ; LCD dataline 5
DB4        EQU    4        ; LCD dataline 4
DB3        EQU    3        ; LCD dataline 3
DB2        EQU    2        ; LCD dataline 2
DB1        EQU    1        ; LCD dataline 1
DB0        EQU    0        ; LCD dataline 0 (LSB)

;Screen Lines
LCD_LINE0    EQU    0x000
LCD_LINE1    EQU    0x040

    org 0

        GOTO    START

START:
        movlw   b'01110000'     ; setup INTOSC for 8-MHz          |B1
        movwf   OSCCON      ; or b'01110000'
        movlw   B'01111111'        ; Set all analog ports to digital only (both porta & portb)
        movwf   ADCON1
        movlw   b'11111111' ; Set PORTA direction all input
         movwf   TRISA       
         movlw   b'00000000' ; Set PORTB direction all output
         movwf   TRISB
        CLRF    INTCON        ; Clear int-flags, Disable interrupts
        CLRF    PCLATH        ; Keep in lower 2KByte
        CLRF    PORTA        ; ALL PORT output should output Low.
        CLRF    PORTB

         cALL    LCDINIT        ; Initialize LCDisplay

        MOVLW    0x030        ; ASCII '0'
        MOVWF    COUNT
        MOVLW    LCD_LINE0

        CALL    LCDSDDA        ; Position cursor leftmost on first line

        CALL    TABLE_MSG    ; Display message
        MOVLW    LCD_LINE0 + 0x013

        CALL    LCDSDDA        ; Position cursor
        MOVF    COUNT, W

        CALL    LCDPUTCHAR    ; Display line number

        INCF    COUNT, F
        MOVLW    LCD_LINE1

        CALL    LCDSDDA

        CALL    TABLE_MSG
        MOVLW    LCD_LINE1 + 0x013

        CALL    LCDSDDA
        MOVF    COUNT, W

        CALL    LCDPUTCHAR

LOOP
        GOTO    LOOP        ; Stay here forever


TABLE_MSG
        MOVLW    0            ; Startindex of table message
DISP_MSG
        MOVWF    TABLE_INDEX    ; Holds message address

        CALL    MSG1
        ANDLW    0x0FF        ; Check if at end of message
        BTFSC    STATUS, Z    ; (zero returned at end)

        GOTO    TABLE_MSG_END             

        CALL    LCDPUTCHAR    ; Display character
        MOVF    TABLE_INDEX, W    ; Point to next character
        ADDLW    1

        GOTO    DISP_MSG
TABLE_MSG_END    RETURN



LCDINIT
                    ; Busy-flag is not yet valid
        CLRF    LCD_CTRL    ; ALL PORT output should output Low.
                    ; power-up delay
        MOVLW    0x01E
        CALL    X_DELAY500    ; 30 * 0.5mS = 15mS
                    ; Busy Flag should be valid from here
        MOVLW    0x038        ; 8-bit-interface, 2-lines
        CALL    LCDPUTCMD
        MOVLW    0x000        ; disp.off, curs.off, no-blink
        CALL    LCDDMODE
        CALL    LCDCLEAR
        MOVLW    0x004        ; disp.on, curs.off
        CALL    LCDDMODE
        MOVLW    0x002        ; auto-inc (shift-cursor)
        CALL    LCDEMODE
        RETURN

LCD_ENABLE
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        NOP
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        NOP
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        NOP
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        RETURN

LCDBUSY
        MOVLW    0x0FF        ; Set PORTB for input
        MOVWF    LCD_DATA_TRIS
        BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
        BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        MOVF    LCD_DATA, W    ; Read busy flag + DDram address
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        ANDLW    0x80        ; Check Busy flag, High = Busy
        BTFSS    STATUS, Z
        GOTO    LCDBUSY

LCDNOTBUSY    BCF    LCD_CTRL, LCD_RW
        MOVLW    0x000
        MOVWF    LCD_DATA_TRIS    ; Set PORTB for output
        RETURN

LCDCLEAR
        MOVLW    0x001
        CALL    LCDPUTCMD
        RETURN

LCDHOME
        MOVLW    0x002
        CALL    LCDPUTCMD
        RETURN

LCDEMODE
        ANDLW    0x003        ; Strip upper bits
        IORLW    0x004        ; Function set
        CALL    LCDPUTCMD
        RETURN

LCDDMODE
        ANDLW    0x007        ; Strip upper bits
        IORLW    0x008        ; Function set
        CALL    LCDPUTCMD
        RETURN

LCDSCGA
        ANDLW    0x03F        ; Strip upper bits
        IORLW    0x040        ; Function set
        CALL    LCDPUTCMD
        RETURN

LCDSDDA
        IORLW    0x080        ; Function set
        CALL    LCDPUTCMD
        RETURN

LCDGADDR
        MOVLW    0x0FF        ; Set PORTB for input
        MOVWF    LCD_DATA_TRIS
        BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
        BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        MOVF    LCD_DATA, W    ; Read busy flag + RAM address
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        ANDLW    0x07F        ; Strip upper bit
        BCF    LCD_CTRL, LCD_RW
        MOVLW    0x000
        MOVWF    LCD_DATA_TRIS    ; Set PORTB for output
        RETURN

LCDPUTCHAR
        MOVWF    LCD_TEMP    ; Character to be sent is in W
        CALL    LCDBUSY        ; Wait for LCD to be ready
        BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
        BSF    LCD_CTRL, LCD_RS; Set LCD in data mode
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        MOVF    LCD_TEMP, W
        MOVWF    LCD_DATA    ; Send data to LCD
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        RETURN

LCDPUTCMD
        MOVWF    LCD_TEMP    ; Command to be sent is in W
        CALL    LCDBUSY        ; Wait for LCD to be ready
        BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
        BCF    LCD_CTRL, LCD_RS; Set LCD in command mode
        BSF    LCD_CTRL, LCD_E    ; LCD E-line High
        MOVF    LCD_TEMP, W
        MOVWF    LCD_DATA    ; Send data to LCD
        BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
        RETURN

DELAY500    
        MOVLW    D'165'            ; +1        1 cycle
        MOVWF    DELAY                ; +2        1 cycle
DELAY500_LOOP    DECFSZ    DELAY, F    ; step 1    1 cycle
        GOTO    DELAY500_LOOP        ; step 2    2 cycles
DELAY500_END    RETURN                ; +3        2 cycles


X_DELAY500    
        MOVWF    X_DELAY            ; +1        1 cycle
X_DELAY500_LOOP    
        CALL    DELAY500    ; step1        wait 500uSec
        DECFSZ    X_DELAY, F            ; step2        1 cycle
        GOTO    X_DELAY500_LOOP        ; step3        2 cycles
X_DELAY500_END    RETURN                ; +2        2 cycles

MSG1
        addwf    PCL ,F        ;Jump to char pointed to in W reg
        retlw    'T'
        retlw    'E'
        retlw    'S'
        retlw    'T'
        retlw    ' '
        retlw    'L'
        retlw    'I'
        retlw    'N'
        retlw    'E'
        retlw    ' '
        retlw    'N'
        retlw    'U'
        retlw    'M'
        retlw    ' '
        retlw    '#'
        retlw    ' '
MSG1_END
    
    END                ; End of program
 
Top