fl { 1-wire Driver for an HD44780 based LCD Character based display Using shiftregister(74HC595) LCD-cotrol use 8bit-mode. PropForth 5.0 06/05/2012 11:50:34 1-wire LCD curcuit Propeller clk P1 0x0 LCD backlight P3 0x1 This 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 _clk \ Comment out when not using brightness-control 1 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 \ s_serial_out \ (n1 n2 -- ) n1:data(8bit)+RS+E n2:_clk bitmask lockdict create a_serial_out forthentry $C_a_lxasm w, h141 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WiPZB l, z1SyLI[ l, z2WyPr2 l, z2WiPeB l, zfyPbM l, z2WyPjA l, zgyPb1 l, z1Sv\KY l, z1Sm]Se l, z3[yPnP l, z1Sya[n l, z1WyPVy l, z3[yPvM l, z1SyLI[ l, z1SV01X l, z1[ixZC l, z2WiQFk l, z20yQ91 l, z3ryQ80 l, z1bixZC l, z2WiQFk l, z20iQCw l, z3ryQ80 l, z1SV000 l, z1[ixZC l, z2WiQFk l, z20iQCw l, z3ryQ80 l, z1bixZC l, z2WiQFk l, z20iQCx l, z3ryQ80 l, z1SV000 l, z1[ixZC l, z2WiQFk l, z20iQCy l, z3ryQ80 l, z1bixZC l, z2WiQFk l, z20iQD0 l, z3ryQ80 l, z1SV000 l, zIj l, z\W l, z3t0 l, z5q0 l, freedict 1 _clk lshift constant _clkm : _clk_out_h _clk pinhi ; \ lcd_com - send command to HD44780 (n -- ) : lcd_com invert 1FF and 200 or \ invert data _clkm a_serial_out \ write data to LCD ; \ setup propeller pins and initialize HD44780 : lcd_init \ set from P**(_data) to P**(_clk) to output _clk pinout _clk_out_h \ 8bit mode 32 delms \ wait 50msec 30 lcd_com 5 delms 30 lcd_com 1 delms 30 lcd_com 5 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 cnt COG@ 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@ + thens loop drop 1 3 lcd_pos cnt COG@ swap - 13880 u/ lcd_dec c" msec" lcd_str ; : test begin AA _clkm a_serial_out fkey? swap drop until ; decimal { (n1 n2 -- ) n1:data(8bit)+RS+E) n2:_clk bitmask fl build_BootOpt :rasm mov $C_treg1 , $C_stTOS spop \ output data to shiftregister for 2 time \ 1st:data(8bit) + RS + E(1) \ 2nd:data(8bit) + RS + E(0) mov $C_treg4 , # 2 __1 mov $C_treg2 , $C_stTOS shl $C_treg2 , # d22 mov $C_treg3 , # d10 \ send 10bit-serialdata to shiftregister __2 shl $C_treg2 , # 1 wc if_c jmpret __bit1ret , # __bit1 if_nc jmpret __bit0ret , # __bit0 djnz $C_treg3 , # __2 \ write data to LCD jmpret __latchret , # __latch and $C_stTOS , # h1FF djnz $C_treg4 , # __1 spop jexit __bit1 andn outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , # d65 waitcnt $C_treg6 , # 0 or outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , __15usec waitcnt $C_treg6 , # 0 __bit1ret ret __bit0 andn outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , __15usec waitcnt $C_treg6 , # 0 or outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , __30usec waitcnt $C_treg6 , # 0 __bit0ret ret __latch andn outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , __200usec waitcnt $C_treg6 , # 0 or outa , $C_treg1 mov $C_treg6 , cnt add $C_treg6 , __300usec waitcnt $C_treg6 , # 0 __latchret ret __15usec d1200 __30usec d2400 __200usec d16000 __300usec d24000 ;asm a_serial_out }