Selectrix

Interface schema met de Sx bus

Met de hier beschreven interface kunnen de hardware signalen van de Sx bus (SELECTRIX, rechts) direct in een computer ingelezen worden. Dit kan met iedere poort, waarop 3 ingangen en 2 uitgangen zitten. De bij de software beschreven routines halen 1 byte van de Sx-bus.

Hardware:

Schema:

Links op het schema is de verbinding naar de computer. De bovenste 2 lijnen zijn voor het aansturen van de DATA lijn van de Sx-bus. Met de onderste 3 lijnen kan de data gelezen worden van de DATA, T0 en T1 lijn. Na spanning conversie worden de signalen naar de Sx-bus gestuurd (rechts). Op de Sx-bus is tevens een voeding aanwezig. Deze wordt voor gebruik gestabiliseerd op een veilige (voor de computer) 5 volts spanning. Op deze wijze kan buiten een standaard converter om de Sx-bus worden aangestuurd.

Conversie naar DATA:

De lijn DATA wordt aangestuurd door alle aangesloten SELECTRIX apparaten. Om nu goede communicatie te hebben is het noodzakelijk dat alleen het geadresseerde apparaat data op de bus zet. Door beide lijnen DATA-0 en DATA-1 met 5 volt (logische "1") aan te sturen, zal de DATA lijn niet door deze interface beïnvloed worden.

Door DATA-0 = 0 volt (logische "0") te maken, wordt de DATA lijn via de weerstand R2 naar GND getrokken. Dit zal door de SELECTRIX apparatuur gelezen worden als een "0".

Door DATA-1 = 0 volt (logische "0") te maken, wordt de DATA lijn via de weerstand R1 en Q1 naar +5V getrokken. Dit zal door de SELECTRIX apparatuur gelezen worden als een "1".

Ten behoeve van metingen is via OPAMP U1B de DATA lijn gebufferd beschikbaar. Tevens kan hier in een vroegtijdig stadium vastgesteld worden of een van de randapparaten de spanning op de rails wil afschakelen (Dit gebeurt normaal via de T1 lijn.)

Conversie T0 en T1 naar LINE-T0 en LINE-T1:

Op T0 en T1 staan signalen die of 0 volt of +5 volt zijn. Volgens de specificaties zijn alle spaningen onder de 2,5 V gelijk aan een logische "0" en alle spanningen boven de 2,5 V gelijk aan een logische "1".

Om de lijnen niet te overmatig te belasten zijn OPAMPS toegepast voor de koppeling en de conversie ipv. Schmidt-triggers.

De golfvormen op deze lijn zijn als volgt:

 Kloksignaal op de T0 lijn.

Datasignaal op de T1 lijn.

Software:

Algemeen:

De software is geschreven voor een 80C31 met een kristal frequentie van 12 MHz. De code is zo geschreven dat alleen het lezen/schrijven van/naar de Sx-bus gebeurt. Alle andere processen moeten wachten tot het byte van de Sx-bus komt. Hierna is circa 70 msec. beschikbaar voor het volgende byte arriveert. De IO-pennen zijn vrij te kiezen (Let op bij gebruik van de P0 pennen).

Het gebruik is eenvoudig. Met de routine Send_Loc wordt data op de DATA lijn geplaatst. Deze wordt hierna door de Central Control 2000 op de rails geplaatst. Met de routine Recv_Loc wordt data van de T1 lijn gehaald. Deze data is een kopie van hetgeen er op de rails staat. De hulproutine Data_tri moet voor een correcte werking zo snel mogelijk na een hardwarereset uitgevoerd worden. Dit is om te voorkomen dat de DATA lijn geblokkeerd wordt door ons apparaat.

Variabelen:

Gebruiker:

Programma:

Een adres voor het te versturen/ontvangen byte ontstaat uit de volgende formule:
adres = (6 - LocTelOff) * 16 + (15 - LocTelnr.)

; 
; Send data to the Sx bus 
;
; In:   Variabelen LocTelnr, LocTelOff en Loc_Data geinitialiseerd
; Out:  None
; Used: A, PSW, Telegram_Nr en Tel_Offset
; 
Send_Loc:  acall Line_Sync
           mov   a, Telegram_Nr
           cjne  a, Loc_Telnr, Send_Loc
           mov   Tel_Offset, #7
