need a help with interfacing lcd with pic16f877a in asm ?!

Status
Not open for further replies.
thanks all for your appreciated effort

the problem was in these lines
Code:
BSF STATUS,RP0 ;SELECT BANK1 TO
BCF STATUS,RP1; ACCESS SFRs IN BANK1
BSF LCD_D7_Direction
BSF STATUS,RP0 ;RETURN TO BANK0

the last line should be
BCF status,RP0
to return back to bank0


the final lcd.inc

Code:
#define LCD_RS PORTC,RC2
#define LCD_RW PORTB,RB1
#define LCD_EN PORTD,RD0
#define LCD_D4 PORTC,RC4
#define LCD_D5 PORTD,RD5
#define LCD_D6 PORTB,RB6
#define LCD_D7 PORTD,RD7

#define LCD_RS_Direction TRISC,RC2
#define LCD_RW_Direction TRISB,RB1
#define LCD_EN_Direction TRISD,RD0
#define LCD_D4_Direction TRISC,RC4
#define LCD_D5_Direction TRISD,RD5
#define LCD_D6_Direction TRISB,RB6
#define LCD_D7_Direction TRISD,RD7


        cblock    0x70            ;start of general purpose registers
            count            ;used in looping routines
            count1            ;used in delay routine
            counta            ;used in delay routine
            countb            ;used in delay routine
            tmp1            ;temporary storage
            tmp2
            templcd            ;temp store for 4 bit mode
            templcd2
            LCDTEMP
            LCDTEMP2
            
        endc




LCDSETCURSOR MACRO ROW,COL

       IF COL>=10
       MOVLW COL
       ANDLW 0X0F
       CALL MAP
       ENDIF
       IF COL<10
       MOVLW COL
       ENDIF

       IF ROW==1
       CALL LCD_Line1W
       ENDIF
       IF ROW==2
       CALL LCD_Line2W
       ENDIF

    ENDM
 




LCD_TEXT_XY MACRO R,C,TEXT
    LOCAL MM
    LOCAL ST
    LOCAL EX
    LOCAL Y=0
    GOTO ST
MM DT TEXT ;Form a lookup table from parameters
       DT 0
       ST
      LCDSETCURSOR R,C
    WHILE Y<16 ;Conditional program translation - repeat 16x
      CALL MM+Y ;Read lookup table and store value to W
      ADDLW .0
      BTFSC STATUS,Z
      GOTO EX ;until it reads zero
      CALL LCD_Char ;Call the routine that prints W on LCD
      Y=Y+1
      ENDW
      EX
      ENDM






LCD_TEXT MACRO TEXT
    LOCAL MESSAGE
    LOCAL START
    LOCAL EXIT
    LOCAL I=0
    GOTO START
MESSAGE DT TEXT ;Form a lookup table from parameters
       DT 0
       START
      ;LCDSETCURSOR ROW,COL
    WHILE I<16 ;Conditional program translation - repeat 16x
      CALL MESSAGE+I ;Read lookup table and store value to W
      ADDLW .0
      BTFSC STATUS,Z
      GOTO EXIT ;until it reads zero
      CALL LCD_Char ;Call the routine that prints W on LCD
      I=I+1
      ENDW
      EXIT
      ENDM





LCD_CHAR_XY MACRO RO,CO,CH
    
    
       LCDSETCURSOR RO,CO
    
       MOVLW CH
       CALL LCD_Char
       ENDM
 
LCD_CHAR MACRO CH
    
       MOVLW CH
       CALL LCD_Char
    
       ENDM




;LCD routines

