Continue to Site

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.

  • 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.

LCD - Put content on the second line

Status
Not open for further replies.

Spadez

New Member
Hi,

Ive been looking into this today and trying several things but nothing seems to work. Im trying to display something on both the top line and the second line of my 16x2 LCD. What happens is either the second line doesnt show up, or it shows up on the top line after the first lines contents.

Here is my entire code:
Code:
;*********************************************************************;
;	LCD - V2.20 RGT : May 2010                                    ;
;	Based on _ FLASH MECHASCREEN  - V5.00 RRS : OCTOBER 2001      ;
;	An LCD screen driving routine for 4 data line applications    ;
;	For LCDs with HITACHI HD44780 and compatible controllers.     ;
;	Written for a 2 line display, init should be changed for a 1  ;
;	line display although it will work as is without displaying   ;
;	second message.                                               ;
;	All timings based on 4MHz oscillator.                         ;
;	Version 2 has screen macro to ease handling of large amounts  ;
;	of text.                                                      ;
;	Version 2.20 changed LCD PORT setup using #DEFINE to make     ;
;	changing port easier. e.g. 16F877A on ICD3 can't use PORTB. 
;James & Jonty
;3rd NOV 2010     Testing out 4 stage temp check
;Version 6  Screen and LED
;LED Port B1    ;
;*********************************************************************;

	LIST		P=16F628A

	INCLUDE		P16F628A.INC

	__CONFIG	_CP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_LVP_OFF&_MCLRE_OFF&_INTRC_OSC_NOCLKOUT 
; PWRTE_ON enables power up timer delay ~72ms which should help screen to self initialise

#DEFINE LCD_PORT	PORTB
#DEFINE LCD_TRIS	TRISB
;LCD_PORT bits
DATA7		EQU	.7	; )
DATA6		EQU	.6	; )4 bit wide
DATA5		EQU	.5	; )data bus
DATA4		EQU	.4	; )
RS		EQU	.3	; Register select - data or commands
E		EQU	.2	; Chip enable
;R/W should be tied to 0V
;Vo use preset (10K) 0V-5V, will be near 0V end.

;RAM locations
SCREEN_DELAY_LOOP	EQU	0x20
SCREEN_DELAY_LOOP1	EQU	0x21
MESS_POINTER		EQU	0x22	; Message pointer
WORD_STORE		EQU	0x23	; Store for commands / data information
TEMP_PCLATH		EQU	0x24	; Temp store for PCLATH during screen string routine

LOOP		EQU	0X20	;DELAY LOOP
LOOP1		EQU	0X21	;DELAY LOOP
COUNT		EQU	0X22
O_BYTE		EQU	0X23
I_BYTE		EQU	0X24
FLAGS		EQU	0X25
CALC_CRC	EQU	0X26	;CALCULATED CRC
BCOUNT		EQU	0X27
TEMP1		EQU	0X28	;TEMP MEMORY DURING CALC_CRC
TEMP2		EQU	0X29	;TEMP MEMORY DURING CALC_CRC

;SCRATCHPAD IS READ INTO 0X2A - 0X32
TEMP_LSB	EQU	0X2A
TEMP_MSB	EQU	0X2B
TH		EQU	0X2C
TL		EQU	0X2D
RES1		EQU	0X2E
RES2		EQU	0X2F
C_REMAIN	EQU	0X30
C_PERC		EQU	0X31
CRC		EQU	0X32

;FLAGS BITS
PRESENCE	EQU	.0	;PRESENCE
DS_ERROR	EQU	.1	;CRC ERROR

;DS1820 BITS
DQ_BIT		EQU	0
#DEFINE		DQ	PORTB,DQ_BIT
#DEFINE		TRIS_DQ	TRISB,DQ_BIT

;*******************************************************************************************
; Macro to call SEND_SCREEN_STRING, enables message strings to start beyond first 256 memory block
; and to cross block boundaries. Costs a few extra instructions per call, but greatly simplifies 
; string handling when dealing with > 256 bytes.

LCD_STRING	macro	lookup_address
		movf	PCLATH,W		; Store current value of PCLATH
		movwf	TEMP_PCLATH		; PCLATH may change below or in SEND_SCREEN_STRING
		if	high(lookup_address) != 0	; if start address of string is > 255
			movlw	high(lookup_address)
			movwf	PCLATH			; update PCLATH for string start address
		endif
		movlw	low(lookup_address)
		call	SEND_SCREEN_STRING
		movf	TEMP_PCLATH,W
		movwf	PCLATH			; Return PCLATH to original value
		endm

