0 0 0 1 S 1 A3 A2 1 A1 A0 1 synchronisatie 'byte' D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 7 data 'bytes' D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 ieder 'byte' is de inhoud D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 van een adres D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1
0 0 0 1 S 1 A3 A2 1 A1 A0 1
Verdeling adressen over de verschillende telegrammen: telegram '0' : 111, 95, 79, 63, 47, 31, 15
struct trains { signed char speed; unsigned char headLight; unsigned char functions; unsigned char decoderType;};
Je bent aardig op weg
Vraagje over je structuur: Waarom HeadLights apart?
#define SX_BIT 800 // 50us#define SX_PAUSE 160 // 10usenum states { SXbitBusy, SXpause,};unsigned char transmittBuffer[8]; unsigned char *ptr;unsigned char packetSentFlag = false;ISR(TIMER1_COMPB_vect) { static unsigned char bitMask = 0x80; // of byte static unsigned char state = SXpause; switch(state) { case SXbitBusy: // bit is actief hier state = SXpause; OCR1A = SX_BIT; PORTD |= 0b00100000; // set enable pin on, ends pause if(*ptr & bitMask) PORTD ^= 0b11000000; // toggle direction if the bit is 1 if(bitMask == 0x01 && ptr == (&transmittBuffer[0] + 7)) { // als alle 8 bytes uitgelokt zijn.. ( ptr = &transmittBuffer[0]; // reset deze pointer bitMask = 0x80; // reset bit mask bitClear(TIMSK1,OCIE1B); // set interrupt uit (volgende pakket moet worden samengesteld) packetSentFlag = true; // sein je hoofd programma dat pakket is uitgeklokt } else { bitMask >>= 1; // = 0b10000000 Deze shift naar rechts if(!bitMask) { // als bit mask 0 is.. bitMask = 0x80; // maak er weer 0b10000000 van ptr++; // hoog de pointer op voor de volgende byte in het array } } break; case SXpause: state = SXbitBusy; OCR1A = SXpause: PORTD &= ~0b00100000; // set enable pin off, starts pause break; }}void initISR() { // initialize the timer cli(); bitSet(TCCR1A,WGM10); bitSet(TCCR1A,WGM11); bitSet(TCCR1B,WGM12); bitSet(TCCR1B,WGM13); bitSet(TCCR1A,COM1B1); bitSet(TCCR1A,COM1B0); bitClear(TCCR1B,CS12); // set prescale on 1 bitClear(TCCR1B,CS11); bitSet(TCCR1B,CS10); OCR1A= 100; // interval tijd begint 1 malig op 100 * 16us omdat.. zomaar cli();}
bitSet(TIMSK1,OCIE1B);
bitClear(TIMSK1,OCIE1B);
/* SX1 centrale Creator: Gerard van der Sel Version: 1.1 Date: 27-12-2015 This software emulates a SX interface on the Arduino. Extra hardware needed is de SX-Arduino board which contains the hardware to communicate with the SX-bus. Protocol used by the SX-Interface (66824 or 66842) 2 byte message: First byte contains command and address: Command is located in bit 7 of first byte: 0: Read address 1: Write address Address: 0 to 111 (valid adresses on the SX-bus) 126 bus selection 127 controls track power Second byte contains data in case of a write command in case of a valid address: 0 to 255 in case of address 126: 0 => select SX0 (track) 1 => select SX1 in case of address 127: 0 trackpower off 128 trackpower on in case of a read: byte is discarded*/#include <Arduino.h>#include "SXcentrale.h"SXcentrale SXcntrl; // Interface to the SX-bus and trackboolean cmdAdr; // Received byte is a commandboolean cmdWrite; // Write commanduint8_t address; // Address for reading or writinguint8_t rcvdData;uint8_t selbus; // Selected busISR(TIMER1_OVF_vect) { // interrupt service routine SXcntrl.isr();} void setup() { // put your setup code here, to run once: // initialize serial: Serial.begin(19200); // initialize SX-bus SXcntrl.init(); // initialize application cmdAdr = true; cmdWrite = false; selbus = 0;}void serialEvent() { // Read all the data while (Serial.available()) { rcvdData = (uint8_t)Serial.read(); // First byte is a command, decode it if (cmdAdr) { // If byte value > 127 a write command, data in second byte if (rcvdData > 127) { cmdWrite = true; address = rcvdData - 128; // address is received data - 128 } else { // Read command, perform it if (rcvdData < 112) { // Get address data Serial.print((char)SXcntrl.get(selbus, rcvdData)); } else { // Illegal address, power or select bus? if (rcvdData == 126) { Serial.print((char)selbus); } if (rcvdData == 127) { Serial.print((char)(SXcntrl.getPWR() * 128)); } } } cmdAdr = false; } else { // Second byte data if (cmdWrite) { if (address < 112) { SXcntrl.set(selbus, address, rcvdData); } else { if (address == 126) { if (rcvdData < 4) { selbus = rcvdData; } } if (address == 127) { if ((rcvdData & 128) == 0) { SXcntrl.setPWR(0); } else { SXcntrl.setPWR(1); } } } cmdWrite = false; } cmdAdr = true; } }}void loop() { // put your main code here, to run repeatedly:}
/* * SXmaster.cpp * * Version: 0.1 * Copyright: Gerard van der Sel * * Changed on: * Version: * Changes: * * * interface hardware needed ! Interface SX-bus - SX T0 (Clock) must be connected to Pin 3 (IOL, INT1); - SX T1 must be connected to Pin 5 (IOL, T1); - SX D must be connected to Pin 6 (IOL, AIN0). SX-bus interface (NEM 682)De clock lijn (T0) is verbonden met een interruptingang, zodat op de flanken van dit signaal een interrupt gegenereerd kan worden. Hierna kan data gelezen worden van T1 of data geschreven worden naar D. Klok: -- ---------------- ---------------- ---------------- ------ | | | | | | | | -- -- -- -- Data: -- ------------------- ------------------- ------------------- --------- X X X X -- ------------------- ------------------- ------------------- --------- ^ ^ ^ ^ ^ ^ ^ ^ W R W R W R W ROpbouw telegram (96 bits): 0 0 0 1 S 1 A3 A2 1 A1 A0 1 synchronisatie 'byte' D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 7 data 'bytes' D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 ieder 'byte' is de inhoud D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 van een adres D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 0 = Logische 0 1 = Logische 1 S = Spanning rails (0 = uit, 1= aan) Ax = Gezamelijk het nummer van het telegram Dx = D0 t/m D7 vormen de data op een Selectrix adres. Verdeling adressen over de verschillende telegrammen: telegram '0' : 111, 95, 79, 63, 47, 31, 15 telegram '1' : 110, 94, 78, 62, 46, 30, 14 telegram '2' : 109, 93, 77, 61, 45, 29, 13 telegram '3' : 108, 92, 76, 60, 44, 28, 12 telegram '4' : 107, 91, 75, 59, 43, 27, 11 telegram '5' : 106, 90, 74, 58, 42, 26, 10 telegram '6' : 105, 89, 73, 57, 41, 25, 9 telegram '7' : 104, 88, 72, 56, 40, 24, 8 telegram '8' : 103, 87, 71, 55, 39, 23, 7 telegram '9' : 102, 86, 70, 54, 38, 22, 6 telegram '10' : 101, 85, 69, 53, 37, 21, 5 telegram '11' : 100, 84, 68, 52, 36, 20, 4 telegram '12' : 99, 83, 67, 51, 35, 19, 3 telegram '13' : 98, 82, 66, 50, 34, 18, 2 telegram '14' : 97, 81, 65, 49, 33, 17, 1 telegram '15' : 96, 80, 64, 48, 32, 16, 0This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <Arduino.h> #include "SXcentrale.h"SXcentrale::SXcentrale() { // initialize pins and variables pinMode(SX_T0, OUTPUT); // SX-T0 is an output digitalWrite(SX_T0, HIGH); pinMode(SX0_T1, OUTPUT); // SX0_T1 is also an output digitalWrite(SX0_T1, HIGH); pinMode(SX1_T1, OUTPUT); // SX1_T1 is also an output digitalWrite(SX1_T1, HIGH); pinMode(SX0_D, INPUT_PULLUP); // SX0_D is an input pinMode(SX1_D, INPUT_PULLUP); // SX1_D is also an input}// initialize functionvoid SXcentrale::init() { // initialize timer1 uint8_t oldSREG = SREG; noInterrupts(); // disable all interrupts // Set timer1 to the correct value for our interrupt interval TCCR1A = 0; TCCR1B = (1 << CS10);// TCCR1B = (1 << CS12); // Debug only TCNT1 = Timer1_40; // preload timer with 40usec delay TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt SREG = oldSREG; // restore interrupts // initialize pins and variables pinMode(SX_T0, OUTPUT); // SX-T0 is an output digitalWrite(SX_T0, LOW); pinMode(SX0_T1, OUTPUT); // SX0_T1 is also an output digitalWrite(SX0_T1, LOW); pinMode(SX1_T1, OUTPUT); // SX1_T1 is also an output digitalWrite(SX1_T1, LOW); pinMode(SX0_D, INPUT_PULLUP); // SX0_D is an input pinMode(SX1_D, INPUT_PULLUP); // SX1_D is also an input for (int i = 0; i < SX_ADDRESS_NUMBER; i++) { _sxbusSX0[i] = 0; // reset sxbus data to zero _sxbusSX1[i] = 0; } initVar(); // Start looking for SYNC}void SXcentrale::initVar() { // start always with sending of header _sx_state = SYNC; // First send SYNC pattern _sx_dataFrameCount = SX_DATACOUNT; // Send all dataframes _sx_sepCount = SX_SEPLEN; // Distanse between two separators _sx_byteCount = SX_SYNC0; // Check for SX_SYNC0 bits of "0" _sx_numFrame = 15; // Set frame to max to start with 0. _sx_intstate = 0; // Start with clock pulse _sx_read_sepCount= SX_SEPLEN; // Distanse between two separators _sx_read_byteCount = 0; // bit counting (byte) _sx_bitTrack = 0; // SX bus bits _sx_bitsendSX0 = 1; // Start with a "1" _sx_bitresvSX0 = 1; _sx_bitsendSX1 = 1; _sx_bitresvSX1 = 1; // Powerbit _sx_PWR = 0; // At start no power // Syncbit _sx_sync = 0; // Clear sync-flag}// Local functions// Write signals to the track (PX protocol)void SXcentrale::writeTrack(uint8_t clockbit) { if (_sx_PWR == 0) { // Power off, stop generating signals bitWrite(SX_TRACKE_PORT, SX_TRACKE_PORTPIN, LOW); bitWrite(SX_TRACKG1_PORT, SX_TRACKG1_PORTPIN, LOW); bitWrite(SX_TRACKG2_PORT, SX_TRACKG2_PORTPIN, LOW); } else { // Enable output amplifier, to generate signals on track. bitWrite(SX_TRACKE_PORT, SX_TRACKE_PORTPIN, HIGH); if (clockbit == 0) { // Clockpuls on track bitWrite(SX_TRACKG1_PORT, SX_TRACKG1_PORTPIN, LOW); bitWrite(SX_TRACKG2_PORT, SX_TRACKG2_PORTPIN, LOW); } else { // Calculate value to track _sx_bitTrack ^= _sx_bitsendSX0; // Send to track bitWrite(SX_TRACKG1_PORT, SX_TRACKG1_PORTPIN, _sx_bitTrack); bitWrite(SX_TRACKG2_PORT, SX_TRACKG2_PORTPIN, !_sx_bitTrack); } }}// Write clock line (inverted)void SXcentrale::writeT0(uint8_t val) { bitWrite(SX_T0_PORT, SX_T0_PORTPIN, !val);}// Write transmit line (inverted)void SXcentrale::writeT1() { bitWrite(SX0_T1_PORT, SX0_T1_PORTPIN, !_sx_bitsendSX0); bitWrite(SX1_T1_PORT, SX1_T1_PORTPIN, !_sx_bitsendSX1);}// Read data linevoid SXcentrale::readD() { _sx_bitresvSX0 = (SX0_D_INPORT & _BV(SX0_D_INPORTPIN)) > 0; _sx_bitresvSX1 = (SX1_D_INPORT & _BV(SX1_D_INPORTPIN)) > 0; // _sx_bitresvSX2 = (SX2_D_INPORT & _BV(SX2_D_INPORTPIN)) > 0; // _sx_bitresvSX3 = (SX3_D_INPORT & _BV(SX3_D_INPORTPIN)) > 0;}// Interrupt service routine (AVR OVERFLOW T1)void SXcentrale::isr() { if (_sx_intstate) { // 40 usec fase (clock high) writeTrack(1); writeT0(1); _sx_intstate = false; TCNT1 += Timer1_40; // reload timer // Start processing the bits // First process the bus readings if (_sx_read_byteCount != 0) { // All bits done _sx_read_sepCount--; if (_sx_read_sepCount == 0) { // Read the separator _sx_read_sepCount = SX_SEPLEN; } else { _sx_read_dataSX0 = (_sx_read_dataSX0 >> 1); // Prepare for reading data bitWrite(_sx_read_dataSX0, 7, _sx_bitresvSX0); // Insert the bit _sx_read_dataSX1 = (_sx_read_dataSX1 >> 1); bitWrite(_sx_read_dataSX1, 7, _sx_bitresvSX1); } _sx_read_byteCount--; if (_sx_read_byteCount == 0) { // All bits done // save read _data if (_sxbusSX0[_sx_read_index] < NO_WRITE) { _sxbusSX0[_sx_read_index] = _sx_read_dataSX0; // Save read data in array _sxbusSX0[_sx_read_index] &= 0xff; } if (_sxbusSX1[_sx_read_index] < NO_WRITE) { _sxbusSX1[_sx_read_index] = _sx_read_dataSX1; _sxbusSX1[_sx_read_index] &= 0xff; } _sx_read_index++; // Point to next byte } } // Next calculate new bus data switch (_sx_state) { // Write sync pattern "0001" to start case SYNC: if (_sx_byteCount == 0) { _sx_bitsendSX0 = 1; _sx_bitsendSX1 = 1; _sx_state = PWR; // Setup for POWER bit _sx_sepCount = SX_SEPLEN - 1; // Set _sx_sepCount and continue } else { _sx_bitsendSX0 = 0; _sx_bitsendSX1 = 0; _sx_byteCount--; } break; // Write the power bit plus separator. case PWR: _sx_sepCount--; if (_sx_sepCount == 0) { // The separator _sx_bitsendSX0 = 1; _sx_bitsendSX1 = 1; _sx_state = ADDR; // Setup for next state ADDR _sx_byteCount = SX_BYTELEN / 2; _sx_sepCount = SX_SEPLEN; // Increment frame number _sx_numFrame++; _sx_numFrame &= 0x0f; _sx_write_dataSX0 = _sx_numFrame; if (_sx_numFrame == 0) { _sx_sync = 1; // Signal frame 0 for sync purposes } } else { _sx_bitsendSX0 = _sx_PWR; _sx_bitsendSX1 = _sx_PWR; } break; // Write the address bits. case ADDR: // But first read powerbit(s) if (_sx_byteCount == (SX_BYTELEN / 2)) { if (_sx_PWR == 0) { _sx_PWR = _sx_bitresvSX0 | _sx_bitresvSX1; // | _sx_bitresvSX2 | _sx_bitresvSX3; } else { _sx_PWR = _sx_bitresvSX0 & _sx_bitresvSX1; // & _sx_bitresvSX2 & _sx_bitresvSX3; } } _sx_sepCount--; if (_sx_sepCount == 0) { // Set the separator _sx_bitsendSX0 = 1; _sx_bitsendSX1 = 1; _sx_sepCount = SX_SEPLEN; } else { _sx_bitsendSX0 = bitRead(_sx_write_dataSX0, 3); _sx_bitsendSX1 = _sx_bitsendSX0; _sx_write_dataSX0 = _sx_write_dataSX0 * 2; } _sx_byteCount--; if (_sx_byteCount == 0) { // Addres part is processed // Advance to the next state _sx_state = DATA; // Setup for DATA write _sx_dataFrameCount = SX_DATACOUNT; _sx_byteCount = SX_BYTELEN; _sx_index = _sx_numFrame * 7; // Calculate index _sx_read_index = _sx_index; _sx_write_dataSX0 = _sxbusSX0[_sx_index]; // Get data to write _sxbusSX0[_sx_index] &= 0xff; // Report written _sx_write_dataSX1 = _sxbusSX1[_sx_index]; _sxbusSX1[_sx_index] &= 0xff; } break; // Write the data bits case DATA: // Start reading databits if (_sx_byteCount == SX_BYTELEN - 1) { _sx_read_byteCount = SX_BYTELEN; // Start reading } _sx_sepCount--; if (_sx_sepCount == 0) { // Set the separator _sx_bitsendSX0 = 1; _sx_bitsendSX1 = 1; _sx_sepCount = SX_SEPLEN; } else { _sx_bitsendSX0 = bitRead(_sx_write_dataSX0, 0); _sx_write_dataSX0 = _sx_write_dataSX0 >> 1; _sx_bitsendSX1 = bitRead(_sx_write_dataSX1, 0); _sx_write_dataSX1 = _sx_write_dataSX1 >> 1; } _sx_byteCount--; if (_sx_byteCount == 0) { // All bits done // Setup for next read/write _sx_byteCount = SX_BYTELEN; _sx_index++; _sx_write_dataSX0 = _sxbusSX0[_sx_index]; // Get data to write _sxbusSX0[_sx_index] &= 0xff; // Report written _sx_write_dataSX1 = _sxbusSX1[_sx_index]; _sxbusSX1[_sx_index] &= 0xff; _sx_dataFrameCount--; if (_sx_dataFrameCount == 0) { // Move on to find SYNC pattern _sx_state = SYNC; _sx_byteCount = SX_SYNC0; } } break; default: initVar(); // Restart sending SYNC writeT0(1); writeT1(); break; } //end switch/case _sx_state } else { // 10 usec fase (clock low) readD(); // Read datalines writeTrack(0); writeT1(); // Write datalines writeT0(0); // Clock low _sx_intstate = true; TCNT1 += Timer1_10; // reload timer }}// Convert from SX-bus addresses to index in array.uint8_t SXcentrale::calcIndex(uint8_t SXadr) { uint8_t frame = 15 - (SXadr & 15); // Get the frame number uint8_t offset = 6 - (SXadr >> 4); // Get the offset in the frame return frame * 7 + offset; // Calculate the index in the array}// functions 'accessing' the SX-bus// Read data from the array, filled by the isr.// In:// bus: 0 - 3, bus to read from.// adr: 0 - 111, address value read from.// Return value:// -1: Address out of range// -3: SX-bus out of range// 0 - 255: Value from SX-busint SXcentrale::get(uint8_t bus, uint8_t adr) { // returns the value of a SX address if (adr < SX_ADDRESS_NUMBER) { switch (bus) { case 0: return _sxbusSX0[calcIndex(adr)] & 0xff; // Return value case 1: return _sxbusSX1[calcIndex(adr)] & 0xff; // case 2: // return _sxbusSX2[calcIndex(adr)] & 0xff; // case 3: // return _sxbusSX3[calcIndex(adr)] & 0xff; default: return -3; // Report bus out of range } } return -1; // Report address out of range}// Write data to the array, writing to the SX-bus is done by the isr.// In:// bus: 0 - 3, bus to send value to.// adr: 0 - 111, address value send to.// dt: 0 - 255, value send// Return value:// 0: Success// -1: Address out of range// -3: SX-bus out of rangeint SXcentrale::set(uint8_t bus, uint8_t adr, uint8_t dt) { if (adr < SX_ADDRESS_NUMBER) { switch (bus) { case 0: _sxbusSX0[calcIndex(adr)] = dt + NO_WRITE; // Make sure it is transmitted break; case 1: _sxbusSX1[calcIndex(adr)] = dt + NO_WRITE; break; // case 2: // _sxbusSX2[calcIndex(adr)] = dt + NO_WRITE; // break; // case 3: // _sxbusSX3[calcIndex(adr)] = dt + NO_WRITE; // break; default: return -3; // bus number out of range } return 0; // success } return -1; // address out of range}// Read POWER status from the SX-bus// Return value:// 0: Power off// 1: Power onuint8_t SXcentrale::getPWR() { return _sx_PWR;}// Write POWER status to the SX-bus and control a connected central.// Return value:// 0: Success// -2: Illegal power valueint SXcentrale::setPWR(uint8_t val) { if (val == 0 || val == 1) { _sx_PWR = val; return 0; } return -2;}// Every time frame 0 is passed sync bit is set by isr.// Return value:// 0: Bus out of sync// 1: Bus in syncuint8_t SXcentrale::inSync() { if (_sx_sync == 1) { _sx_sync = 0; // reset sync bit to check for next pass return 1; // report frame 0 found } return 0;}
/* * SXcentrale.cpp * * Version: 0.1 * Copyright: Gerard van der Sel * * Changed on: * Version: * Changes: * * * interface hardware needed ! Read SX Signal - SX Clock must be connected to Pin3 = INT1 and SX Data must be connected to Pin 5. Both are connected through a resistor off 22 kilo ohm. Pin 6 can be connected via a 100 ohm resistor to the write line of the SX bus This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#ifndef SXcentrale_H_#define SXcentrale_H_#include <Arduino.h>// Define arduino pins and ports// The io pins for the busses#define SX_T0 3 // Clock (for all)#define SX_T0_PORT PORTD#define SX_T0_PORTPIN PORTD3#define SX0_T1 4 // Data write#define SX0_T1_PORT PORTD#define SX0_T1_PORTPIN PORTD4#define SX0_D 5 // Data read#define SX0_D_INPORT PIND#define SX0_D_INPORTPIN PIND5#define SX1_T1 6 // Data write#define SX1_T1_PORT PORTD#define SX1_T1_PORTPIN PORTD6#define SX1_D 7 // Data read#define SX1_D_INPORT PIND#define SX1_D_INPORTPIN PIND7// The io pins for the trackamplifier#define SX_TRACKE A1#define SX_TRACKE_PORT PORTC#define SX_TRACKE_PORTPIN PORTC1#define SX_TRACKG1 A2#define SX_TRACKG1_PORT PORTC#define SX_TRACKG1_PORTPIN PORTC2#define SX_TRACKG2 A3#define SX_TRACKG2_PORT PORTC#define SX_TRACKG2_PORTPIN PORTC3// defines for state machine#define DATA 0 // For performance DATA first#define SYNC 1 // (Gives fastest code)#define PWR 2#define ADDR 3// defines for Selectrix constants#define SX_SYNC0 3 // 3 "0" bits achter elkaar#define SX_DATACOUNT 7 // 7 dataframes in 1 SYNC Channel#define SX_SEPLEN 3 // 3 bit in a separated part#define SX_BYTELEN 12 // 12 bits for one byte#define SX_ADDRESS_NUMBER 112 // number SX channels#define NO_WRITE 256 // No data to write#define Timer1_10 -160 // 10 usec delay#define Timer1_40 -640 // 40 usec delay// #define Timer1_10 30000 // 10 usec delay (debug, also set CS12)// #define Timer1_40 30000 // 40 usec delay (debug, also set CS12)class SXcentrale {public: SXcentrale(); void init(void); int get(uint8_t, uint8_t); int set(uint8_t, uint8_t, uint8_t); uint8_t getPWR(void); int setPWR(uint8_t); void isr(void); uint8_t inSync(void); private: void writeTrack(uint8_t clockbit); void writeT0(uint8_t val); void writeT1(); void readD(); void initVar(); uint8_t calcIndex(uint8_t adr); bool _sx_intstate; // interrupt timing int timer1_counter; uint8_t _sx_numFrame; // number frame uint8_t _sx_dataFrameCount; // frame counting uint8_t _sx_state; uint8_t _sx_sepCount; // bit counting (seperator) uint8_t _sx_byteCount; // bit counting (byte) uint8_t _sx_index; // current index in the array uint8_t _sx_PWR; // current state of POWER on track uint8_t _sx_read_sepCount; // bit counting (seperator) uint8_t _sx_read_byteCount; // bit counting (byte) uint8_t _sx_read_index; // current index in the array uint8_t _sx_sync; // set if Frame 0 is processed uint8_t _sx_bitTrack; uint8_t _sx_bitsendSX0; // read databit uint8_t _sx_bitresvSX0; // write databit uint8_t _sx_read_dataSX0; // read data uint8_t _sx_write_dataSX0; // data to write int _sxbusSX0[SX_ADDRESS_NUMBER]; // to store the SX-bus data uint8_t _sx_bitsendSX1; // read databit uint8_t _sx_bitresvSX1; // write databit uint8_t _sx_read_dataSX1; // read data uint8_t _sx_write_dataSX1; // data to write int _sxbusSX1[SX_ADDRESS_NUMBER]; // to store the SX-bus data /* SX Timing 1 Bit 50 us 1 Kanal 600 us (= 12 Bit) 1 Grundrahmen ca. 4,8 ms 1 Gesamtrahmen ca. 80 ms (= 16 Grundrahmen) 0 0 0 1 S 1 A3 A2 1 A1 A0 1 == sync frame of 12 bits */};#endif /* SXcentrale_H_ */
ISR(TIMER1_OVF_vect) { // interrupt service routine SXcntrl.isr();}
Dan is je objecten structuur niet goed en is er grote kans op problemen. Zo ben je van alle problemen af en is het in mijn ogen netjes geregeld.