RS485 Master.txt
Warning: if you clip this code into your program, look out for possible html code slipping in.
REM Simple master program for testing RS485 networking with an SBC2000-074.
REM
REM Copyright 1998 Vesta Technology, Inc.
REM All rights reserved.
REM
REM This program will "poll" several slaves, and display the responses on the
REM LCD. Each slave's display will consist of a pair of numbers on the top
REM line of the LCD (the slave's station number and its count of messages),
REM and one number on the second line of the LCD (the master's count of failures
REM communicating to that slave).
REM We will set up for a maximum of 5 slaves, numbered 0-4
CONSTANT max_slaves AS INTEGER = 5
REM This bit will be set when the COM port is idle, and clear when the
REM COM port is busy.
GLOBAL XMTR_EMPTY AS BIT = 0x98,1
REM Set up a subroutine to control the Push-To-Talk signal going to the RS485
REM board. We are using pin 1 of the DIO connector, which is bit 4 of port D.
SUBROUTINE PTT(state AS INTEGER)
STATIC PTT_BIT AS BIT = 8,4
PTT_BIT = state
END
REM When an INPUT statement fails because no response was received in time,
REM we need to detect that fact and clear the error. If we don't, subsequent
REM INPUT statements will fail because of the error, even if they have
REM received input. Note that if you compile with debug, you can replace the
REM address 0x3B with the name IDE_Error_Code.
VITAL SUBROUTINE ErrHandler(errtype AS INTEGER)
IF errtype = 88
POKE(0x3B, 0) : REM Clear error code if it's "timeout"
ENDIF
END
REM We are going to simulate an array in RAM, because the "failures" array
REM could cause excessive writing to the EEPROM if we used a normal array.
REM We will build our simulated array by setting a base address counting
REM backwards from the end of global RAM. Note that we will not get any
REM warnings from the compiler if these addresses are used by other variables.
FUNCTION failures(which AS INTEGER) AS INTEGER
IF IDE_Board() = 2
failures = 126
ELSE
failures = 158
ENDIF
failures = failures - 2 * which
END
REM Declare the variables we need.
GLOBAL slave AS INTEGER
GLOBAL j AS INTEGER
GLOBAL slv_num AS INTEGER, response AS INTEGER
CONSTANT CR AS STRING = "\013"
REM Initialize the failures array
FOR j = 0 TO 4
DPOKE(failures(j), 0)
NEXT j
REM By default, INPUT will wait forever. We don't want this, because that
REM would mean that a missing slave or other problem could cause this
REM application to hang forever. Therefore, we set up a limit on how long
REM INPUT will wait before aborting with an error.
POKE(0x29, 50) : REM Set up timeout of about 1/2 second
REM Now execute the main loop of the application. We will send a slave's
REM ID number, then wait for a response from the slave.
DO WHILE 1
FOR slave = 1 TO max_slaves
PIPE PRINT COMM0
PTT(1) : REM Assert push-to-talk
PRINT slave, CR : REM Address the slave
REM A minor delay to allow the last character to complete
REM before releasing push-to-talk.
DO
REM
LOOP UNTIL XMTR_EMPTY
PTT(0)
INPUT slv_num
INPUT response
REM Check to see if we got a good response from the slave
IF slv_num <> slave
DPOKE(failures(slave), DPEEK(failures(slave))+1)
ENDIF
REM Print information about what's going on.
REM Along the top line of the LCD, print the latest response
REM from each slave.
PIPE PRINT LCD
LCD_Command(0x80+8*(slave-1))
PRINT slv_num, response
LCD_Display(" ")
REM Along the second line of the LCD, print the count of
REM failed responses from each slave.
LCD_Command(0xC0+8*(slave-1))
PRINT DPEEK(failures(slave))
LCD_Display(" ")
REM Delay to allow the slave time to release push-to-talk
FOR j = 0 TO 10
REM
NEXT j
NEXT slave
LOOP