Send_Next: mov   a, Tel_Offset
           dec   a
           cjne  a, Loc_TelOff, Send_Skip
           mov   c, Loc_Data.0             ; Start writing data
           acall Write_D                   ; Speed (0-4)
           mov   c, Loc_Data.1
           acall Write_D
           acall Read_Tren
           mov   c, Loc_Data.2
           acall Write_D
           mov   c, Loc_Data.3
           acall Write_D
           acall Read_Tren
           mov   c, Loc_Data.4
           acall Write_D
           mov   c, Loc_Data.5             ; Direction
           acall Write_D
           acall Read_Tren
           mov   c, Loc_Data.6             ; Light
           acall Write_D
           mov   c, Loc_Data.7             ; Function
           acall Write_D
           acall Read_Tren
           ret
Send_Skip: acall SKIP_BYTE
           djnz  Tel_Offset, Send_Next
           ret
;
; Receive data from the Sx bus
;
; In:   Variabele adres geinitialiseerd
; Out:  A (data read)
; Used: A, PSW, Telegram_Nr en Tel_Offset
;
Recv_Loc:  acall Line_Sync
           mov   a, Telegram_Nr
           cjne  a, Loc_Telnr, Recv_Loc
           mov   Tel_Offset, #7
Recv_Next: mov   a, Tel_Offset
           dec   a
           cjne  a, Loc_TelOff, Recv_Skip
           clr   a                            ; Start reading byte from T1
           acall Read_T1
           mov   acc.0, c                     ; Speed (0-4)
           acall Read_T1
           mov   acc.1, c
           acall Read_Tren
           acall Read_T1
           mov   acc.2, c
           acall Read_T1
           mov   acc.3, c
           acall Read_Tren
           acall Read_T1
           mov   acc.4, c
           acall Read_T1
           mov   acc.5, c                      ; Direction
           acall Read_Tren
           acall Read_T1
           mov   acc.6, c                      ; Light
           acall Read_T1
           mov   acc.7, c                      ; Function
           acall Read_Tren
           ret
Recv_Skip: acall SKIP_BYTE
           djnz  Tel_Offset, Recv_Next
           ret
;
; Wait till start of next telegram
;
; In:   None
; Out:  Nummer huidige telegram in Telegram_Nr en A
; Used: A, PSW
;
Line_Sync: acall Read_T1
           jb    line_DATA, Line_Sync
           acall Read_T1
           jb    line_DATA, Line_Sync
           acall Read_T1
           jb    line_DATA, Line_Sync          ; Three times "0" is sync
           acall Read_T1
           acall Read_T1
           acall Read_T1                       ; Determine telegram number
           clr   a
           acall Read_T1
           mov   c, line_DATA
           mov   acc.3, c
           acall Read_T1
           mov   c, line_DATA
           mov   acc.2, c
           acall Read_T1
           acall Read_T1
           mov   c, line_DATA
           mov   acc.1, c
           acall Read_T1
           mov   c, line_DATA
           mov   acc.0, c
           cpl   a
           anl   a, #0fh
           mov   Telegram_Nr, a
           acall Read_T1
           ret
;
; Skip next byte in telegram
;
; In:   None
; Out:  None
; Used: PSW
;
SKIP_BYTE: acall Read_T1
           acall Read_T1
           acall Read_Tren
           acall Read_T1
           acall Read_T1
           acall Read_Tren
           acall Read_T1
           acall Read_T1
           acall Read_Tren
           acall Read_T1
           acall Read_T1
           acall Read_Tren
           ret
;
; Read one bit from T1, sync with T0
;
; In:   None
; Out:  State of T1 ("0" of "1") in carry
; Used: R7, PSW
;
Read_T1:   jb    line_CLK, Read_T1            ; Wait until clock goes low
           mov   r7, #5
           djnz  r7, $- 2                     ; Wait till middle clock
           mov   c, line_T1                   ; Read T1 line in carry
           ret
;
; Read trennungsbit: Every third bit is a "1"
;
; In:   None
; Out:  None
; Used: R7, PSW
;
Read_Tren: jb    line_CLK, Read_Tren
           mov   r7, #0ah
           djnz  r7, $- 2                    ; Wait till clock goes "1"
           ret
;
; Write one bit to D, sync with T0
;
; In:   State of D ("0" of "1") in carry
; Out:  None
; Used: R7, PSW
;
Write_D:   jb    line_CLK, Write_D
           mov   data_0,c
           cpl   c
           mov   data_1,c
           mov   r7, #0fh
           djnz  r7, $- 2                    ; Wait till clock goes "1"
;        fall thru  Data_tri                 ; Line again "tri-state"
;
; Set D line "tri-state"
;
; In:   None
; Out:  None
; Used: None
;
Data_tri:  setb  data_1
           setb  data_0
           ret