''******************************* ''*LCD DISPLAY * ''*Author William Hardie * ''*Started 4-13-11 * ''*Version 1.1 * ''*Revision date 8-22-11 * ''******************************* ''Can be used for 2x16 or 4x20 serial displays ''w or w/o backlight ''Output to display only ''Must supply LCD_Pin ' I/O Pin For LCD '' LCD_Baud ' LCD Baud Rate 2400,9600,or 19200 '' LCD_Lines ' Either 2 or 4 lines '' LCD_Colms ' Either 16 or 20 columns '' LCD_BkLite ' Backlite option 0 false,1 true CON LCD_BKSPC = $08 ' move cursor left LCD_RT = $09 ' move cursor right LCD_LF = $0A ' move cursor down 1 line LCD_CLS = $0C ' L clear LCD (with 5 ms delay) LCD_CR = $0D ' move pos 0 of next line LCD_BL_ON = $11 ' B backlight on LCD_BL_OFF = $12 ' B backlight off LCD_OFF = $15 ' Display off LCD_ON1 = $16 ' LCD on; cursor off, blink off LCD_ON2 = $17 ' LCD on; cursor off, blink on LCD_ON3 = $18 ' LCD on; cursor on, blink off LCD_ON4 = $19 ' LCD on; cursor on, blink on LCD_LINE0 = $80 ' H move to line 0, column 0,Home LCD_LINE1 = $94 ' 1 move to line 1, column 0 LCD_LINE2 = $A8 ' 2 move to line 2, column 0 LCD_LINE3 = $BC ' 3 move to line 3, column 0 ' C put character ' S put string ' N put string without fill ' X go to X (col),Y (line) ' D clear entire line ' W wait time period '' Custom Character definition label #$F8, LCD_CC0, LCD_CC1, LCD_CC2, LCD_CC3 #$FC, LCD_CC4, LCD_CC5, LCD_CC6, LCD_CC7 VAR byte cog byte backlt long BitTime byte dpin byte MaxCol byte MaxLine long time long LCDStack[50] 'lcd working stack byte dbuffer[90] {display buffer large enough for 4 lines, 20 columns, + cntrl chars} PUB LCD_Start(pin,baud,lines,colms,bklite) : dsuccess ''Load into separate cog LCD_Stop dsuccess:=(cog:=cognew(LCD_Main(pin,baud,lines,colms,bklite),@LCDStack[0])+1) PUB LCD_Stop if cog 'Stop the cog COGSTOP(cog~ -1) PUB LCD_Main(pin,baud,lines,colms,bklite) zerobuf dpin := pin backlt := bklite MaxCol := colms MaxLine := lines init(pin,baud) putchar(LCD_ON2) repeat 'command & data buffer cntrl case dbuffer[0] 0 : {do nothing} 'wait in loop "B" : processBklt 'put backlite on/off "D" : processClrLn 'put clear line "C" : processChar 'put character "S" : processStr 'put string "N" : processStrNF 'put string w/o fill "W" : processWait 'delay timer "L" : tx(LCD_CLS) 'Clear entire display waitcnt (clkfreq/200 + cnt) 'Delay 5 mS (200Hz) zerobuf "H" : tx(LCD_LINE0) 'home cursor, line 0 zerobuf "1" : tx(LCD_LINE1) 'line 1, col 0 zerobuf "2" : tx(LCD_LINE2) 'line 2, col 0 zerobuf "3" : tx(LCD_LINE3) 'line 3, col 0 zerobuf "X" : tx(dbuffer[1]) 'move cursor to xy zerobuf "T" : tx(dbuffer[1]) 'send a character zerobuf other: errorstr(@CodeError) 'no match zerobuf quit LCD_Stop 'stop cog PUB init(pin,baud) 'initialize display outa[pin]~ dira[pin]~~ outa[pin] := 1 BitTime := clkfreq/baud 'Set bit speed for serial output waitcnt(clkfreq/10 + cnt) 'Wait 100ms (10 Hz) tx(LCD_CLS) 'Clear entire display waitcnt (clkfreq/200 + cnt) 'Delay 5 mS (200Hz) tx(LCD_LINE0) 'Home display tx(LCD_BL_OFF) 'Turn backlight off PUB zerobuf 'load buffer with 0 dbuffer[0] := 0 PUB ck4zero 'Wait for buffer available repeat while dbuffer[0] <> 0 PUB cls 'clear screen ck4zero dbuffer[0] := "L" PUB home 'home to line 0,col 0 ck4zero dbuffer[0] := "H" waittime(500) PUB stl1 'cursor to line 1,col 0 ck4zero dbuffer[0] := "1" PUB stl2 'cursor to line 2,col 0 ck4zero dbuffer[0] := "2" PUB stl3 'cursor to line 3,col 0 ck4zero dbuffer[0] := "3" PUB putbklt(bklt) 'load backlight value ck4zero dbuffer[1] := bklt dbuffer[0] := "B" PUB putchar(txByte) 'send a character ck4zero dbuffer[1] := txByte 'Write the character dbuffer[0] := "C" PUB putstr(straddr) | idx 'Send a string ck4zero idx := 1 repeat strsize(straddr) 'For each char in string dbuffer[idx++] := byte[straddr++] 'Write the character dbuffer[idx] := 0 'Add zero terminating char dbuffer[0] := "S" PUB putstrNF(straddr) | idx 'Send a string without fill ck4zero idx := 1 repeat strsize(straddr) 'For each char in string dbuffer[idx++] := byte[straddr++] 'Write the character dbuffer[idx] := 0 'Add zero terminating char dbuffer[0] := "N" PUB gotoxy(Col, Line) 'Move cursor to col/line ck4zero dbuffer[1] := LinePos[Line] + Col 'Load target position dbuffer[0] := "X" PUB clrln(line) ck4zero dbuffer[1] := line dbuffer[0] := "D" PUB txchar(chr) ck4zero dbuffer[1] := chr dbuffer[0] := "T" PUB waittime(dtime) ck4zero time := dtime dbuffer[0] := "W" PRI processBklt 'if backlight option if backlt == 1 if dbuffer[1] == 0 'is backlight on or off tx(LCD_BL_OFF) else tx(LCD_BL_ON) else errorstr(@Nobklt) 'if not backlight errorstr(@Blank) 'send error message waittime(1000) zerobuf PRI processChar tx(dbuffer[1]) 'Write the character zerobuf PRI processStr | addr,lendelta,lenstr addr := @dbuffer[1] lenstr := strsize(addr) if lenstr > MaxCol errorstr(@toolong) else repeat strsize(addr) 'For each char in string tx(byte[addr++]) 'Write the character if lenstr < MaxCol 'subtract post incr lendelta := MaxCol - lenstr repeat (lendelta) tx(32) zerobuf PRI processStrNF | addr addr := @dbuffer[1] repeat strsize(addr) 'For each char in string tx(byte[addr++]) 'Write the character zerobuf PRI processClrLn | lin 'line is 0 to 3 lin := dbuffer[1] if lin < MaxLine tx(LinePos[lin]) repeat (MaxCol) tx(32) 'decimal 32, hex 20, blank tx(LinePos[lin]) 'goto start of line else errorstr(@RangeError) zerobuf PRI errorstr(straddr)| lendelta,lenstr 'send error string lenstr := strsize(straddr) if lenstr > MaxCol putchar("Z") else repeat strsize(straddr) tx(byte[straddr++]) if lenstr < MaxCol 'subtract post incr lendelta := MaxCol - lenstr repeat (lendelta) tx(32) PUB processWait | cntfreq 'time in mS if time => 1000 '1000,2000,..9000 cntfreq := clkfreq * (time/1000) else cntfreq := clkfreq / (1000/time) 'evenly divisible into 1000 waitcnt(cntfreq + cnt) zerobuf PUB tx(txByte)| t 'Transmit a Byte dira[dpin]~~ 'Pin is an output txByte := ((txByte | $100) << 2) t := cnt 'Sync repeat 10 'Start,8 data,& stop, waitcnt (t += BitTime) 'Wait for bit outa[dpin] := (txByte >>= 1) & 1 'Output bit DAT LinePos byte LCD_LINE0, LCD_LINE1, LCD_LINE2, LCD_LINE3 Blank byte " ",0 CodeError byte "Code not active",0 RangeError byte "Out of range",0 Nobklt byte "No BkLite option",0 toolong byte "String too long",0 {{ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├─────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this │ │software and associated documentation files (the "Software"), to deal in the Software│ │without restriction, including without limitation the rights to use, copy, modify, │ │merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ │permit persons to whom the Software is furnished to do so, subject to the following │ │conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies│ │or substantial portions of the Software. │ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ │INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ │PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ │HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF │ │CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE│ │OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └─────────────────────────────────────────────────────────────────────────────────────┘ }}