fl { 3-wire Driver for an HD44780 based LCD Character based display PropForth 4.0/4.0a compatible 2011/4 3-wire LCD curcuit Propeller data P3 0x3 latch P4 0x4 clk P5 0x5 option below contrast P6 0x6 brightness P7 0x7 } \ j ( -- n1 ) the second most current loop counter : j _rsptr COG@ 5 + COG@ ; : variable lockdict create $C_a_dovarl w, 0 l, forthentry freedict ; \ waitcnt ( n1 n2 -- n3 ) \ wait until n1, n3 = n1 + n2 : waitcnt _execasm2>1 1F1 _cnip ; \ Edit 3 constant below to match your hardware 3 wconstant _data 4 wconstant _latch 5 wconstant _clk \ Option 1F8 wconstant ctra 1FA wconstant frqa 1FC wconstant phsa 6 wconstant _contrast 7 wconstant _bright 13880 constant 1msec \ 1msec tics wvariable char \ character number for LCD:x wvariable line \ line number for LCD:y wvariable cur_line \ current line number \ option wvariable cog variable b_cycle variable b_duty_on variable c_cycle variable c_duty_on wvariable pwm1 wvariable pwm2 1 _data lshift constant _datam 1 _latch lshift constant _latchm 1 _clk lshift constant _clkm \ Option 1 _contrast lshift constant _contrastm 1 _bright lshift constant _brightm : _data_out_l _datam _maskoutlo ; : _data_out_h _datam _maskouthi ; : _latch_out_l _latchm _maskoutlo ; : _latch_out_h _latchm _maskouthi ; : _clk_out_l _clkm _maskoutlo ; : _clk_out_h _clkm _maskouthi ; \ Option : _cont_out_l _contrastm _maskoutlo ; : _cont_out_h _contrastm _maskouthi ; : _bright_out_l _brightm _maskoutlo ; : _bright_out_h _brightm _maskouthi ; \ Option : set_contrast \ setting contrast for LCD ( n1 n2 -- ) n1:duty factor(%) n2:cycle(ms) io io>cog cog W@ or cog W! 4 1a lshift _contrast or ctra COG! 1 frqa COG! _contrast pinout 1msec u* c_cycle L! c_cycle L@ u* 64 u/ c_duty_on L! 1 cnt COG@ c_duty_on L@ + begin c_duty_on L@ negate phsa COG! c_cycle L@ waitcnt 0 until ; \ Option : set_bright \ setting contrast ( n1 n2 -- ) n1:duty factor(%) n2:cycle(ms) io io>cog 4 lshift cog W@ or cog W! 4 1a lshift _bright or ctra COG! 1 frqa COG! _bright pinout 1msec u* b_cycle L! b_cycle L@ u* 64 u/ b_duty_on L! 1 cnt COG@ b_duty_on L@ + begin b_duty_on L@ negate phsa COG! b_cycle L@ waitcnt 0 until ; \ Option : change_contrast \ change contrast ( n1 n2 -- ) n1:duty factor(%) n2:cycle(ms) 2dup 0= swap 0= or 0= if swap dup 64 > if drop 64 then swap cog W@ f and 4 = if 4 cogreset cog W@ f0 and cog W! then pwm2 W! pwm1 W! c" pwm1 W@ pwm2 W@ set_contrast" 4 cogx then ; \ Option : change_bright \ change brightness ( n1 n2 -- ) n1:duty factor(%) n2:cycle(ms) 2dup 0= swap 0= or 0= if swap dup 64 > if drop 64 then swap cog W@ f0 and 50 = if 5 cogreset cog W@ f and cog W! then pwm2 W! pwm1 W! c" pwm1 W@ pwm2 W@ set_bright" 5 cogx then ; : serial_send 8 0 do dup 1 7 i - lshift and 0> if _data_out_h else _data_out_l then _clk_out_h _clk_out_l loop drop _data_out_l 1 delms ; \ lcd_com - send command to HD44780 (n -- ) : lcd_com serial_send _latch_out_h _latch_out_l 2 delms ; \ setup propeller pins and initialize HD44780 : lcd_init \ set from P**(_data) to P**(_clk) to output _data 3 0 do dup pinout 1+ loop drop \ 8bit mode 32 delms \ wait 50msec 30 serial_send _latch_out_h _latch_out_l 5 delms _latch_out_h _latch_out_l 1 delms _latch_out_h _latch_out_l 5 delms 38 serial_send _latch_out_h _latch_out_l 8 serial_send _latch_out_h _latch_out_l 1 serial_send _latch_out_h _latch_out_l 6 serial_send _latch_out_h _latch_out_l c serial_send _latch_out_h _latch_out_l 10 char W! 2 line W! \ defsult setting is 16Charcters & 2Lines \ 0 cog W! cog W@ f0 and 50 <> if c" 32 5 set_bright" 5 cogx \ set LCD's backlight to duty=50% cycle time=5msec 6 delms \ wait cog W@ f0 and 50 <> if ." cog5 for brightness don't start" cr then then cog W@ f and 4 <> if c" 55 5 set_contrast" 4 cogx \ set LCD's contrast to 80% 6 delms \ wait cog W@ f and 4 <> if ." cog4 for contrast don't start" then then ; \ setup of display construction (x y -- ) : lcd_setup line W! char W! ; \ display character : lcd_char serial_send _data_out_h _latch_out_h _latch_out_l _data_out_l 2 delms ; \ display string ( cstr -- ) : lcd_str C@++ dup if bounds do i C@ lcd_char loop else 2drop then ; \ clear lcd : lcd_clear 1 lcd_com ; { x -- horizontal pos : 0x1 to 0x28 (decimal: 1 to 40Characters) y -- line number : 0x1 to 0x4 (decimal: 1 to 4Lines) ( x y -- ) } : lcd_pos 2 u/mod swap 0= if 1 = \ line is even? if 40 else char W@ 10 = if 50 else 54 then then else 0= if 0 else char W@ 10 = if 10 else 14 then then then 1- + 80 or lcd_com ; \ output cr : LCD_cr cur_line W@ 1+ dup line W@ > if drop 1 1 lcd_pos 1 cur_line W! else dup 1 swap lcd_pos cur_line W! then ; \ display decimal number to covert hex (n -- ) n:hex-value variable tmp wvariable result : lcd_dec 0 result W! 3b9aca00 tmp L! dup 80000000 and if invert 1+ 2d lcd_char then \ check minus? a 0 do dup tmp L@ >= if tmp L@ u/mod 30 + lcd_char 1 result W! else result W@ tmp L@ 1 = or if 30 lcd_char then then tmp L@ a u/ tmp L! loop drop ; \ display hex number (n1 n2 -- ) n1:hex-value n2:digits(1 to 8) : lcd_hex dup rot2 8 swap - 2 lshift lshift swap 0 do dup f0000000 and 1c rshift dup a < if 30 + else 37 + then lcd_char 4 lshift loop drop ; \ display binary number (n1 n2 -- ) n1:hex-value n2:digits(1 to 10) : lcd_bin dup rot2 20 swap - lshift swap 0 do dup 80000000 and if 31 else 30 then lcd_char 1 lshift loop drop ; \ output spaces ( n -- ) n:space's number output to LCD : lcd_blank dup if 0 do bl lcd_char loop else drop then ; : set_bar_graph 20 40 6 0 do \ set 6 charcters 8 0 do \ set 8 lines for 1 character dup lcd_com \ command for character to CG-RAM swap dup lcd_char swap \ write data 1+ loop f8 and swap dup 1 rshift or swap loop 2drop ; : sleep 8 serial_send _latch_out_h _latch_out_l \ display OFF cog W@ f and 4 = if 4 cogreset then cog W@ f0 and 50 = if 5 cogreset then 0 cog W! ; : wakeup c serial_send _latch_out_h _latch_out_l \ display ON c" 32 5 set_bright" 5 cogx \ set LCD's backlight to duty=50% cycle time=5msec 6 delms \ wait cog W@ f0 and 50 <> if ." cog5 for brightness don't start" cr then c" 28 5 set_contrast" 4 cogx \ set LCD's contrast to 80% 6 delms \ wait cog W@ f and 4 <> if ." cog4 for contrast don't start" then ; \ --------------------------------------------------------------------------------------------------- : demo lcd_init 10 4 lcd_setup \ 16characters 4line \ display char-code [0x20 - 0x7f] & [0xa0 - 0xff] 20 line W@ 2 = if 7 0 else 3 0 then do line W@ 2 = if i 3 = if 4 seti drop a0 then 2 0 else 4 0 then do line W@ 4 = if j 1 = if i 2 = if 20 + then then then 1 i 1+ lcd_pos 10 0 do dup lcd_char 100 delms 1+ loop loop loop drop lcd_clear \ display binary, hex, decimal c" 0x1+0x6 = b" lcd_str 1 6 + 4 lcd_bin 1 2 lcd_pos c" 0xACE+0xF=0x" lcd_str ace f + 4 lcd_hex 5 delsec lcd_clear 1 cur_line W! c" 0x12+0xe0=" lcd_str 12 e0 + lcd_dec c" (D)" lcd_str LCD_cr c" 0x0-0x12=" lcd_str 0 12 - lcd_dec c" (D)" lcd_str 5 delsec set_bar_graph lcd_clear c" Bar Graph" lcd_str 1 \ x-position char W@ 0 do 0 6 0 do dup lcd_char 1+ 64 delms swap dup 2 lcd_pos swap loop drop 1+ dup 2 lcd_pos \ increment x-position loop drop char W@ 2 lcd_pos char W@ char W@ 0 do 5 6 0 do dup lcd_char 1- 64 delms swap dup 2 lcd_pos swap loop drop 1- dup 2 lcd_pos loop drop lcd_clear c" Demo Finished" lcd_str 1 2 lcd_pos b3 c4 de b6 d8 b1 20 c6 b7 b5 b5 b 0 do lcd_char loop ; : set_bar_graph2 40 8 0 do \ set 8 charcters 8 0 do \ set 8 lines for 1 character dup lcd_com \ command for character to CG-RAM 7 j - i < if 1f else 0 then lcd_char \ write data 1+ loop f8 and loop drop ; variable tmp1 : demo2 lcd_init 10 4 lcd_setup \ 16characters 4line set_bar_graph2 lcd_clear c" Wave" lcd_str 1 2 lcd_pos 1 tmp L! 1 tmp1 L! 0 100 0 do dup char W@ 0 do dup lcd_char dup 7 = tmp L@ 1 = and if drop ff else dup ff = if drop 7 -1 tmp L! else dup 0 = if 1+ 1 tmp L! else tmp L@ + then then then loop drop 1 2 lcd_pos dup 7 = tmp1 L@ 1 = and if drop ff else dup ff = if drop 7 -1 tmp1 L! else dup 0 = if 1+ 1 tmp1 L! else tmp1 L@ + then then then loop drop ; : pwm_test lcd_init 10 4 lcd_setup \ 16characters 4line c" LCD Brightness " lcd_str 65 1 do 1 2 lcd_pos i lcd_dec i 5 change_bright 32 delms loop 32 5 change_bright lcd_clear c" LCD Contrasts " lcd_str 65 1 do 1 2 lcd_pos i lcd_dec i 5 change_contrast 32 delms loop 58 5 change_contrast lcd_clear c" Test Finished " lcd_str ;