fl { 2-wire Driver for an HD44780 based LCD Character based display (4bit control) Used Shift-register PropForth 5.0 03/05/2012 21:18:04 2-wire LCD curcuit Propeller latch P0 0x0 clk P1 0x1 LCD backlight P2 0x2 wire should be short } 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 2 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 \ serial out data(6bit) to shift-register \ ( n1 n2 n3 -- ) n1:shift-data n2:_latchm n3:_clkm lockdict create a_shift_data forthentry $C_a_lxasm w, h124 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WiPZB l, z1SyLI[ l, z2WiPeB l, z1SyLI[ l, zfyPOQ l, z2WyPj7 l, zgyPO1 l, z1bfxZD l, z1bixZC l, z2WiPyk l, z20yPrS l, z3ryPr0 l, z1[ixZD l, z1[ixZC l, z3[yPnP l, z1SyLI[ l, z1SV01X l, freedict \ ( -- ) set shift-register output to zero(6bit) lockdict create a_clk_out forthentry $C_a_lxasm w, h11C h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WyPW6 l, z1bixZB l, 0 l, 0 l, z1[ixZB l, 0 l, z3[yP[K l, z1SyLI[ l, z1SV01X l, freedict : _latch_out_l _latch pinlo ; : _latch_out_h _latch pinhi ; : _clk_out_l _clk pinlo ; : _clk_out_h _clk pinhi ; 1 _latch lshift constant _latchm 1 _clk lshift constant _clkm \ send hi-pulse to Enable-pin : lcd_enable _latch_out_h _latch_out_l ; \ send data to shift-register \ ( n -- ) n:lcd4bit(bit0-3) + RS(bit4) + E(bit5) : shift_out \ ( n1 n2 n3 -- ) n1:shift-data n2:_latchm n3:_clkm _latchm _clkm a_shift_data ; \ reset shift-register : reset_sr _clkm a_clk_out ; \ lcd_com - send command to HD44780 (n -- ) n:bit8=RS-bit bit7-0=LCD-data : lcd_com invert 1FF and dup 100 and if 10 else 0 then swap 2dup \ upper 4bit 4 rshift F and or 20 or \ Add RS-bit and Enable-bit shift_out lcd_enable reset_sr \ lower 4bit F and or 20 or shift_out lcd_enable reset_sr ; \ 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 reset_sr \ 8bit mode 32 delms \ wait 50msec 3C \ 3 invert 3F and shift_out lcd_enable 5 delms lcd_enable 1 delms lcd_enable 5 delms reset_sr \ reset shift-register 2 lcd_com 28 lcd_com C lcd_com 1 lcd_com 6 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 1 delms 10 0 do dup lcd_char 100 delms 1+ loop loop loop drop lcd_clear 1 delms \ display binary, hex, decimal c" 0x1+0x6 = b" lcd_str 1 6 + 4 lcd_bin 1 2 lcd_pos 1 delms c" 0xACE+0xF=0x" lcd_str ACE F + 4 lcd_hex 5 delsec lcd_clear 1 cur_line W! 1 delms 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 1 delms 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 1 delms 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 cnt COG@ lcd_init \ 10 4 lcd_setup \ 16characters 4line set_bar_graph2 lcd_clear 1 delms 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@ + 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@ + thens loop drop 1 3 lcd_pos cnt COG@ swap - 13880 u/ lcd_dec c" msec" lcd_str ; decimal { fl build_BootOpt :rasm \ get _clkm mov $C_treg1 , $C_stTOS spop \ get _latchm mov $C_treg2 , $C_stTOS spop \ shift data to left shl $C_stTOS , # d26 \ set loop-count mov $C_treg3 , # 7 __1 shl $C_stTOS , # 1 wc \ set latch to Hi/Lo if_c or outa , $C_treg2 \ clock pulse sec or outa , $C_treg1 mov $C_treg4 , cnt add $C_treg4 , # d28 waitcnt $C_treg4 , # 0 \ set _latch to Lo andn outa , $C_treg2 andn outa , $C_treg1 djnz $C_treg3 , # __1 spop jexit ;asm a_shift_data fl build_BootOpt :rasm mov $C_treg1 , # 6 __1 \ pulse width 150nsec or outa , $C_stTOS nop nop andn outa , $C_stTOS nop djnz $C_treg1 , # __1 spop jexit ;asm a_clk_out }