' ========================================================================= ' ' File....... Stamp-to-PC.BS2 ' Purpose.... Serial Comm with PC using Flow Control ' Author..... Jon Williams -- Parallax, Inc. ' E-mail..... jwilliams@parallax.com ' Started.... 01 AUG 2002 ' Updated.... 30 JAN 2006 ' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' ' This program (and its companion VB program) demonstrate serial communi- ' cations with a PC using a MAX232 level shifter and flow control. ' ' Using flow control allows the Stamp to complete a task without missing ' data from the PC. ' ' Note: If you have two serial connections on your computer, you can use ' DEBUG to view the Stamp side of the communications process ' -----[ Revision History ]------------------------------------------------ ' 30 JAN 2006 - Updated to PBASIC 2.5 ' -----[ Conditional Definitions ]----------------------------------------- #DEFINE __DebugMode = 0 ' 1 = DEBUG on ' -----[ I/O Definitions ]------------------------------------------------- RX PIN 0 ' receive (from PC) TX PIN 1 ' transmit (to PC) RTS PIN 2 ' Request To Send (from PC) CTS PIN 3 ' Clear To Send (to PC) LEDs VAR OUTD ' task indicator ' -----[ 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 SevenBit CON $2000 Inverted CON $4000 Open CON $8000 Baud CON T9600 RxNum CON $C0 ' rx number from PC TxNum CON $C1 ' tx number to PC RxStr CON $C2 ' rx string from PC TxStr CON $C3 ' tx string to PC NumTasks CON 4 IsOff CON %1111 ' all LEDs off LedDelay CON 250 ' -----[ Variables ]------------------------------------------------------- task VAR Nib ' current Stamp task cmd VAR Byte ' command from PC aNumber VAR Word ' numeric value from PC idx VAR Byte ' EEPROM address pointer dByte VAR Byte ' data byte from PC ' -----[ EEPROM Data ]----------------------------------------------------- MsgLen DATA 21 Msg DATA "Nuts & Volts Magazine", 0 ' -----[ Initialization ]-------------------------------------------------- Reset: LEDs = IsOff ' all LEDs off DIRD = %1111 ' make port D outputs HIGH CTS ' not ready to receive yet ' -----[ Program Code ]---------------------------------------------------- Main: SERIN RX\CTS, Baud, 5, Do_Task, [cmd] #IF __DebugMode #THEN DEBUG "Cmd = ", HEX2 cmd, CR #ENDIF LOOKDOWN cmd, [RxNum, TxNum, RxStr, TxStr], cmd ON cmd GOSUB RX_Number, TX_Number, RX_String, TX_String Do_Task: ON task GOTO Task_0, Task_1, Task_2, Task_3 task = 0 ' fix bad task spec GOTO Main Task_0: LEDs = %1110 ' show current task PAUSE LedDelay ' take some time doing it LEDs = IsOff task = task + 1 // NumTasks ' point to next task GOTO Main Task_1: LEDs = %1101 PAUSE LedDelay LEDs = IsOff task = task + 1 // NumTasks GOTO Main Task_2: LEDs = %1011 PAUSE LedDelay LEDs = IsOff task = task + 1 // NumTasks GOTO Main Task_3: LEDs = %0111 PAUSE LedDelay LEDs = IsOff task = task + 1 // NumTasks GOTO Main ' -----[ Subroutines ]----------------------------------------------------- RX_Number: SERIN RX\CTS, Baud, [aNumber.LOWBYTE, aNumber.HIGHBYTE] #IF __DebugMode #THEN DEBUG "Number in = ", DEC aNumber, CR #ENDIF RETURN ' ------------------------------------------------------------------------- TX_Number: #IF __DebugMode #THEN DEBUG "Sending: ", DEC aNumber, CR #ENDIF SEROUT TX\RTS, Baud, [aNumber.LOWBYTE, aNumber.HIGHBYTE] RETURN ' ------------------------------------------------------------------------- RX_String: idx = 0 ' reset pointer DO SERIN RX\CTS, Baud, [dByte] ' receive char from PC WRITE (Msg + idx), dByte ' save it to EEPROM IF (dByte = 0) THEN EXIT ' if 0, string is complete idx = idx + 1 ' update pointer LOOP WRITE MsgLen, idx ' save string length RETURN ' ------------------------------------------------------------------------- TX_String: READ MsgLen, idx ' get string length SEROUT TX\RTS, Baud, [idx] ' send string length SERIN RX\CTS, Baud, 100, TX_Str_Exit, [cmd] ' wait for restart IF (cmd = TxStr) THEN ' send string if instructed idx = Msg DO READ idx, dByte ' get char from EEPROM IF (dByte = 0) THEN EXIT ' check for end SEROUT TX\RTS, Baud, [dByte] ' send char idx = idx + 1 ' point to next LOOP ENDIF TX_Str_Exit: RETURN