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:
Here is the section that I was experimenting with:
When I put just this line:
It is printed on the second line :s
James
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: