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.
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.
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.
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.
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