;*******************************************************************************************

	ORG	0x00		;Reset vector

	goto	START_OF_PROG

;*******************************************************************************************







;*******************************************************************************************
READ_SCRATCHPAD
;READ SCRATCHPAD, CHECK PRESENCE & CRC
	bcf	FLAGS,DS_ERROR
	call	DS_RESET
	btfss	FLAGS,PRESENCE
	return			;NOT PRESENT

	movlw	0XCC		;SKIP ROM
	call	OUT_BYTE
	movlw	0X44		;CONVERT TEMP
	call	OUT_BYTE

	call	PASSIVE_WAIT_CONVERSION

;	call	WAIT_CONVERSION		;CAN BE LONG _ DO OTHER THINGS?

	call	DS_RESET
	btfss	FLAGS,PRESENCE
	return			;NOT PRESENT

	movlw	0XCC		;SKIP ROM
	call	OUT_BYTE
	movlw	0XBE		;READ SCRATCHPAD
	call	OUT_BYTE

	clrf	CALC_CRC
	movlw	TEMP_LSB	;ADDRESS TO STORE TEMP_LSB
	movwf	FSR
	movlw	.9		;READ 9 BYTES FROM SCRATCHPAD
	movwf	BCOUNT

NEXT_CODE
	call	IN_BYTE
	movwf	INDF
	movwf	TEMP1
	movlw	.8
	movwf	COUNT		;8 BITS PER BYTE
	incf	FSR,F
	decfsz	BCOUNT,F
	goto	DO_CRC
	movf	TEMP1,W
	subwf	CALC_CRC,W	;Z WILL BE SET IF CRC CORRECT
	btfss	STATUS,Z
	bsf	FLAGS,DS_ERROR	;CRC WAS NOT CORRECT
	return
DO_CRC
	movf	CALC_CRC,W
	xorwf	TEMP1,W
	movwf	TEMP2		;STORE IN TEMP LOCATION THAT CAN BE ROTATED INTO C
	rrf	TEMP1,F		;ROTATE DATA READY FOR NEXT BIT
	rrf	TEMP2,W
	btfss	STATUS,C
	goto	NO_CARRY
	movlw	0X18
	xorwf	CALC_CRC,F
NO_CARRY
	rrf	CALC_CRC,F
	decfsz	COUNT,F
	goto	DO_CRC
	goto	NEXT_CODE

;------------------------------------------------------
DS_RESET
; RESET DS1820 _ CHECK FOR PRESENCE PULSE!
	bcf	FLAGS,PRESENCE
	call	PIN_LO
	movlw	.48
	call	DELAY_10US	;48 X 10US ~480US
	call	PIN_HI
	movlw	.6
	call	DELAY_10US	;6 X 10US ~60US
	btfss	DQ		;CHECK PRESENCE PULSE
	bsf	FLAGS,PRESENCE	;PRESENT
	movlw	.42
	call	DELAY_10US	;42 X 10US ~420US
	return

;------------------------------------------------------
PIN_LO
	bcf	DQ		;SET DATA PIN LOW, DO ONCE INITIALLY ?
	bsf	STATUS,RP0	;SAFEST THIS WAY _ OTHER CODE MAY ACCIDENTLY CHANGE DQ?
	bcf	TRIS_DQ		;SET DATA PIN AS OUTPUT
	bcf	STATUS,RP0
	return

;------------------------------------------------------
PIN_HI
	bsf	STATUS,RP0
	bsf	TRIS_DQ		;SET DATA AS INPUT WITH PULL UP!!!
	bcf	STATUS,RP0
	return

;------------------------------------------------------
OUT_BYTE
	movwf	O_BYTE
	movlw	.8
	movwf	COUNT
OUT_BYTE_1
	rrf	O_BYTE,F
	btfss	STATUS,C
	goto	OUT_0
	goto	OUT_1
OUT_BYTE_2
	decfsz	COUNT,F
	goto	OUT_BYTE_1
	return

OUT_0
	call	PIN_LO
	movlw	.6		;60US DELAY
	call	DELAY_10US
	call	PIN_HI
	goto	OUT_BYTE_2

