LCD con 16F684
Salve,
sono agli inizi con i PIC..e ho un problema. Non riesco a visualizzare una scritta su un display LCD a 2 righe. Il PIC che uso e' un 16F684. Vi allego lo schema elettrico e il programma (ho cercato di adattare un esempio di Zampilli per il 16F684).
Il problema è che non vedo niente sul display...
Grazie
Saluti
[img]<img%20src="http://immagini.p2pforum.it/out.php/i394986_LCD.JPG"%20alt=""%20/>[/img]
PROCESSOR 16F684
RADIX DEC
INCLUDE "P16F684.INC"
;Suppress MPASM warning message 302:
;"Register in operand not in bank 0. Ensure that bank bits are correct"
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF)
;LCD Control lines
LCD_RS equ 0 ;Register Select
LCD_E equ 1 ;Enable
;LCD data line bus
LCD_DB4 equ 2 ;LCD data line DB4
LCD_DB5 equ 3 ;LCD data line DB5
LCD_DB6 equ 4 ;LCD data line DB6
LCD_DB7 equ 5 ;LCD data line DB7
ORG 020H
tmpLcdRegister res 2
msDelayCounter res 2
;Reset Vector
ORG 00H
Start
bsf STATUS,RP0 ;Swap to register bank 1
movlw 00011111B ;Set PORTA lines
movwf TRISA
movlw 00000000B ;Set PORTC lines
movwf TRISC
; bcf PORTC,LCD_DB4 ;Set as output just the LCD's lines
; bcf PORTC,LCD_DB5
; bcf PORTC,LCD_DB6
; bcf PORTC,LCD_DB7
; bcf PORTC,LCD_E
;bcf PORTC,LCD_RS
bcf STATUS,RP0 ;Swap to register bank 0
;LCD inizialization
call LcdInit
;Locate LCD cursor on row 0, col 0
movlw 10H
call LcdLocate
;Shows "HELLO WORLD" string on LCD
movlw 'H'
call LcdSendData
movlw 'E'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'O'
call LcdSendData
movlw ' '
call LcdSendData
movlw 'W'
call LcdSendData
movlw 'O'
call LcdSendData
movlw 'R'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'D'
call LcdSendData
movlw ' '
call LcdSendData
movlw '!'
call LcdSendData
foreverLoop
goto foreverLoop
;**********************************************************************
; Delay subroutine
;
; W = Requested delay time in ms (clock = 4MHz)
;**********************************************************************
msDelay
movwf msDelayCounter+1
clrf msDelayCounter+0
; 1 ms (about) internal loop
msDelayLoop
nop
decfsz msDelayCounter+0,F
goto msDelayLoop
nop
decfsz msDelayCounter+1,F
goto msDelayLoop
return
;**********************************************************************
; Init LCD
; This subroutine must be called before each other lcd subroutine
;**********************************************************************
LcdInit
movlw 30 ;Wait 30 ms
call msDelay
;****************
; Reset sequence
;****************
bcf PORTC,LCD_RS ;Set LCD command mode
;Send a reset sequence to LCD
bsf PORTC,LCD_DB4
bsf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 5 ;Wait 5 ms
call msDelay
bcf PORTC,LCD_E ;Disables LCD
movlw 1 ;Wait 1ms
call msDelay
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disables LCD
movlw 1 ;Wait 1ms
call msDelay
bsf PORTC,LCD_E ;Enables E
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disables E
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_DB4
bsf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
;Set 4 bit data bus length
movlw 28H;
call LcdSendCommand
;Entry mode set, increment, no shift
movlw 06H;
call LcdSendCommand
;Display ON, Curson ON, Blink OFF
movlw 0EH
call LcdSendCommand
;Clear display
call LcdClear
return
;**********************************************************************
; Clear LCD
;**********************************************************************
LcdClear
;Clear display
movlw 01H
call LcdSendCommand
movlw 2 ;Wait 2 ms
call msDelay
;DD RAM address set 1st digit
movlw 80H;
call LcdSendCommand
return
;**********************************************************************
; Locate cursor on LCD
; W = D7-D4 row, D3-D0 col
;**********************************************************************
LcdLocate
movwf tmpLcdRegister+0
movlw 80H
movwf tmpLcdRegister+1
movf tmpLcdRegister+0,W
andlw 0FH
iorwf tmpLcdRegister+1,F
btfsc tmpLcdRegister+0,4
bsf tmpLcdRegister+1,6
movf tmpLcdRegister+1,W
call LcdSendCommand
return
;**********************************************************************
; Send a data to LCD
;**********************************************************************
LcdSendData
bsf PORTC,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a command to LCD
;**********************************************************************
LcdSendCommand
bcf PORTC,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a byte to LCD by 4 bit data bus
;**********************************************************************
LcdSendByte
;Save value to send
movwf tmpLcdRegister
;Send highter four bits
bcf PORTC,LCD_DB4
bcf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
btfsc tmpLcdRegister,4
bsf PORTC,LCD_DB4
btfsc tmpLcdRegister,5
bsf PORTC,LCD_DB5
btfsc tmpLcdRegister,6
bsf PORTC,LCD_DB6
btfsc tmpLcdRegister,7
bsf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
;Send lower four bits
bcf PORTC,LCD_DB4
bcf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
btfsc tmpLcdRegister,0
bsf PORTC,LCD_DB4
btfsc tmpLcdRegister,1
bsf PORTC,LCD_DB5
btfsc tmpLcdRegister,2
bsf PORTC,LCD_DB6
btfsc tmpLcdRegister,3
bsf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
return
END
sono agli inizi con i PIC..e ho un problema. Non riesco a visualizzare una scritta su un display LCD a 2 righe. Il PIC che uso e' un 16F684. Vi allego lo schema elettrico e il programma (ho cercato di adattare un esempio di Zampilli per il 16F684).
Il problema è che non vedo niente sul display...
Grazie
Saluti
[img]<img%20src="http://immagini.p2pforum.it/out.php/i394986_LCD.JPG"%20alt=""%20/>[/img]
PROCESSOR 16F684
RADIX DEC
INCLUDE "P16F684.INC"
;Suppress MPASM warning message 302:
;"Register in operand not in bank 0. Ensure that bank bits are correct"
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF)
;LCD Control lines
LCD_RS equ 0 ;Register Select
LCD_E equ 1 ;Enable
;LCD data line bus
LCD_DB4 equ 2 ;LCD data line DB4
LCD_DB5 equ 3 ;LCD data line DB5
LCD_DB6 equ 4 ;LCD data line DB6
LCD_DB7 equ 5 ;LCD data line DB7
ORG 020H
tmpLcdRegister res 2
msDelayCounter res 2
;Reset Vector
ORG 00H
Start
bsf STATUS,RP0 ;Swap to register bank 1
movlw 00011111B ;Set PORTA lines
movwf TRISA
movlw 00000000B ;Set PORTC lines
movwf TRISC
; bcf PORTC,LCD_DB4 ;Set as output just the LCD's lines
; bcf PORTC,LCD_DB5
; bcf PORTC,LCD_DB6
; bcf PORTC,LCD_DB7
; bcf PORTC,LCD_E
;bcf PORTC,LCD_RS
bcf STATUS,RP0 ;Swap to register bank 0
;LCD inizialization
call LcdInit
;Locate LCD cursor on row 0, col 0
movlw 10H
call LcdLocate
;Shows "HELLO WORLD" string on LCD
movlw 'H'
call LcdSendData
movlw 'E'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'O'
call LcdSendData
movlw ' '
call LcdSendData
movlw 'W'
call LcdSendData
movlw 'O'
call LcdSendData
movlw 'R'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'D'
call LcdSendData
movlw ' '
call LcdSendData
movlw '!'
call LcdSendData
foreverLoop
goto foreverLoop
;**********************************************************************
; Delay subroutine
;
; W = Requested delay time in ms (clock = 4MHz)
;**********************************************************************
msDelay
movwf msDelayCounter+1
clrf msDelayCounter+0
; 1 ms (about) internal loop
msDelayLoop
nop
decfsz msDelayCounter+0,F
goto msDelayLoop
nop
decfsz msDelayCounter+1,F
goto msDelayLoop
return
;**********************************************************************
; Init LCD
; This subroutine must be called before each other lcd subroutine
;**********************************************************************
LcdInit
movlw 30 ;Wait 30 ms
call msDelay
;****************
; Reset sequence
;****************
bcf PORTC,LCD_RS ;Set LCD command mode
;Send a reset sequence to LCD
bsf PORTC,LCD_DB4
bsf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 5 ;Wait 5 ms
call msDelay
bcf PORTC,LCD_E ;Disables LCD
movlw 1 ;Wait 1ms
call msDelay
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disables LCD
movlw 1 ;Wait 1ms
call msDelay
bsf PORTC,LCD_E ;Enables E
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disables E
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_DB4
bsf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
;Set 4 bit data bus length
movlw 28H;
call LcdSendCommand
;Entry mode set, increment, no shift
movlw 06H;
call LcdSendCommand
;Display ON, Curson ON, Blink OFF
movlw 0EH
call LcdSendCommand
;Clear display
call LcdClear
return
;**********************************************************************
; Clear LCD
;**********************************************************************
LcdClear
;Clear display
movlw 01H
call LcdSendCommand
movlw 2 ;Wait 2 ms
call msDelay
;DD RAM address set 1st digit
movlw 80H;
call LcdSendCommand
return
;**********************************************************************
; Locate cursor on LCD
; W = D7-D4 row, D3-D0 col
;**********************************************************************
LcdLocate
movwf tmpLcdRegister+0
movlw 80H
movwf tmpLcdRegister+1
movf tmpLcdRegister+0,W
andlw 0FH
iorwf tmpLcdRegister+1,F
btfsc tmpLcdRegister+0,4
bsf tmpLcdRegister+1,6
movf tmpLcdRegister+1,W
call LcdSendCommand
return
;**********************************************************************
; Send a data to LCD
;**********************************************************************
LcdSendData
bsf PORTC,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a command to LCD
;**********************************************************************
LcdSendCommand
bcf PORTC,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a byte to LCD by 4 bit data bus
;**********************************************************************
LcdSendByte
;Save value to send
movwf tmpLcdRegister
;Send highter four bits
bcf PORTC,LCD_DB4
bcf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
btfsc tmpLcdRegister,4
bsf PORTC,LCD_DB4
btfsc tmpLcdRegister,5
bsf PORTC,LCD_DB5
btfsc tmpLcdRegister,6
bsf PORTC,LCD_DB6
btfsc tmpLcdRegister,7
bsf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
;Send lower four bits
bcf PORTC,LCD_DB4
bcf PORTC,LCD_DB5
bcf PORTC,LCD_DB6
bcf PORTC,LCD_DB7
btfsc tmpLcdRegister,0
bsf PORTC,LCD_DB4
btfsc tmpLcdRegister,1
bsf PORTC,LCD_DB5
btfsc tmpLcdRegister,2
bsf PORTC,LCD_DB6
btfsc tmpLcdRegister,3
bsf PORTC,LCD_DB7
bsf PORTC,LCD_E ;Enables LCD
movlw 1 ;Wait 1ms
call msDelay
bcf PORTC,LCD_E ;Disabled LCD
movlw 1 ;Wait 1ms
call msDelay
return
END