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.

Driving LCD by PIC18F2423

Status
Not open for further replies.

vit2206

Newbie level 2
Joined
May 27, 2010
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,302
Hello everybody,

It should be very easy for most of you, but I need help urgently! I need to drive 16*2 LCD with PIC18F2423 MCU. I have a code in asm. However there are mistakes there:
1) the initialization time is too high (5-6 sec) have no idea why :-(
2) all the letters doubled, like 'HHEELLOO ...'...

I gues it somehow connected with PCL register, but I am too newbe to figure out myself ... please help!

Code:
LIST P=18F2423		;directive to define processor
	#include <P18F2423.INC>	;processor specific variable definitions



; LABEL EQUATES	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Timer1	EQU	20		; 1ms count register
TimerX	EQU	21		; Xms count register
Var	EQU	22		; Output variable
Point	EQU	23		; Program table pointer
Select	EQU	24		; Copy of RS bit
OutCod	EQU	25		; Temp store for output code
Var1	EQU 26			; First digit

RS	EQU	1		; Register select output bit
E	EQU	2		; Display enable

; PROGRAM BEGINS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	ORG	0		; Place machine code  
	NOP			; for ICD mode

	BANKSEL	TRISC		; Select bank 1 
	CLRF	TRISC			; All outputs
	MOVWF	TRISC		; Initialise display port 
	BANKSEL PORTC		; Select bank 0
	CLRF	PORTC		; Clear display outputs

	GOTO	Start		; Jump to main program 


; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 1ms delay with 1us cycle time (1000 cycles)...............
	
Onems	MOVLW	D'249'		; Count for 1ms delay 
	MOVWF	Timer1		; Load count
Loop1	NOP			; Pad for 4 cycle loop
	DECFSZ	Timer1		; Count
	GOTO	Loop1		; until Z
	RETURN			; and finish

	
; Delay Xms, X received in W ...............................

Xms	MOVWF	TimerX		; Count for X ms
LoopX	CALL	Onems		; Delay 1ms
	DECFSZ	TimerX		; Repeat X times 
	GOTO	LoopX		; until Z
	RETURN			; and finish
	

; Generate data/command clock siganl E .....................

PulseE	BSF	PORTC,E		; Set E high
	CALL	Onems		; Delay 1ms
	BCF	PORTC,E		; Reset E low
	CALL	Onems		; Delay 1ms
	RETURN			; done
	

; Send a command byte in two nibbles from RB4 - RB7 ........

Send	MOVWF	OutCod		; Store output code
	ANDLW	0F0		; Clear low nybble
	MOVWF	PORTC		; Output high nybble
	BTFSC	Select,RS	; Test RS bit
	BSF	PORTC,RS	; and set for data
	CALL	PulseE		; and clock display register
	CALL	Onems		; wait 1ms for display 

	SWAPF	OutCod		; Swap low and high nybbles 
	MOVF	OutCod,W	; Retrieve output code
	ANDLW	0F0		; Clear low nybble
	MOVWF	PORTC		; Output low nybble
	BTFSC	Select,RS	; Test RS bit
	BSF	PORTC,RS	; and set for data
	CALL	PulseE		; and clock display register
	CALL	Onems		; wait 1ms for display 
	RETURN			; done


;	Table of fixed characters to send ..................

Line1	ADDWF	PCL		; Modify program counter 
	RETLW	'H'		; Pointer = 0
	RETLW	'E'		; Pointer = 1
	RETLW	'L'		; Pointer = 2
	RETLW	'L'		; Pointer = 3
	RETLW	'O'		; Pointer = 4
	RETLW	' '		; Pointer = 5
	RETLW	' '		; Pointer = 6
	RETLW	' '		; Pointer = 7
	RETLW	' '		; Pointer = 8
	RETLW	' '		; Pointer = 9
	RETLW	' '		; Pointer = 10
	RETLW	' '		; Pointer = 11
	RETLW	' '		; Pointer = 12
	RETLW	' '		; Pointer = 13
	RETLW	' '		; Pointer = 14
	RETLW	' '		; Pointer = 15