;Initialise LCD
LCD_INIT    call    Delay100        ;wait for LCD to settle

        BSF STATUS,RP0 ;SELECT BANK1 TO
 BCF STATUS,RP1; ACCESS SFRs IN BANK1
 BCF LCD_D4_Direction
 BCF LCD_D5_Direction
 BCF LCD_D6_Direction
 BCF LCD_D7_Direction
 BCF LCD_RS_Direction
 BCF LCD_RW_Direction
 BCF LCD_EN_Direction

 BCF STATUS,RP0 ;RETURN BACK TO BANK0




 BCF LCD_RS
 BCF LCD_EN
 BCF LCD_RW

 CALL Delay5 ;DO 5MS DELAY
 CALL Delay5 ;DO 5MS DELAY
 CALL Delay5 ;DO 5MS DELAY

 MOVLW 0X03
 CALL lcdsnibble
 call Delay5
 MOVLW 0X03
 CALL lcdsnibble
 call Delay5
 MOVLW 0X03
 CALL lcdsnibble
 call Delay5

 MOVLW 0X02
 CALL lcdsnibble  ;// cmd: go into 4-bit mode (only MS 4bits connected)
 CALL Delay5
 MOVLW 0x28 ; // 4-bit mode, 2lines, 5*7 matrix
 CALL LCD_Cmd
 MOVLW 0x6 ; // enable display
 CALL LCD_Cmd
 MOVLW 0xC ; // display ON, cursor & blink OFF
 CALL LCD_Cmd
 MOVLW 0x1 ; // clear display, address counter to zero
 CALL LCD_Cmd

 CALL Delay100


 retlw    0x00

; command set routine
LCD_Cmd    movwf    LCDTEMP2
 
    BCF LCD_RS
    BSF STATUS,RP0 ;SELECT BANK1 TO
    BCF STATUS,RP1; ACCESS SFRs IN BANK1
    BSF LCD_D7_Direction
    BCF STATUS,RP0 ;RETURN TO BANK0
    WF
    BTFSC LCD_D7
    GOTO WF
    BANKSEL TRISB
    BCF LCD_D7_Direction
    BANKSEL PORTB

    BCF LCD_RS ;COMMAND
    NOP

    BCF LCD_RW; ;write
    NOP
    BCF LCD_EN


 SWAPF LCDTEMP2,W
 ANDLW 0X0F
 CALL lcdsnibble

 MOVF LCDTEMP2,W
 ANDLW 0X0F
 CALL lcdsnibble
 CALL Delay5
 retlw    0x00

LCD_CharD    addlw    0x30            ;add 0x30 to convert to ASCII
LCD_Char

    movwf    LCDTEMP2
    BCF LCD_RS
    BSF STATUS,RP0 ;SELECT BANK1 TO
    BCF STATUS,RP1; ACCESS SFRs IN BANK1
    BSF LCD_D7_Direction
    BCF STATUS,RP0 ;RETURN TO BANK0
    WFF
    BTFSC LCD_D7
    GOTO WFF
    BANKSEL TRISB
    BCF LCD_D7_Direction
    BANKSEL PORTB

    BSF LCD_RS ;DATA
    NOP

    BCF LCD_RW; ;write
    NOP
    BCF LCD_EN

 SWAPF LCDTEMP2,W
 ANDLW 0X0F
 CALL lcdsnibble

 MOVF LCDTEMP2,W
 ANDLW 0X0F
 CALL lcdsnibble
 CALL Delay5
 retlw    0x00

LCD_Line1    movlw    0x80            ;move to 1st row, first column
        call    LCD_Cmd
        retlw    0x00

LCD_Line2    movlw    0xc0            ;move to 2nd row, first column
        call    LCD_Cmd
        retlw    0x00

LCD_Line1W    addlw    0x80            ;move to 1st row, column W
        call    LCD_Cmd
        retlw    0x00

LCD_Line2W    addlw    0xc0            ;move to 2nd row, column W
        call    LCD_Cmd
        retlw    0x00

LCD_CURSOR_ON    movlw    0x0d            ;Set display on/off and cursor command
        call    LCD_Cmd
        retlw    0x00

LCD_CURSOR_OFF    movlw    0x0c            ;Set display on/off and cursor command
        call    LCD_Cmd
        retlw    0x00

LCD_CLEAR    movlw    0x01            ;Clear display
        call    LCD_Cmd
        retlw    0x00
    
LCD_RETURN_HOME    movlw    0x02        
        call    LCD_Cmd
        retlw    0x00
    
LCD_BLINK_CURSOR_ON    movlw    0x0F        
        call    LCD_Cmd
        retlw    0x00
    
LCD_BLINK_CURSOR_OFF    movlw    0x0E        
        call    LCD_Cmd
        retlw    0x00

LCD_MOVE_CURSOR_LEFT    movlw    0X10         
        call    LCD_Cmd
        retlw    0x00

LCD_MOVE_CURSOR_RIGHT    movlw    0x14        
        call    LCD_Cmd
        retlw    0x00
    
LCD_TURN_ON    movlw    0x0C        
        call    LCD_Cmd
        retlw    0x00
    
