SX/B Example: Serial LCD | Examples Index |
' ========================================================================= ' ' File...... SERIAL_LCD.SXB ' Purpose... Serial LCD Controller with 8 I/O bits ' Author.... (c) Parallax, Inc. -- All Rights Reserved ' E-mail.... support@parallax.com ' Started... ' Updated... 05 JUL 2006 ' ' ========================================================================= ' ------------------------------------------------------------------------- ' Program Description ' ------------------------------------------------------------------------- ' ' Implements a simple serial LCD controller using the SX28. ' ' This controller is designed to be command-compatible with SEETRON 2x16 ' LCD displays, but is fixed at 9600 baud and uses open-true serial mode. ' It also offers extended functions with RC of the SX28 ' ' By sending the instruction prefix ($FE) twice, this LCD controller ' enters "extended" function mode. The following extended functions are ' currently available: ' ' $F0, ddr : Set IO port DDR (1 = input, 0 = output; default is %11111111) ' $F1 : Read IO port ' $F2, bits : Write bits to IO port ' $FF : Read LCD RAM (from current cursor position) ' ------------------------------------------------------------------------- ' Device Settings ' ------------------------------------------------------------------------- DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX FREQ 4_000_000 ID "SLCD" ' ------------------------------------------------------------------------- ' IO Pins ' ------------------------------------------------------------------------- Sio VAR RA.0 ' pull-up via 4.7K LcdE VAR RA.1 ' pull-down via 4.7K LcdRW VAR RA.2 LcdRS VAR RA.3 TRIS_Ctrl VAR TRIS_A LcdBus VAR RB ' RB.0 --> DB0, ... TRIS_Lcd VAR TRIS_B IoPort VAR RC TRIS_IO VAR TRIS_C ' ------------------------------------------------------------------------- ' Constants ' ------------------------------------------------------------------------- Baud CON "OT9600" ' open for single wire Cmd CON $FE ' LCD command prefix ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- serByte VAR Byte ' serial IO byte tmpB1 VAR Byte ' work vars tmpB2 VAR Byte tmpW1 VAR Word ' ========================================================================= PROGRAM Start ' ========================================================================= ' ------------------------------------------------------------------------- ' Subroutine Declarations ' ------------------------------------------------------------------------- DELAY SUB 1, 2 ' delay in milliseconds DELAY_US SUB 1, 2 ' delay in microseconds BLIP SUB 0 ' move bus to/from LCD LCDINIT SUB 0 ' initialize LCD LCDCMD SUB 1 ' command byte --> LCD LCDOUT SUB 1 ' byteVar --> LCD LCDIN SUB 0 ' byteVar <-- LCD RX_BYTE SUB 0 ' rx from serial I/O TX_BYTE SUB 1 ' tx to serial I/O ' ------------------------------------------------------------------------- ' Program Code ' ------------------------------------------------------------------------- Start: TRIS_Ctrl = %0001 ' RA.0 = input (serial) LCDINIT Main: serByte = RX_BYTE ' wait for byte IF serByte = Cmd THEN Do_Command ' command? Do_Write: LCDOUT serByte ' no, write char byte GOTO Main Do_Command: serByte = RX_BYTE ' get command byte IF serByte = Cmd THEN Extended_Cmd ' extended command? LCDCMD serByte ' no, write cmd byte GOTO Main Extended_Cmd: serByte = RX_BYTE ' get extended command Set_IO: IF serByte <> $F0 THEN Read_IO ' check command serByte = RX_BYTE ' get port configuration TRIS_IO = serByte ' setup IO port GOTO Main Read_IO: IF serByte <> $F1 THEN Write_IO DELAY 2 ' delay for host setup TX_BYTE IoPort ' send port bits to host GOTO Main Write_IO: IF serByte <> $F2 THEN Read_Byte IoPort = RX_BYTE ' put bits on the port GOTO Main Read_Byte: IF serByte <> $FF THEN Cmd_X serByte = LCDIN ' read LCD (cursor pos) DELAY 2 ' delay for host setup TX_BYTE serByte ' send byte to to host GOTO Main Cmd_X: ' for future expansion ' GOTO Main ' ------------------------------------------------------------------------- ' Subroutine Code ' ------------------------------------------------------------------------- ' Use: DELAY ms ' -- 'ms' is delay in milliseconds, 1 - 65535 DELAY: IF __PARAMCNT = 1 THEN tmpW1 = __PARAM1 ' save byte value ELSE tmpW1 = __WPARAM12 ' save word value ENDIF PAUSE tmpW1 RETURN ' ------------------------------------------------------------------------- ' Use: DELAY us ' -- 'us' is delay in microseconds, 1 - 65535 DELAY_US: IF __PARAMCNT = 1 THEN tmpW1 = __PARAM1 ' save byte value ELSE tmpW1 = __WPARAM12 ' save word value ENDIF PAUSEUS tmpW1 RETURN ' ------------------------------------------------------------------------- ' Use: LCDCMD cmdByte ' -- send 'cmdByte' to LCD with RS line low LCDCMD: ' write command byte LcdRS = 0 GOTO Lcd_Put ' ------------------------------------------------------------------------- ' Use: LCDOUT char ' -- send 'char' to LCD with RS line high LCDOUT: ' write character byte LcdRS = 1 ' ------------------------------------------------------------------------- Lcd_Put: ' byte --> LCD bus LcdBus = __PARAM1 ' ------------------------------------------------------------------------- BLIP: ' move bus into LCD LcdE = 1 DELAY_US 2 LcdE = 0 DELAY_US 40 ' instruction delay RETURN ' ------------------------------------------------------------------------- ' Use: char = LCDIN ' -- puts value at LCD cursor position in 'char' LCDIN: TRIS_Lcd = %11111111 ' make LCD bus inputs LcdRS = 1 ' character mode LcdRW = 1 ' read mode LcdE = 1 ' move byte to bus tmpB1 = LcdBus ' grab the byte LcdE = 0 ' complete the read LcdRW = 0 ' return to write mode TRIS_Lcd = %00000000 ' make LCD bus outputs RETURN tmpB1 ' return byte to caller ' ------------------------------------------------------------------------- ' Use: LCDINIT ' -- initialize LCD for 8-bit, 2-line interface LCDINIT: DELAY 15 ' power-up delay, 15 ms TRIS_Lcd = %00000000 ' all outputs LcdBus = %00110000 ' 8-bit interface BLIP DELAY 5 ' delay 4.5 ms (min) BLIP DELAY_US 100 BLIP LCDCMD %00111000 ' multi-line, 5x7 font LCDCMD %00001100 ' display on, no cursor LCDCMD %00000110 ' auto-increment cursor LCDCMD %00000001 ' clear and home LCD RETURN ' ------------------------------------------------------------------------- ' Use: char = RX_BYTE ' -- reads byte from serial input and places in 'char' RX_BYTE: SERIN Sio, Baud, tmpB1 ' receive a byte RETURN tmpB1 ' return to caller ' ------------------------------------------------------------------------- ' Use: TX_BYTE char ' -- transmits 'char' over serial connnection TX_BYTE: tmpB1 = __PARAM1 ' save byte to send SEROUT Sio, Baud, tmpB1 ' send the byte RETURN
The following program demonstrates the features of this serial LCD using a BASIC Stamp 2 microcontroller.
' ========================================================================= ' ' File...... SERIAL_LCD_TEST.BS2 ' Purpose... Test the SX/B Serial LCD controller ' Author.... (c) Parallax, Inc. -- All Rights Reserved ' E-mail.... support@parallax.com ' Started... ' Updated... 05 JUL 2006 ' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' ' This program demostrates the SX/B serial LCD controller code. The SX/B ' LCD controller is code-compatible with SEETRON LCD displays, but adds ' extended features. ' ' To access extended features, the intruction commnad (254) is sent twice, ' then followed with the extended command and possible data byte. ' ' Extended commands: ' ' <$FE><$FE><$F0> - Set SX/B IO port DDR (1 = input, 0 = output) ' <$FE><$FE><$F1> - Read SX/B IO port ' <$FE><$FE><$F2><bits> - Write bits to SX/B IO port ' <$FE><$FE><$FF> - Read LCD RAM (current cursor position) ' -----[ Revision History ]------------------------------------------------ ' -----[ I/O Definitions ]------------------------------------------------- Sio PIN 15 ' -----[ Constants ]------------------------------------------------------- #SELECT $STAMP #CASE BS2, BS2E, BS2PE T1200 CON 813 T2400 CON 396 T4800 CON 188 T9600 CON 84 T19K2 CON 32 TMidi CON 12 T38K4 CON 6 #CASE BS2SX, BS2P T1200 CON 2063 T2400 CON 1021 T4800 CON 500 T9600 CON 240 T19K2 CON 110 TMidi CON 60 T38K4 CON 45 #CASE BS2PX T1200 CON 3313 T2400 CON 1646 T4800 CON 813 T9600 CON 396 T19K2 CON 188 TMidi CON 108 T38K4 CON 84 #ENDSELECT Inverted CON $4000 Open CON $8000 Baud CON Open | T9600 LcdCls CON $01 ' clear the LCD LcdHome CON $02 ' move cursor home LcdCrsrL CON $10 ' move cursor left LcdCrsrR CON $14 ' move cursor right LcdDispL CON $18 ' shift chars left LcdDispR CON $1C ' shift chars right LcdDDRam CON $80 ' Display Data RAM control LcdCGRam CON $40 ' Character Generator RAM LcdLine1 CON $80 ' DDRAM address of line 1 LcdLine2 CON $C0 ' DDRAM address of line 2 LcdSetIO CON $F0 ' set LCD IO port DDR LcdRdIO CON $F1 ' read from LCD IO port LcdWrIO CON $F2 ' write to LCD IO port LcdI CON $FE ' instruction LcdRdRAM CON $FF ' read from cursor pos ' -----[ Variables ]------------------------------------------------------- eePntr VAR Word char VAR Byte col VAR Byte idx VAR Nib ioPort VAR Byte ' -----[ EEPROM Data ]----------------------------------------------------- CC0 DATA $0E,$1F,$1C,$18,$1C,$1F,$0E,$00 CC1 DATA $0E,$1F,$1F,$18,$1F,$1F,$0E,$00 CC2 DATA $0E,$1F,$1F,$1F,$1F,$1F,$0E,$00 ' -----[ Initialization ]-------------------------------------------------- Reset: PAUSE 500 ' let LCD get ready SEROUT Sio, Baud, [LcdI, LcdCls] PAUSE 2 DL_Chars: ' download custom chars SEROUT Sio, Baud, [LcdI, LcdCGRam] FOR eePntr = CC0 TO (CC2 + 7) READ eePntr, char SEROUT Sio, Baud, [char] NEXT SEROUT Sio, Baud, [LcdI, LcdDDRam] ' -----[ Program Code ]---------------------------------------------------- Main: DEBUG CLS, "SX/B Serial LCD Demo" SEROUT Sio, Baud, [LcdI, LcdCls] PAUSE 500 Write_To_LCD: DEBUG CRSRXY, 0, 2, "Writing to LCD" SEROUT Sio, Baud, 10, ["SERIAL LCD"] SEROUT Sio, Baud, 10, [LcdI, LcdLine2 + 7, "WITH SX/B"] PAUSE 1000 Read_From_LCD: DEBUG CRSRXY, 0, 4, "Reading LCD L1: [" SEROUT Sio, Baud, [LcdI, LcdHome] PAUSE 2 FOR col = 0 TO 15 SEROUT Sio, Baud, [LcdI, LcdI, LcdRdRAM] SERIN Sio, Baud, [char] DEBUG char NEXT DEBUG "]", CRSRXY, 0, 5, "Reading LCD L2: [" SEROUT Sio, Baud, [LcdI, LcdLine2] PAUSE 2 FOR col = 0 TO 15 SEROUT Sio, Baud, [LcdI, LcdI, LcdRdRAM] SERIN Sio, Baud, [char] DEBUG char NEXT DEBUG "]" PAUSE 1000 Animation: DEBUG CRSRXY, 0, 7, "Custom character demo" FOR col = LcdLine2 TO (LcdLine2 + 15) FOR idx = 0 TO 5 SEROUT Sio, Baud, [LcdI, col] LOOKUP idx, [0, 1, 2, 1, 0, " "], char SEROUT Sio, Baud, [char] PAUSE 50 NEXT NEXT IO_Port_Test: DEBUG CRSRXY, 0, 9, "IO Port Test" SEROUT Sio, Baud, [LcdI, LcdI, LcdSetIO, %10000000] DEBUG CRSRXY, 0, 10, " - port.7 = " SEROUT Sio, Baud, [LcdI, LcdI, LcdRdIO] SERIN Sio, Baud, [char] DEBUG BIN1 char.BIT7, CRSRXY, 0, 11, " - Writing to port " FOR idx = 0 TO 6 char = %00000001 << idx SEROUT Sio, Baud, [LcdI, LcdI, LcdWrIO, char] SEROUT Sio, Baud, [LcdI, LcdLine2] SEROUT Sio, Baud, ["PORT: ", BIN8 char] PAUSE 250 NEXT FOR idx = 5 TO 0 char = %00000001 << idx SEROUT Sio, Baud, [LcdI, LcdI, LcdWrIO, char] SEROUT Sio, Baud, [LcdI, LcdLine2] SEROUT Sio, Baud, ["PORT: ", BIN8 char] PAUSE 250 NEXT GOTO Main