fl { 2-wire Driver for an HD44780 based LCD Character based display PropForth 4.6 Modified for pulse_monitor Not used LCD_backlight 2-wire LCD curcuit Propeller latch P10 0xa clk P11 0xb LCD backlight P12 0xc Not used } hex \ aallot ( n1 -- ) add n1 to coghere, allocates space in the cog or release it, n1 is # of longs [ifndef aallot : aallot coghere W+! coghere W@ par >= if 10 ERR then ; ] \ cog, ( x -- ) allocate 1 long in the cog and copy x to that location [ifndef cog, : cog, coghere W@ COG! 1 aallot ; ] \ lasm ( addr -- ) expects an address pointing to a structure in the following form \ empty long, long upper address of the assembler routine, long lower address of the assembler routine \ a series of longs which are the assembler codes [ifndef lasm : lasm 4+ dup L@ swap 4+ swap over L@ dup coghere W! do 4+ dup L@ cog, loop drop ; ] \ _cfo ( n1 -- n2 ) n1 - desired frequency, n2 frqa/frqb : _cfo clkfreq 1- min 0 swap clkfreq um/mod swap clkfreq 2/ >= abs + ; : delsec 10 u/mod dup if 0 do 3e80 delms loop else drop then dup if 0 do 3e8 delms loop else drop then ; 1F8 wconstant ctra 1FA wconstant frqa \ Edit 2 constant below to match your hardware a wconstant _latch b wconstant _clk \ Comment out when not using brightness-control c wconstant _bright \ set LCD's braightness to oscillate pin at the specified frequency \ ( n1 --) n1 is the frequency, uses ctra NCO-mode : set_bright _cfo frqa COG! _bright dup pinout 10000000 + ctra COG! ; wvariable char \ character number for LCD:x wvariable line \ line number for LCD:y wvariable cur_line \ current line number 15A asmlabel a_reset 153 asmlabel a_clk_out 14F wconstant v_clk lockdict variable def_014F 0160 l, 014F l, 0 l, A0FE1A10 l, E4FE1B51 l, 5C7C0000 l, 68BFE94F l, 5CFEA550 l, 64BFE94F l, 5CFEA550 l, E4FE1153 l, 5CFDF0F1 l, 5C7C0075 l, 68BFE94F l, A0FE1C64 l, 5CFEA550 l, E4FE1D5C l, 64BFE94F l, 5C7C0075 l, freedict 1 _clk lshift constant _clkm : _latch_out_l _latch pinlo ; : _latch_out_h _latch pinhi ; : _clk_out_l _clk pinlo ; : _clk_out_h _clk pinhi ; \ lcd_com - send command to HD44780 (n -- ) : lcd_com invert 1ff and dup 0<> \ invert data if a_clk_out else drop then \ if n = 0 , drop \ count up until n by a_clk_out(assembler code) _latch_out_h _latch_out_l \ output High_pulse to LCD's Enable a_reset \ reset counter (assembler code) 1 delms ; \ setup propeller pins and initialize HD44780 : lcd_init def_014F lasm _clkm v_clk COG! \ set from P**(_data) to P**(_clk) to output _latch 2 0 do dup pinout 1+ loop drop a_reset \ 8bit mode 32 delms \ wait 50msec 30 invert 1ff and \ invert data a_clk_out _latch_out_h _latch_out_l 5 delms _latch_out_h _latch_out_l 1 delms _latch_out_h _latch_out_l 5 delms a_reset \ reset counter (assembler code) 1 delms 38 lcd_com 8 lcd_com 1 lcd_com 6 lcd_com c lcd_com 10 char W! 2 line W! \ defsult setting is 16Charcters & 2Lines \ 3e8 set_bright ; \ setup of display construction (x y -- ) : lcd_setup line W! char W! ; \ display character ( c -- ) : lcd_char 100 or \ Add RS=1 to character-code lcd_com ; \ 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- + dup . 80 or lcd_com 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 ; : sleep \ LCD Off (not erase display-data) 8 lcd_com \ display OFF 0 ctra COG! _bright pinin ; : wakeup \ LCD On c lcd_com \ display ON 3e8 set_bright \ 1kHz ; { : 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 ; : lcd_demo1 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 : lcd_demo2 \ wave 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 thens 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 ; } { fl :asm v_clk 0 __Ddelay mov _treg5 , # 10 __C djnz _treg5 , # __C __Edelayret ret a_clk_out __1 or outa , v_clk jmpret __Edelayret , # __Ddelay andn outa , v_clk jmpret __Edelayret , # __Ddelay djnz _sttos , # __1 spop jnext a_reset or outa , v_clk mov _treg6 , # 64 __11 jmpret __Edelayret , # __Ddelay djnz _treg6 , # __11 andn outa , v_clk jnext ;asm } decimal