OUT_1
	call	PIN_LO		;MOMENTARY _ LONGISH!
	call	PIN_HI
	movlw	.6		;60US DELAY
	call	DELAY_10US
	goto	OUT_BYTE_2

;------------------------------------------------------
IN_BYTE
	movlw	.8
	movwf	COUNT
	clrf	I_BYTE
IN_BYTE_1
	call	PIN_LO		;3US
	nop			;4US
	call	PIN_HI		;11US
	nop			;12US
	bcf	STATUS,C	;13US
	btfsc	DQ		;14US SAMPLE NEAR END OF 15US
	bsf	STATUS,C
	rrf	I_BYTE,F
	movlw	.4		;40US + EXTRAS _ MIN OF 45US
	call	DELAY_10US
	decfsz	COUNT,F
	goto	IN_BYTE_1
	movf	I_BYTE,W
	return

;------------------------------------------------------
WAIT_CONVERSION
;WAIT END OF CONVERSION WHILE ACTIVELEY POWERED
	bcf	DQ		;SET DATA PIN LOW  ?? DO ONCE INITIALLY ??
	bsf	STATUS,RP0	
	bcf	TRIS_DQ		;SET DATA PIN AS OUTPUT _ 0
	nop			;1US
	bsf	TRIS_DQ		;SET AS DATA AS INPUT WITH PULL UP!!!
	bcf	STATUS,RP0	;3US
	goto	$+1		;5US
	goto	$+1		;7US
	goto	$+1		;9US
	goto	$+1		;11US
	goto	$+1		;13US
	btfsc	DQ		;14US SAMPLE NEAR END OF 15US
	goto	CONV_FINISHED
	movlw	.6		;40US + EXTRAS _ MIN OF 45US
	call	DELAY_10US
	goto	WAIT_CONVERSION
CONV_FINISHED
	movlw	.4		;40US + EXTRAS _ MIN OF 45US
	call	DELAY_10US
	return	

;------------------------------------------------------
PASSIVE_WAIT_CONVERSION
;WAIT END OF CONVERSION WHILE PASSIVELEY POWERED
;ALSO WORKS WHILE POWERED
;MUST DRIVE DQ HIGH DURING CONVERSION

	bsf	DQ
	bsf	STATUS,RP0
	bcf	TRIS_DQ		;DRIVE HIGH
	bcf	STATUS,RP0

	movlw	.4		;4 * ~0.2S = ~800MS
	movwf	COUNT
	call	DELAY
	decfsz	COUNT,F
	goto	$-2

	bsf	STATUS,RP0
	bsf	TRIS_DQ		;FLOAT HIGH
	bcf	STATUS,RP0
	bcf	DQ
	return

;------------------------------------------------------
DELAY
	clrf	LOOP		; ~ 0.2S DELAY (~256 X 256 X 3 US)
	clrf	LOOP1
ENCORE
	decfsz	LOOP,F
	goto	ENCORE
	decfsz	LOOP1,F
	goto	ENCORE
	return

;------------------------------------------------------
DELAY_10US
	movwf	LOOP1
DELAY_10US_1
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	decfsz	LOOP1,F
	goto	DELAY_10US_1
	return

;******************************************************************************










MESSAGE_DATA
; Screen lookup table.
; Each string starts with an address command byte and is terminated by a zero.
; DT means Define Table and is an assembler instruction, the assembler converts this to a
; series of retlw's, DT's are generally more readable except when defining chars.

	movf	MESS_POINTER,W
	movwf	PCL

;	org	0x0f6		; Debug only DELETE these 2 lines !!!!!!!!!!!!!!
;				; me testing macro !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

user_defs
; User defined char 5 x 7 plus 1 cursor line
; three most significant bits are ignored by screen
; MSB set to 1 to avoid 0 end of string marker in mid string.

	retlw	0x48		; Start address of second character (1) in character generator ram.
;char 1				; The first character (0) is difficult to use as it can't be embedded
				; in a string as 0 is used as end of string marker.
	retlw	b'10001010'
	retlw	b'10000000'
	retlw	b'10000100'
	retlw	b'10000100'
	retlw	b'10000000'
	retlw	b'10010001'
	retlw	b'10001110'
	retlw	b'10000000'	; cursor line, sometimes separated from other 7 rows