LCD_TURN_OFF    movlw    0x08        
        call    LCD_Cmd
        retlw    0x00

LCD_SHIFT_LEFT    movlw    0x18        
        call    LCD_Cmd
        retlw    0x00

LCD_SHIFT_RIGHT    movlw    0x1C        
        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

Delay255    movlw    0xff        ;delay 255 mS
        goto    d0
Delay100    movlw    d'100'        ;delay 100mS
        goto    d0
Delay50        movlw    d'50'        ;delay 50mS
        goto    d0
Delay20        movlw    d'20'        ;delay 20mS
        goto    d0
Delay5        movlw    0x05        ;delay 5.000 ms (4 MHz clock)
d0        movwf    count1
d1        movlw    0xC7            ;delay 1mS
        movwf    counta
        movlw    0x01
        movwf    countb
Delay_0
        decfsz    counta, f
        goto    $+2
        decfsz    countb, f
        goto    Delay_0

        decfsz    count1    ,f
        goto    d1
        retlw    0x00



;end of LCD routines

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

MAP            ADDWF   PCL,f
                RETLW   0x0A
                RETLW   0x0B
                RETLW   0x0C
                RETLW   0x0D
                RETLW   0x0E
                RETLW   0x0F
            
            
lcdsnibble

MOVWF LCDTEMP
 BTFSC LCDTEMP,0
 GOTO B4
 BCF LCD_D4
 GOTO B44
 B4
 BSF LCD_D4
 B44
;....................
;....................
 BTFSC LCDTEMP,1
 GOTO B5
 BCF LCD_D5
 GOTO B55
 B5
 BSF LCD_D5
 B55
;....................
;....................
 BTFSC LCDTEMP,2
 GOTO B6
 BCF LCD_D6
 GOTO B66
 B6
 BSF LCD_D6
 B66
;;....................
;;..................
 BTFSC LCDTEMP,3
 GOTO B7
 BCF LCD_D7
 GOTO B77
 B7
 BSF LCD_D7
B77

 NOP
 BSF LCD_EN
 NOP
 NOP
 BCF LCD_EN


 RETLW 0X00


and here is an example to print the analog value on lcd


Code:
    PROCESSOR 16F877A
INCLUDE <P16F877A.INC>

    __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:

    CBLOCK 0X20
    CNT
    ADhi ; Binary input high byte
    ADlo  ; Binary input low byte
    ADL
    ADH
    D11
    D2
    D3
    NumL            ;Binary inputs for decimal convert routine
    NumH
    TenK            ;Decimal outputs from convert routine
    Thou
    Hund
    Tens
    Ones
    ENDC
;START PROGRAM

    ORG 0
    GOTO MAIN
INCLUDE <LCD_SAR.INC>

MAIN:

    CALL LCD_INIT

    BSF STATUS,RP0 ;SELECT BANK1 TO
    BCF STATUS,RP1; ACCESS SFRs IN BANK1
    BSF TRISA,0
    MOVLW B'10000011'
    MOVWF ADCON1

    BCF STATUS,RP0 ;RETURN BACK TO BANK0

    MOVLW B'11000001'
    MOVWF ADCON0
 
BEGIN:

    MOVLW 007 ; load counter
    MOVWF CNT
LOOP
    DECFSZ CNT ; and delay 20us
    GOTO LOOP

    BSF ADCON0,GO ; start ADC..
wait
    BTFSC ADCON0,GO ; ..and wait for finish
    GOTO wait

    CALL CONV2D
    CALL Convert

    CALL LCD_CLEAR

    MOVF Thou,W
    ADDLW 0X30
    CALL LCD_Char

    MOVLW '.'
    CALL LCD_Char

    MOVF Hund,W
    ADDLW 0X30
    CALL LCD_Char

    MOVF Tens,W
    ADDLW 0X30
    CALL LCD_Char

    MOVF Ones,W
    ADDLW 0X30
    CALL LCD_Char

    LCD_TEXT " VOLT"
    LCD_TEXT_XY 2,0,"ANALOG"
    LCD_TEXT "//"
    LCD_TEXT_XY 2,8,"TEST"
    CALL DELAY_SECOND
    GOTO BEGIN

