fl { 2-wire Driver for an HD44780 based LCD Character based display PropForth 5.0 19/03/2012 14:24:44 2-wire LCD curcuit Propeller latch P0 0x0 clk P1 0x1 LCD backlight P3 0x3 This pin is not next to clk pin. } hex \ _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 0 wconstant _latch 1 wconstant _clk \ Comment out when not using brightness-control 3 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 \ ( n -- ) Output reset pulse n:reset pin mask lockdict create a_reset forthentry $C_a_lxasm w, h11D h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z1bixZB l, z2WyPX[ l, z1SyZ[Q l, z3[yP[L l, z1[ixZB l, z1SyLI[ l, z1SV01X l, z2WyPbF l, z3[yPfR l, z1SV000 l, freedict \ ( n1 n2 -- ) Output clock pulse n1:clock pin mask n2:number of clock-pulse lockdict create a_clk_out forthentry $C_a_lxasm w, h120 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WiPZB l, z1SyLI[ l, z1bixZB l, z1SyZvS l, z1[ixZB l, z1SyZvS l, z3[yP[L l, z1SyLI[ l, z1SV01X l, z2WiPik l, z20yPbU l, z3ryPb0 l, z1SV000 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 _clkm swap 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 _clkm a_reset \ reset counter (assembler code) 1 delms ; \ setup propeller pins and initialize HD44780 : lcd_init \ set from P**(_data) to P**(_clk) to output _latch 2 0 do dup pinout 1+ loop drop _clkm a_reset \ 8bit mode 32 delms \ wait 50msec _clkm 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 _clkm 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 \ 1kHz ; \ 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 ; decimal { fl build_BootOpt :rasm or outa , $C_stTOS mov $C_treg1 , # d100 __1 jmpret __loop_ret , # __loop djnz $C_treg1 , # __1 andn outa , $C_stTOS spop jexit __loop mov $C_treg2 , # d15 __2 djnz $C_treg2 , # __2 __loop_ret ret ;asm a_reset fl build_BootOpt :rasm mov $C_treg1 , $C_stTOS spop __1 or outa , $C_stTOS jmpret __waitret , # __wait andn outa , $C_stTOS jmpret __waitret , # __wait djnz $C_treg1 , # __1 spop jexit __wait mov $C_treg2 , cnt add $C_treg2 , # d30 waitcnt $C_treg2 , # 0 __waitret ret ;asm a_clk_out } { fl hex 0 wconstant _latch 1 wconstant _clk 1 _clk lshift constant _clkm lockdict create a_reset forthentry $C_a_lxasm w, h11D h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z1bixZB l, z2WyPX[ l, z1SyZ[Q l, z3[yP[L l, z1[ixZB l, z1SyLI[ l, z1SV01X l, z2WyPbF l, z3[yPfR l, z1SV000 l, freedict lockdict create a_clk_out forthentry $C_a_lxasm w, h120 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WiPZB l, z1SyLI[ l, z1bixZB l, z1SyZvS l, z1[ixZB l, z1SyZvS l, z3[yP[L l, z1SyLI[ l, z1SV01X l, z2WiPik l, z20yPbU l, z3ryPb0 l, z1SV000 l, freedict : test1 _latch 2 0 do dup pinout 1+ loop drop begin _clkm a_reset 1 delms 0 until ; : test2 _latch 2 0 do dup pinout 1+ loop drop begin _clkm 100 a_clk_out 0 until ; decimal }