;char 2
	retlw	b'10001010'	; 0x50 start address of char 2
	retlw	b'10000000'
	retlw	b'10000100'
	retlw	b'10000100'
	retlw	b'10000000'
	retlw	b'10001110'
	retlw	b'10010001'
	retlw	b'10000000'	; cursor line, sometimes separated from other 7 rows

	retlw	0		; 0 marks end of string

really_hot_message
	DT	0x80,"**** its hot",.1,.2,0	; 0x80 is effective address of first char on first line
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2 as defined above

hot_message
	DT	0x80,"Its hot",0		; 0x80 is effective address of first char on first line

medium_message
	DT	0x80,"Just right",.1,0		; 0x80 is effective address of first char on first line

cold_message					; 0xC0 is effective address of first char on second line
	DT	0xC0,"Its a bit nippy!",.2,0	; string followed by userdefined chars 1 & 2 as defined above

;*******************************************************************************************

INITIALISE

	clrf	LCD_PORT
	bsf	STATUS,RP0	; Change to bank 1
	movlw	b'00000000'	; unused bits 0 & 1
	movwf	LCD_TRIS	; Set data / control lines to Output
	bcf	STATUS,RP0	; Go back to bank 0
	bsf	PORTB,1		;LED ON

	movlw	.20			; ~15ms delay after screen power up before send to it
	movwf	SCREEN_DELAY_LOOP1	; this delay is approx 15ms ( 20 x 256 x 3 us) @ 4MHz
	clrf	SCREEN_DELAY_LOOP

	decfsz	SCREEN_DELAY_LOOP,F
	goto	$-1
	decfsz	SCREEN_DELAY_LOOP1,F
	goto	$-3

	movlw	0x20			; set 4 bit data bus, at power up will be in 8 bit at this stage
	call	SEND_SCREEN_CMD		; will actually send 0x2? and 0x0? do D0-D3 float high/low
	movlw	0x28			; 4 bit, 2 line display
	call	SEND_SCREEN_CMD
	movlw	0x06			; Entry mode DD increment
	call	SEND_SCREEN_CMD
	movlw	0x0E			; Display & cursor on, not flashing
	call	SEND_SCREEN_CMD		; Cursor is usefull while debuging, 0x0C for no cursor
	call	CLEAR_SCREEN
	return

;*******************************************************************************************

CLEAR_SCREEN

	movlw	0x01			; Clear display, home cursor
	call	SEND_SCREEN_CMD

	movlw	.3			; needs >= 1.64ms delay before next screen send
	movwf	SCREEN_DELAY_LOOP1			; this delay is approx 2.3ms ( 3 x 256 x 3 us) @ 4MHz
	clrf	SCREEN_DELAY_LOOP
REP
	decfsz	SCREEN_DELAY_LOOP,F
	goto	REP
	decfsz	SCREEN_DELAY_LOOP1,F
	goto	REP
	return

;*******************************************************************************************

SEND_SCREEN_CMD
	bcf	LCD_PORT,RS
	goto	SEND

SEND_SCREEN_DATA
	bsf	LCD_PORT,RS

SEND
	movwf	WORD_STORE	; Store all 8 bits of data
	movlw	B'00001111'
	andwf	LCD_PORT,F		; Clear data
	movf	WORD_STORE,W	; Collect data
	andlw	B'11110000'	; Strip bottom four bits
	iorwf	LCD_PORT,F		; Move data MSB Reg. B
	nop			; all nops to allow port settle prior to next change
	bsf	LCD_PORT,E		; Enable screen
	nop
	bcf	LCD_PORT,E
	movlw	B'00001111'
	andwf	LCD_PORT,F		; Clear data
	swapf	WORD_STORE,W	; Reverse nibbles of data
	andlw	B'11110000'	; Strip bottom four bits
	iorwf	LCD_PORT,F		; Move data LSB Reg. B
	nop
	bsf	LCD_PORT,E		; Enable screen
	nop
	bcf	LCD_PORT,E

	movlw	.12		; Delay between screen sends needs to be >= 40us
	movwf	SCREEN_DELAY_LOOP		; ~12 x 3 us + call & return etc > 40 us between screen sends

GO_ROUND_AGAIN
	decfsz	SCREEN_DELAY_LOOP,F
	goto	GO_ROUND_AGAIN

	return

;*******************************************************************************************

