lcd.frt
\ HD44780 LCD interface library
marker _lcd_
PORTD 2 portpin: rs
PORTD 3 portpin: rw
PORTD 4 portpin: e
PORTB 0 portpin: db4
PORTB 1 portpin: db5
PORTB 2 portpin: db6
PORTB 3 portpin: db7
variable 4bitmode
16 constant lcd.width
: lcd.initpins
rw pin_output
rs pin_output
e pin_output
db7 pin_output
db6 pin_output
db5 pin_output
db4 pin_output
db7 low
db6 low
db5 low
db4 low
rw high
rs high
e low
;
\ Pulses the E line for approx. 1ms.
: lcd.epulse
e high 1ms e low 1ms
;
: lcd.command ( cmd -- )
rw low ( write mode)
e low ( clock is based on high pulses, but sampled on downward slope)
4bitmode @ 1 = if
dup ( make a copy of the cmd byte, we'll need it twice)
$f0 and 4 rshift ( shift down high nibble)
PORTB c! lcd.epulse ( shift out the high nibble)
$0f and ( zero out high nibble)
PORTB c! lcd.epulse ( shift out the low nibble)
else
PORTB c! lcd.epulse ( shift out the whole byte)
then
rw high ( read mode)
\ According to the datasheet, DB7 indicates a busy flag. Checking it wasn't
\ working for me, so this is disabled for now.
\ db7 pin_input
\ db7 low
\ begin
\ lcd.epulse
\ lcd.epulse
\ db7 pin_low?
\ until
;
\ Send a command byte to the LCD.
: lcd.sendcmd ( c -- )
rs low
lcd.command
;
\ Emit a character to the LCD, based on the current DDRAM address.
: lcd.emit ( c -- )
rs high
lcd.command
;
\ Print a string to the LCD. String is placed on stack via s" " word.
\ If string is longer than lcd.width characters, only lcd.width characters are printed.
: lcd.print ( addr u x y -- )
dup 1 > if abort" Y > 1" then ( ensure Y address is within range (0 or 1))
1 = if $40 + then ( if Y==1, add 2nd line offset of $40 )
$80 + ( add command to offset)
lcd.command ( set DDRAM address)
lcd.width min ( truncate string if necessary)
0 do ( for each character in string -- consumes count)
dup ( make a copy of the address of the string)
c@ ( fetch character (consumes address))
lcd.emit ( emit this character)
1+ ( increment address)
loop
drop ( drop the string address)
;
\ Initialize a HD44780 LCD. Right now this assumes 4 bit mode.
: lcd.init ( -- )
lcd.initpins
$20 lcd.command ( set 4 bit mode)
1 4bitmode !
$28 lcd.command ( set 4 bit mode, 2 line display)
$0F lcd.command ( display on, cursor underline and blinking)
$06 lcd.command ( entry mode set, shift cursor right and increment)
s" Hello world" 0 0 lcd.print
;
Generated by GNU enscript 1.6.4.