• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Nigel's LCD Example

Status
Not open for further replies.

merhaka

New Member
I am trying to use Nigel's LCD example found here PIC Tutorial  Three - LCD Modules (The first one)

However, I'm using a 16F628A and simulating it in ISIS.. It doesn't really look like it's working correctly, as the pins flash (as they should) but for about 10 seconds - one would imagine that it should be near instant with the short text string being sent??

Also, nothing is shown on the LCD screen.. It remains blank.

I have modified the program header and selected the "Target Device" in MPLAB as 16F628A. is there something else I'm missing?

Code:
	LIST	p=16F628A		;tell assembler what chip we are using
	include "P16F628A.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3D18			;sets the configuration settings (oscillator type etc.)
 

Nigel Goodwin

Super Moderator
Most Helpful Member
Can't help you on a simulator, but the tutorials are well tried and tested, and in use by MANY people - simulators aren't real, and don't act accurately enough, I suspect it's your simulator at fault?.
 

Wp100

Well-Known Member
Hi,

how have you got your lcd connected in Isis ? - it just needs the 7 data line connecting - do not bother with the powers rails or the contrast trimmer.

do not draw in any xtal if your micro uses one - not needed by Isis.

point on the micro and right click it, then 'edit properities' goto the ' processor clock frequency' and just delete anything there so its blank.
 

merhaka

New Member
I suspect it's your simulator at fault?
I thought the same thing - and tried a test program with proton (type of basic programming) with a simple 'Hello world' - it works fine with the same wiring, on the 16F628A.. Near instant as well.

I wanted to remove the pull-up resistor from the equation, and moved the LCD to portb - its the same result (rather low data transfer to the LCD, and no display).

The code I am working with is a 1:1 from nigels site, but with the 16F628A declared, and PORTB instead of PORTA;

Code:
	LIST	p=16F628A		;tell assembler what chip we are using
	include "P16F628A.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3D18			;sets the configuration settings (oscillator type etc.)




		cblock	0x20			;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	
		endc

LCD_PORT	Equ	PORTB
LCD_TRIS	Equ	TRISB
LCD_RS		Equ	0x04			;LCD handshake lines
LCD_RW		Equ	0x06
LCD_E		Equ	0x07

		org	0x0000

		movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)

Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB



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

		call	Delay100		;wait for LCD to settle


		call	LCD_Init		;setup LCD


		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	Delay255
		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
		incf	count, f
		goto	Message2

EndMessage	
		
Stop		goto	Stop			;endless loop




;Subroutines and text tables

;LCD routines

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

		movlw	0x28			;Set display shift
		call	LCD_Cmd

		movlw	0x06			;Set display character mode
		call	LCD_Cmd

		movlw	0x0d			;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	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;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	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;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	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;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	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;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	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

Pulse_e		bsf	LCD_PORT, LCD_E
		nop
		bcf	LCD_PORT, LCD_E
		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
The connections are;
rB0 to d4, through to rB3 to d7
rB4 to RS
rB7 to E
RW tied to ground (the only modification to nigels wiring - RW is not used in this example though, timed delays are..)

Like I said, a quick test program in proton will display fine. Even with the .hex compiled output. Why nigels code doesn't work, well I'm not sure..

Proton Code;
Code:
Device = 16F628A
Config INTRC_OSC_NOCLKOUT, CP_OFF, WDT_OFF, PWRTE_ON, LVP_OFF
XTAL = 4

LCD_DTPIN = PORTB.0
LCD_RSPIN = PORTB.4
LCD_ENPIN = PORTB.7
LCD_INTERFACE = 4
LCD_LINES = 2
LCD_TYPE = 0
ALL_DIGITAL = True
 
DelayMS 100
Cls
 
Print At 1,1, "Hello"
Print At 2,1, "world!!"
 
End
 
Last edited:

SPDCHK

Member
I've had the same problem with Proteus and LCD displays, (with both 16F628 and 16F88) PICs.

As Nigel said, the code does work. (I've used his code on a prototype board and it works) but then transferring the hex to Proteus it does not work.

What I've found is that the way Proteus initializes the LCD is not the same as in real life. I had to make changes to the internal timers and initialization sequence to make it work for the 16F88. I haven't bothered with the 16F628.

It's definitively a Proteus issue.
 

merhaka

New Member
I think I will just stick with the idea that it works in real life..

My ebay lcd comes in early next week sometime
 

SPDCHK

Member
It took me forever to realize that I was using the upper nibble (Bits <4,5,6,7>) of Port B vs. the lower nibbles as used by Nigel on PortA. My code obviously does the nibble swap different to Nigel’s code. For the life of me I cannot get Nigel's code de-bugged to load into Proteus. So I include the code I converted from my 16F88 code that does work in Proteus.

BE AWARE, the DATA pins of the LCD is connected on PortB<4..7>

For those with Proteus, I also include a simple design file for the 628.
 

Attachments

SPDCHK

Member
Could you post your 16F88 code - specifically the timer/init changes? I'm interested to see whats different
Gramo, it's already on the forum under this thread. Open the "AI measure.zip" file. Full code included.
 

merhaka

New Member
Wow, cheers SPDCHK!

That compiles and simulates just fine. Well commented too

"Hello World"
"How-ya Doin?"

Cool :)

I'm not sure what is going on with Nigel's LCD routine and ISIS, I'll leave that for another day and get started on learning your *working* routine
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top