SEND_SCREEN_STRING

	movwf	MESS_POINTER
	call	MESSAGE_DATA		; Fetch address command
	call	SEND_SCREEN_CMD		; Send address set command

NEXT_DATA 
	incfsz	MESS_POINTER,F		; Increment message pointer and check for overflow
	goto	NO_OVERFLOW
	incf	PCLATH,F		; inc PCLATH to move to next 256 memory block
NO_OVERFLOW
	call	MESSAGE_DATA		; fetch data
	addlw	.0			; add zero, if data was 0 then Z of status will be set
	btfsc	STATUS,Z		; Test for stop byte
	return				; This message finished, return
	call	SEND_SCREEN_DATA	; Display character
	goto	NEXT_DATA

;*******************************************************************************************

START_OF_PROG

	call	INITIALISE		; Set up port and screen


RE_READ
	call	READ_SCRATCHPAD
	btfss	FLAGS,PRESENCE
	goto	NOT_PRESENT
	btfsc	FLAGS,DS_ERROR
	goto	READ_ERROR

	movf	TEMP_MSB,F
	btfss	STATUS,Z
	goto	NEGATIVE

	bcf	STATUS,C
	rrf	TEMP_LSB,F
				;TEMP_LSB IS DECIMAL TEMP
				;PLUS 0.5 DEGREE IF C SET
	;	goto	RE_READ

check_temp
	call	CLEAR_SCREEN
	movlw	.24			; compare W with Decimal 25  
	subwf	TEMP_LSB,W
	btfsc	STATUS,C		; result is C bit condition
	goto	cold

check_temp28
	call	CLEAR_SCREEN
	movlw	.28			; compare W with Decimal 25  
	subwf	TEMP_LSB,W
	btfsc	STATUS,C		; result is C bit condition
	goto	medium

check_temp30
	call	CLEAR_SCREEN
	movlw	.30			; compare W with Decimal 25  
	subwf	TEMP_LSB,W
	btfsc	STATUS,C		; result is C bit condition
	goto	hot


really_hot 
	bsf  PORTB,1
	LCD_STRING	really_hot_message	; Display user defined graphic characters
	goto RE_READ


cold 
	bcf  PORTB,1
	LCD_STRING	cold_message		; Display user defined graphic characters
	goto RE_READ

medium 
	bsf  PORTB,1
	LCD_STRING	medium_message
	goto RE_READ

hot 
	bsf  PORTB,1
	LCD_STRING	hot_message		; Display user defined graphic characters
	goto RE_READ






NEGATIVE
	;2'S COMPLIMENT NEGATIVE ROUTINE

NOT_PRESENT
	;DS1820 NOT FOUND ROUTINE

READ_ERROR
	;READ ERROR ROUTINE

FINISH
	goto	FINISH

	END

Here is the section that I was experimenting with:
Code:
really_hot_message
	DT	0x80,"Its hot",.1,.2,0	; 0x80 is effective address of first char on first line
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2 as defined above

When I put just this line:
Code:
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2

It is printed on the second line :s

James
 
Last edited:
hi James,
Running your program in Oshonsoft shows that when the ',0' at the end of the "crap its hot' string is reached, the RETURN resets the PCL to what it was before the CALL to the string, so the 2nd part of the string never gets processed, ' "its above 30"...
 
Excuse the langauge, i took it out in one bit of my code but not the other :p

Code:
really_hot_message
	DT	0x80,"Its hot",.1,.2	; 0x80 is effective address of first char on first line
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2 as defined above

It seems like something like this might work then, since I have removed the end of the string ".0" on the first line.
 
Excuse the langauge, i took it out in one bit of my code but not the other :p

Code:
really_hot_message
	DT	0x80,"Its hot",.1,.2	; 0x80 is effective address of first char on first line
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2 as defined above

It seems like something like this might work then, since I have removed the end of the string ".0" on the first line.

Hi,
I tried that and dosn't display the string correctly.
You have to use the string Macro again to service that 2nd line after the 1st line has completed.
 
hi
Like this.
Code:
really_hot_message
	;;;dw 0x0001
	DT	0x80,"Crap its hot",.1,.2,0	; 0x80 is effective address of first char on first line
really_hot_message2 	
	DT	0xC0,"Its above 30",0		; string followed by userdefined chars 1 & 2 as defined above
 

Attachments

  • AAesp01.gif
    AAesp01.gif
    9.7 KB · Views: 149
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top