Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC 16f876A with LCD problem (urgently)

Status
Not open for further replies.

Am_Da_One

Newbie level 2
Joined
Jul 23, 2005
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,322

i wrote the code for 16f876A and simulated it with PIC simuliator and simuilated fine ,,, but on hardware the LCD only shows empty blocks without any output data and here is the code :
NOTE : i checked also the hardware from other sites and it is correct .



;LCD text demo -8 bit mode
;Nigel Goodwin 2002

LIST p=16F876A ;tell assembler what chip we are using
include "P16F876A.inc" ;include the defaults for the chip



count equ 0x20
count1 equ 0x21
counta equ 0x22
countb equ 0x23
tmp1 equ 0x24
tmp2 equ 0x25
templcd equ 0x26
templcd2 equ 0x27


org 0x00
nop
org 0x05


Initialise
bcf STATUS, RP0 ;select bank 0
clrf count
clrf PORTA
clrf PORTB
clrf PORTC


SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x00 ;make all pins outputs
movwf TRISB
movwf TRISA
movwf TRISC
bcf STATUS, RP0 ;select bank 0

call Delay5 ;wait for LCD to settle


call LCD_Init ;setup LCD


start clrf count ;set counter register to zero
Message
movf count, w ;put counter value in W
call Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto NextMessage
call LCD_Char
call Delay5
incf count, f
goto Message

NextMessage call LCD_Line2 ;move to 2nd row, first column

clrf count ;set counter register to zero
Message2
movf count, w ;put counter value in W
call Text2 ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto EndMessage
call LCD_Char
call Delay5
incf count, f
goto Message2

EndMessage

call LCD_Line1
Stop goto start




;Subroutines and text tables

;LCD routines

;Initialise LCD
LCD_Init
movlw 0x38 ;Set 4 bit mode
call LCD_Cmd

movlw 0x1f ;Set display shift
call LCD_Cmd

movlw 0x06 ;Set display character mode
call LCD_Cmd

movlw 0x08 ;Set display on/off and cursor command
call LCD_Cmd

call LCD_Clr ;clear display

retlw 0x00

; command set routine
LCD_Cmd
movwf templcd
; swapf templcd, w ;send upper nibble
; andlw 0x0f ;clear upper 4 bits of W
; movwf PORTB
; bcf PORTB, 4 ;RS line to 0
; call Pulse_e ;Pulse the E line high

movf templcd, w ;send lower nibble
; andlw 0x0f ;clear upper 4 bits of W
movwf PORTB
bcf PORTC, 0 ;RS line to 0
call Pulse_e ;Pulse the E line high
call Delay5
retlw 0x00

LCD_CharD addlw 0x30
LCD_Char
movwf templcd
; swapf templcd, w ;send upper nibble
; andlw 0x0f ;clear upper 4 bits of W
; movwf PORTB
; bsf PORTB, 4 ;RS line to 1
; call Pulse_e ;Pulse the E line high

movf templcd, w ;send lower nibble
; andlw 0x0f ;clear upper 4 bits of W
movwf PORTB
bsf PORTC, 0 ;RS line to 1
call Pulse_e ;Pulse the E line high
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_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00

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

LCD_Clr movlw 0x01 ;Clear display
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 0x01 ;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

Pulse_e
bsf PORTC, 1
nop
bcf PORTC, 1
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


Text addwf PCL, f
retlw 'H'
retlw 'e'
retlw 'l'
retlw 'l'
retlw 'o'
retlw 0x00

Text2 ADDWF PCL, f
RETLW 'R'
RETLW 'e'
RETLW 'a'
RETLW 'd'
RETLW 'y'
RETLW '.'
RETLW '.'
RETLW '.'
RETLW 0x00


end
 

I think your LCD is not initialized properly. Take a look at my code, it works. Although I am not showing all the routines, you will get the idea.

Code:
L2_START	EQU	H'40'		;address of start of line 2 of LCD
INIT_CMD	EQU	B'00110000'	;LCD initialization command, send upper nibble only
F_SET_I4_CMD	EQU	B'00101000'	;LCD function set command, interface 4 bits, 2 lines
CLR_CMD		EQU	H'01'		;clear entire LCD display command
HOME_CMD	EQU	H'02'		;LCD return cursor home command
DISP_OFF_CMD	EQU	B'00001000'	;LCD display off command
DISP_ON_CMD	EQU	B'00001100'	;LCD display on, no cursor displayed, no blinking
MODE_CMD	EQU	B'00000110'	;LCD entry mode set command
CRLF_CMD	EQU	H'C0'		;LCD command to set address to start of line 2
LINE_LENGTH	EQU	D'24'		;length of LCD display line in characters
;====================================================================================
;This section initializes the LCD after power-up

LCD_INIT:	movlw D'160'		;LCD needs 15ms after power up before init. Make it 16ms
		call Long_dly		;
		movlw INIT_CMD		;output init command
		movwf PORTC		;
		bsf _LCD_E		;pulse Enable
		bcf _LCD_E		;
		movlw D'50'		;wait another 5ms; LCD requires 4.1ms
		call Long_dly		;
		bsf _LCD_E		;send init. command again
		bcf _LCD_E		;
		movlw D'2'		;wait another 200us; LCD needs 100us
		call Long_dly		;
		bsf _LCD_E		;send init. command once again
		bcf _LCD_E		;
		DELAY_100us		;wait 100us between commands;  LCD needs 40us
		movlw F_SET_I4_CMD	;set interface type to 4-bit
		andlw 0xF0		;mask out last 4 bits
		movwf PORTC		;output data
		bsf _LCD_E		;pulse Enable
		bcf _LCD_E		;
		DELAY_100us		;from this point on we can use the SEND_CMD,SEND_DATA
					;routines
		movlw F_SET_I4_CMD	;specify 4 bit interface, 2 lines, 5x7 dot characters
		call SEND_CMD		;
		DELAY_100us		;
		movlw DISP_OFF_CMD	;display off, cursor off, no blink
		call SEND_CMD		;
		DELAY_100us		;
		movlw CLR_CMD		;clear display, set DD RAM address to 0
		call SEND_CMD		;
		movlw D'20'		;must wait at least 1.64ms, we'll wait 2ms
		call Long_dly		;
		movlw MODE_CMD		;set mode to auto increment, no display shift
		call SEND_CMD		;
		DELAY_100us		;after this delay the display is initialized
		movlw DISP_ON_CMD	;
		call SEND_CMD		;turn on the display
		DELAY_100us		;


I have not looked at the rest of your code, I just assume it is correct.
Note the 15ms initial delay. Many people use a shorter delay, but when I wrote this code I checked the chip's datasheet and it was 15ms.
Also, note that you can only use regular commands with the LCD after a certain point in its initilization sequence. Before that, you pulse the enable line outside the command. After the last 100us delay the LCD is ready to accept normal commands and data.

I hope this helps. Otherwise, let me know.
 

I did not see you make PortA digital... You have to disable the comparators on portA. Check datasheet.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top