CONV2D:
    MOVF ADRESH,W ; get ADC result
    MOVWF ADhi ; high bits
    BANKSEL ADRESL ; in bank 1
    MOVF ADRESL,W ; get ADC result
    BANKSEL ADRESH ; default bank 0
    MOVWF ADlo ; low byte
; Multiply by 5 for result 0 - 5120 by shifting left 2 TIMES + THE ORIGINAL VALUE.........
    BCF STATUS,C ; rotate 0 into LSB and
    RLF ADlo ; shift low byte left
    BTFSS STATUS,C ; carry out?
    GOTO rot1 ; no, leave carry clear
    BSF STATUS,C ; rotate 1 into LSB and
rot1
    RLF ADhi ; shift high byte left
    BCF STATUS,C ; rotate 0 into LSB
    RLF ADlo ; rotate low byte left again
    BTFSS STATUS,C ; carry out?
    GOTO rot2 ; no, leave carry clear
    BSF STATUS,C ; rotate 1 into LSB and
rot2
    RLF ADhi ; shift high byte left

    MOVF ADRESH,W ; get ADC result
    MOVWF ADH ; high bits
    BANKSEL ADRESL ; in bank 1
    MOVF ADRESL,W ; get ADC result
    BANKSEL ADRESH ; default bank 0
    MOVWF ADL ; low byte

    BCF STATUS,C
    MOVF ADL,W
    ADDWF ADlo,F
    BTFSS STATUS,C
    GOTO NC
    MOVF ADH,W
    ADDWF ADhi,W
    ADDLW 0X01
    MOVWF ADhi
    GOTO HI
NC:
    MOVF ADH,W
    ADDWF ADhi,F
HI:
    MOVF ADhi,W
    MOVWF NumH
    MOVF ADlo,W
    MOVWF NumL
    RETURN ; done


;This routine downloaded from [URL]http://www.piclist.com[/URL]
Convert:                        ; Takes number in NumH:NumL
                                ; Returns decimal in
                                ; TenK:Thou:Hund:Tens:Ones
        swapf   NumH, w
        iorlw    B'11110000'
        movwf   Thou
        addwf   Thou,f
        addlw   0XE2
        movwf   Hund
        addlw   0X32
        movwf   Ones

        movf    NumH,w
        andlw   0X0F
        addwf   Hund,f
        addwf   Hund,f
        addwf   Ones,f
        addlw   0XE9
        movwf   Tens
        addwf   Tens,f
        addwf   Tens,f

        swapf   NumL,w
        andlw   0X0F
        addwf   Tens,f
        addwf   Ones,f

        rlf     Tens,f
        rlf     Ones,f
        comf    Ones,f
        rlf     Ones,f

        movf    NumL,w
        andlw   0X0F
        addwf   Ones,f
        rlf     Thou,f

        movlw   0X07
        movwf   TenK

                    ; At this point, the original number is
                    ; equal to
                    ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
                    ; if those entities are regarded as two's
                    ; complement binary.  To be precise, all of
                    ; them are negative except TenK.  Now the number
                    ; needs to be normalized, but this can all be
                    ; done with simple byte arithmetic.

        movlw   0X0A                             ; Ten
Lb1:
        addwf   Ones,f
        decf    Tens,f
        btfss   3,0
        goto   Lb1
Lb2:
        addwf   Tens,f
        decf    Hund,f
        btfss   3,0
        goto   Lb2
Lb3:
        addwf   Hund,f
        decf    Thou,f
        btfss   3,0
        goto   Lb3
Lb4:
        addwf   Thou,f
        decf    TenK,f
        btfss   3,0
        goto   Lb4

        retlw    0x00


;DELAY 1 SEC ROUTINE 4MHz oscillator
DELAY_SECOND:
    MOVLW .5 ;.10==B'00000101' 8MHz OSC
    MOVWF D3
LOOP3:
    MOVLW .200 ;.200==B'11111111'
    MOVWF D2
LOOP2:
    MOVLW .200 ;.200==B'11111111'
    MOVWF D11
LOOP1:
    NOP
    NOP
    DECFSZ D11,F
    GOTO LOOP1
    DECFSZ D2,F
    GOTO LOOP2
    DECFSZ D3,F
    GOTO LOOP3
    RETURN

END


regards
 
Last edited:
Congratulations. Those errors are hard to find. Then when you do find it, you feel like an idiot -- at least I do.

Thank you for the follow-up.

John
 
Reactions: emb
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…