Need help with character placement on LCD
robot
Posts: 13
Hey folks, Here is my problem. The characters on my 4x20 lcd screen get written to the third line before the second. I've read the datasheets for the lcd and understand that I must send the characters to the correct adress on the LCD. I'm not sure how to do this though.... Heres my code for sending characters and instructions
DATA· @0, "Text sent displayed on LCD" , %00000000·
Display:
READ index,ch 'read data from eeprom
IF ch = %00000000 THEN RETURN
GOSUB sendchr 'send to lcd
index = index + 1 'increment eeprom addr
GOTO Display
sendchr:
GOSUB busychk 'wait til lcd not busy
OUTB = ch.HIGHNIB 'upper part first
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
GOSUB busychk 'wait again
OUTB = ch.LOWNIB 'lower nibble
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
RETURN
·
DATA· @0, "Text sent displayed on LCD" , %00000000·
Display:
READ index,ch 'read data from eeprom
IF ch = %00000000 THEN RETURN
GOSUB sendchr 'send to lcd
index = index + 1 'increment eeprom addr
GOTO Display
sendchr:
GOSUB busychk 'wait til lcd not busy
OUTB = ch.HIGHNIB 'upper part first
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
GOSUB busychk 'wait again
OUTB = ch.LOWNIB 'lower nibble
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
RETURN
·
Comments
First, that can not be the entire routine, as less than one full line would probably be written. There is also no indication that the LCD was initialized, and if so how it was initialized. Certain parameters can be set during LCD initialization which can affect the "sizing" of the LCD and how the display is treated internally by the LCD controller chip.
Second, if you were presuming that the data statement being used (see below) would place the data on the LCD screen in any particular place, that is not the case. The "@ nnn" address merely indicates where to place the data in Stamp memory, not in the LCD ram.
DATA· @0, "Text sent displayed on LCD" , %00000000
Third, an explicit command must often be given to adjust the cursor to the location on the LCD where you want the data to appear. So too the actual location of where the data is to be displayed often must be set by manipulating the DDRAM address.
Fourth, you have given no indication as to the manufacturer and model of the LCD and whether it is HD44780 compatible. The HD44780 is an Hitachi LCD which is generally recognized as the de facto standard for character based LCD's, and the one with which most microcontrollers are compatible.
Regards,
Bruce Bates
Also, there is some good info in the StampWorks Manual
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Rick
' {$STAMP BS2}
' {$PBASIC 2.5}
pulstime CON 500 'pulsout time interval
'changes based on stamp model
'see "pulsout" command for
'timing details.
'
' Some command constants based on the Hitachi 44780 spec
'
WakeUp CON %00110000 'Wake up
FourBitMode CON %00100000 'Set to 4 bit mode
OneLine5x8Font CON %00100000 '1 line 5x8 font
OneLine5x10Font CON %00100100 '1 line 5x10 fnt
TwoLine5x8Font CON %00101000 '2 line 5x8
TwoLine5x10Font CON %00101100 '2 line 5x10
DisplayOff CON %00001000 'Display off
DisplayOn CON %00001100 'Display on, no cursor
DisplayOnULCrsr CON %00001110 'Display on, underline cursor
DisplayOnBLCrsr CON %00001101 'Display on, blink cursor
IncCrsr CON %00000110 'Auto-increment cursor no display shift
IncCrsrShift CON %00000111 'Auto-increment display. shift display left
DecCrsr CON %00000100 'Decrement cursor. No display shift
DecCrsrShift CON %00000101 'Decrement cursor with display shift
ClearDisplay CON %00000001 'clear display
HomeDisplay CON %00000010 'Cursor to home
ScrollLeft CON %00011000 'Scroll to left
ScrollRight CON %00010100 'Scroll right
CrsrLeft CON %00010000 'Cursor to left
CrsrRight CON %00010100 'Cursoft right
MoveCrsr CON %10000000 'Move cursor to position
MoveToCGRAM CON %01000000 'Move to CGRAM position
e CON 3 'enable
rw CON 2 'read/write
rs CON 1 'register select
'outb is data bus for lcd (p4-p7)
x VAR Byte 'scratchpad var
cmd VAR Byte 'command to sendcmd sub
ch VAR Byte 'character to sendchr sub
temp VAR Nib 'temp scratchpad
index VAR Byte 'index to eeprom
timecounter VAR Word
value VAR Byte
text VAR Word
DATA @0, "·· Press and hold····· light turn red,·· pushbutton to make " , %00000000
DATA @75, " When light turns··· fast as you can!··· green, let go as········ " , %00000000
DATA @150, "You must wait until light turns green" , %00000000
DATA @200, "Your time was ", %00000000
DATA @225, " ms", %00000000
Init:
DIRL = %11111110 'p1-p7 outputs
LOW e 'put
LOW rw ' control lines
LOW rs ' in initial state
PAUSE 500 'wait til vcc stable
GOSUB InitLCD 'initialize LCD
beginning:
cmd = ClearDisplay
GOSUB sendcmd
index = 0
GOSUB instructions
PAUSE 1250
cmd = ClearDisplay
GOSUB sendcmd
index = 75
GOSUB instructions
GOSUB Game
Game:
DO
···· IF (IN9 = 1)· THEN
···· LOW 14
···· HIGH 15
···· RANDOM value
···· PAUSE 1000 + value
···· HIGH 14
···· LOW 15
···· timecounter = 0
···· DO
···· PAUSE 1
···· timecounter = timecounter + 1
···· LOOP UNTIL IN9 = 0
···· LOW 14
···· timecounter = timecounter * 2
···· IF (timecounter = 2) THEN
···· cmd = ClearDisplay
···· GOSUB sendcmd
···· index = 150
···· GOSUB instructions
···· PAUSE 2000
···· GOTO beginning
···· ELSE
···· cmd = ClearDisplay
···· GOSUB sendcmd
···· index = 200
···· GOSUB instructions
···· DEBUG DEC timecounter
···· value = timecounter DIG 2
···· LOOKUP value, [noparse][[/noparse]32, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
···· GOSUB sendchr
···· value = timecounter DIG 1
···· LOOKUP value, [noparse][[/noparse]48, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
···· GOSUB sendchr
···· value = timecounter DIG 0
···· LOOKUP value, [noparse][[/noparse]48, 49, 50, 51, 52, 53, 54, 55, 56, 57], ch
···· GOSUB sendchr
···· index = 225
···· GOSUB instructions
···· PAUSE 2000
···· GOTO beginning
··· ENDIF
··· ENDIF
LOOP
instructions:
Display:
READ index,ch 'read data from eeprom
IF ch = %00000000 THEN RETURN
GOSUB sendchr 'send to lcd
index = index + 1 'increment eeprom addr
GOTO Display
'
' Initialize LCD according to specifications for the HD44780
'
InitLCD:
FOR x=1 TO 3 'spec said to do three times
OUTB = WakeUp>>4 'send wakeup call
PULSOUT e,pulstime 'send command
PAUSE 5
NEXT
OUTB = FourBitMode>>4 'go to 4 but mode
PULSOUT e,pulstime 'send it
PAUSE 1
'
' Initialization command sequence...
'
cmd = FourBitMode
GOSUB sendcmd
cmd = TwoLine5x8Font
GOSUB sendcmd
cmd = DisplayOff
GOSUB sendcmd
cmd = DisplayOnBLCrsr
GOSUB sendcmd
cmd = IncCrsr
GOSUB sendcmd
cmd = ClearDisplay
GOSUB sendcmd
cmd = HomeDisplay
GOSUB sendcmd
RETURN
'
' send character to ddram on lcd
'
sendchr:
GOSUB busychk 'wait til lcd not busy
OUTB = ch.HIGHNIB 'upper part first
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
GOSUB busychk 'wait again
OUTB = ch.LOWNIB 'lower nibble
HIGH rs 'rs high
PULSOUT e,pulstime 'send it
LOW rs 'reset rs
RETURN
'
' Send command in the var "cmd" to the lcd
'
sendcmd:
GOSUB busychk 'wait til lcd not busy
OUTB = cmd.HIGHNIB 'upper cmd first
PULSOUT e,pulstime 'send it
GOSUB busychk 'wait again
OUTB = cmd.LOWNIB 'lower nibble
PULSOUT e,pulstime 'send it
RETURN
'
' waits til the lcd is no longer busy and then returns
' uses the var "temp"
'
busychk:
DIRL = %00001110 'make lcd databus input
HIGH rw 'were reading
busyloop:
HIGH e 'enable
temp = INB 'get data from lcd
LOW e 'toggle back enable
PULSOUT e,pulstime 'because were in 4bit mode (two reads of 4 bits)
TEMP = temp & $80 'mask all but busy flag (db7 from lcd)
IF temp <> 0 THEN busyloop 'loop until not busy
LOW rw 'back to write
DIRL = %11111110 'reset databus back to output
RETURN
Here is my program in an easier to read format.............Hope this works!
You just have to structure your DATA so that you don't send more than 20 characters at a time, assuming that you're starting at the beginning of a line.
Are you familiar with the ASCII formatting codes?·
I am familiar with the ascii codes, I used some of them in my code above, however, I'm still new to this, and far from proficient at using them to control character placement.
That sound pretty simple. Just use a counter and add one to it each time you write a character to the screen. Once the count gets to the limit, do whatever it is that you need to do and reset the counter.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Anyway, you must structure your DATA·(break it up)·and not run more than·19 characters in succession (20 will force·the cursor·to the next line, but not the next line down) --·assuming that you begin at position 1 of any line.· Take stock of the situation (count) and figure to position your cursor accordingly.
Try programming the LCD outside of your game program, get a hang of the formatting codes, see how they work out.
12, "Hope", 10, 13, "This", 10, 13, "Makes", 10, 13, "Sense"