Line2	ADDWF	PCL		; Modify program counter
	RETLW	'W'		; Pointer = 0
	RETLW	'O'		; Pointer = 1
	RETLW	'R'		; Pointer = 2
	RETLW	'L'		; Pointer = 3
	RETLW	'D'		; Pointer = 4
	RETLW	' '		; Pointer = 5
	RETLW	' '		; Pointer = 6
	RETLW	' '		; Pointer = 7
	RETLW	' '		; Pointer = 8
	RETLW	' '		; Pointer = 9
	RETLW	' '		; Pointer = 10
	RETLW	' '		; Pointer = 11



; Initialise the display....................................

Init	MOVLW	D'10'		; Load count for 100ms delay
	CALL	Xms		; and wait for display start
	MOVLW	0F0		; Mask for select code
	MOVWF	Select		; High nybble not masked

	MOVLW	0x30		; Load initial nibble
	MOVWF	PORTC		; and output it to display
	CALL	PulseE		; Latch initial code
	MOVLW	D'5'		; Set delay 5ms
	CALL	Xms		; and wait
	CALL	PulseE		; Latch initial code again
	CALL	Onems		; Wait 1ms
	CALL	PulseE		; Latch initial code again
	BCF		PORTC,4		; Set 4-bit mode
	CALL	PulseE		; Latch it
	
	MOVLW	0x28		; Set 4-bit mode, 2 lines
	CALL	Send		; and send code
	MOVLW	0x08		; Switch off display
	CALL	Send		; and send code
	MOVLW	0x01		; Code to clear display
	CALL	Send		; and send code
	MOVLW	0x06		; Enable cursor auto inc  
	CALL	Send		; and send code
	MOVLW	0x80		; Zero display address
	CALL	Send		; and send code
	MOVLW	0x0C		; Turn on display  
	CALL	Send		; and send code

	RETURN			; Done
	

; Send the fixed message to the display.....................

OutMes	CLRF	Point		; Reset table pointer
	BSF	Select,RS	; Select data mode

Mess1	MOVF	Point,W		; and load it
	CALL	Line1		; Get ASCII code from table
	CALL	Send		; and do it
	MOVLW	D'250'		; Load count to wait 250ms
	CALL	Xms			; so numbers are visible
	INCF	Point		; point to next character
	MOVF	Point,W		; and load the pointer
	SUBLW	D'7'		; check for last table item
	BTFSS	STATUS,Z	; and finish if 16 done
	GOTO	Mess1		; Output character code

	MOVLW	0xC0		; Move cursor to line 2 
	BCF	Select,RS	; Select command mode
	CALL	Send		; and send code
	CLRF	Point		; Reset table pointer
Mess2	MOVF	Point,W		; and load it
	CALL	Line2		; Get fixed character
	BSF	Select,RS	; Select data mode
	CALL	Send		; and send code
	MOVLW	D'250'		; Load count to wait 250ms
	CALL	Xms		; so numbers are visible
	INCF	Point		; next character
	MOVF	Point,W		; Reload pointer 
	SUBLW	D'11'		; and check for last
	BTFSS	STATUS,Z	; Skip if last
	GOTO	Mess2		; or send next
	RETURN			; done




; MAIN PROGRAM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Start	CALL	Init		; Initialise the display
	CALL	OutMes		; Display fixed characters
	
END


Thank you in advance.
Vitaliy
 

could you post the circuit diagram? at first impression, it should initialize on 4-bit mode, at least on 120ms and write a character every 250ms...

maybe you haven't used a 4MHz crystal for this app...

mmm...
i think the code is for a PIC16.... but you are using a pic18!!! mmm... must check about this issue...





maybe (just maybe) this corrects the double lettering...

Code:
temp   EQU 27         ; new temporal variable
Line1 BCF STATUS,C
   MOVWF temp
   RLFW  temp,W
   ADDWF   PCL      ; Modify program counter
   RETLW   'H'      ; Pointer = 0
   RETLW   'E'      ; Pointer = 1
   RETLW   'L'      ; Pointer = 2
   RETLW   'L'      ; Pointer = 3
   RETLW   'O'      ; Pointer = 4
   RETLW   ' '      ; Pointer = 5
   RETLW   ' '      ; Pointer = 6
   RETLW   ' '      ; Pointer = 7
   RETLW   ' '      ; Pointer = 8
   RETLW   ' '      ; Pointer = 9
   RETLW   ' '      ; Pointer = 10
   RETLW   ' '      ; Pointer = 11
   RETLW   ' '      ; Pointer = 12
   RETLW   ' '      ; Pointer = 13
   RETLW   ' '      ; Pointer = 14
   RETLW   ' '      ; Pointer = 15

Line2 BCF STATUS,C
   MOVWF temp
   RLFW  temp,W
   ADDWF   PCL      ; Modify program counter
   RETLW   'W'      ; Pointer = 0
   RETLW   'O'      ; Pointer = 1
   RETLW   'R'      ; Pointer = 2
   RETLW   'L'      ; Pointer = 3
   RETLW   'D'      ; Pointer = 4
   RETLW   ' '      ; Pointer = 5
   RETLW   ' '      ; Pointer = 6
   RETLW   ' '      ; Pointer = 7
   RETLW   ' '      ; Pointer = 8
   RETLW   ' '      ; Pointer = 9
   RETLW   ' '      ; Pointer = 10
   RETLW   ' '      ; Pointer = 11

as the PLC.0 bit must be 0... its specified on the DS00716A (maybe too old) microchip document...
 

    vit2206

    Points: 2
    Helpful Answer Positive Rating
thanks for help!

the doubling letters problem is solved! )
You are right. This code was initially written for PIC16F877 MCU, where it worked perfectly... But with PIC18F2423......... not really (
About oscillator speed.. today I've found that the speed is just 31kHz. I tried several times to change it (I've written 0x70 to OSCCON register), but program just didn't work at all... Wierd behaviour.
Moreover, I can't avoid this stupid
ADDWF PCL
RETLW '...'
structure. I mean, if I try to put some variables instead it just doesn't work. By 'doesn't work' I mean that LCD initialized but doesn't show anything :-(
By searching for register changes while running the not working program, I found out that the reason that LCD doesn't show anything is that data (message byte) goes to LATC register instead of PORTC (( WHY??? And PORTC remains cleared...

So I am very confused and have no idea what to do with this annoying LCD. Need help urgently...

thanks,
Vitaliy

P.S. following there is a schematic. Based on this I've changed following:
Code:
RS   EQU   0      ; Register select output bit 
E   EQU   1      ; Display enable


 

well according to the DS00716A you could use TABLE instructions so you could implement a better way to store your constant messages...

also, on pic16 this could help a lot!
Code:
temp   EQU 27         ; new temporal variable 
Line1 BCF STATUS,C 
   MOVWF temp 
   RLFW  temp,W 
   ADDWF   PCL      ; Modify program counter 
   dt "HELLO     " ; some spaces just in case.

Line2 BCF STATUS,C 
   MOVWF temp 
   RLFW  temp,W 
   ADDWF   PCL      ; Modify program counter 
   dt "WORLD           " ; notice the spaces.
on PIC16 using a 'dt' could save a lot of 'retlw', you must test it on pic18....

if you need to show a variable, you must convert from binary 8-bit to 3 digit ascii code, say

you have on Var the value D'34' you must convert it to characters '0'(0x30) '3'(0x33) and '4'(0x34)... i don't have the exact code for a PIC18 over asm, but maybe you can find it over the net...

the convertion process is something like...
divide Var by 10, the modulo (remainder?) is your first digit (units), converting it to ASCII is easy, just add 0x30(hexadecimal or 48 decimal) to the digit and 'send' it to the lcd...

set quotient as the new value of Var... and repeat until Var is 0...

this way you got all the digits from right to left, and is just a problem of ordering them...

hope this helps yo a little more
 

    vit2206

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top