-
Ich hätte an dieser Stelle noch eine Frage.
Sind die Leitungen vom CAN-BUS eigendlich Kurzschlusssicher?
Also dass das Senden nicht mehr möglichist ist klar, aber ist der Transciever dann auch hinüber?
Konnte im DBL nichts finden bezüglich CANL und CANH.
-
Die Leitungen sind Kurzschlusssicher, sowohl gegeneinander als auch gegen +12V und GND (ist zumindest mit PCA82C250 ausprobiert).
Wenn man fehlertolerante Transceiver wie z.B. den TJA1053 nimmt, funktioniert der Bus bei einem Kurzschluss sogar noch.
askazo
-
Das ist ja nicht schlecht, ehrlich wahr!
Danke für den Tipp!
-
Aber Vorsicht: Der TJA1053 ist ein Low-Speed-Transceiver, der geht also nur bis max. 125kb/s
askazo
-
Hallo,
Ich hab mich ja ziemlich mit dem CAN-BUS nun beschäftigt und hab wieder ein Codeschnipsel für euch.
Mit diesem gelingt es ganz schnell einen freien TX-Buffer automatisch suchen zu lassen.
Lasst euch aber von "sender" und "befehl" nicht verwirren. Aus diesen beiden setzt sich in meinen CAN-Systemen der Identifyer zusammen...
Code:
uint8_t MCP2515_status( void ){
uint8_t status;
SPI_cs_low();
SPI_master_transmit( 0b10100000 ); // Read Status ( S.64 bzw. S.67 )
status = SPI_master_transmit( 0xFF );
SPI_cs_high();
return status;
}
void CAN_transmit( uint8_t sender, uint8_t befehl, uint8_t rtr, uint8_t dlc, uint8_t *data ){
uint8_t status = MCP2515_status();
uint8_t buffer;
if( !(status & (1<<6)) ){ buffer = 0b01000100; } // TXB2CTRL.TXREQ
if( !(status & (1<<4)) ){ buffer = 0b01000010; } // TXB1CTRL.TXREQ
if( !(status & (1<<2)) ){ buffer = 0b01000000; } // TXB0CTRL.TXREQ
uint8_t i = 0;
SPI_cs_low();
SPI_master_transmit( buffer );
SPI_master_transmit( (sender<<3) + (befehl>>3) );
SPI_master_transmit( (befehl<<5) );
SPI_master_transmit( 0x00 );
SPI_master_transmit( 0x00 );
SPI_master_transmit( (rtr<<6) + (dlc) );
while( i<dlc ){
SPI_master_transmit( data[i] );
i++;
}
SPI_cs_high();
switch (buffer){
case 0b01000000: MCP2515_bit_modify( TXB0CTRL, (1<<TXREQ), 0xFF ); break;
case 0b01000010: MCP2515_bit_modify( TXB1CTRL, (1<<TXREQ), 0xFF ); break;
case 0b01000100: MCP2515_bit_modify( TXB2CTRL, (1<<TXREQ), 0xFF ); break;
}
}
-
!Wichtiger Bericht!
Falls Ihr vorhaben solltet, wie ich, beispielsweise alle 0,5 Sekunden eine Nachricht über den CAN-BUS zu versenden, und das per Timer-Interrupt steuern wollt, müsst ihr folgendes beachten...
Ihr dürft die Nachricht nicht direkt im Interrupt versenden!!!
Man sollte statt dessen im Interrupt eine Variable setzen, und diese dann in der normalen Operation abfragen, mit if() oder so...
WEIL:
Sollte der Zufall eintreten, dass genau dann der Interrupt ausgeführt wird, wenn der ATMEL gerade seine Daten an den CAN-Controller schickt, so wird diese Aktion unterbrochen, und die neue Information wird gesendet. Das führt unter umständen dazu, dass das Programm ( aber nicht die Interruptroitinen ) da hängen bleibt, wo er auf beendung der SPI-Transmission wartet.
Sollte man beachten! Ich hab stundenlang gesucht! ](*,)
-
HI, ich hab ein problem mit den SPI Funktionen, wieso leist man den Bus, indem man 0xff schreibt ?
hier der entsprechende Codeabschnitt:
Code:
//|============================= SPI Transmission =============================|
uint8_t spi_putc( uint8_t data )
{
// Sende ein Byte
SPDR = data;
// Warten bis Byte gesendet wurde
while( !( SPSR & (1<<SPIF) ) );
return SPDR;
}
//|============================ Ein Register lesen ============================|
uint8_t mcp2515_read_register(uint8_t adress)
{
uint8_t data;
PORTB &= ~(1<<SPI_CS); // CS low
spi_putc(SPI_READ);
spi_putc(adress);
data = spi_putc(0xff);
PORTB |= (1<<SPI_CS); // CS high
return data;
}
-
Die Adresse muss ja erst übertragen werden. Nachdem die Adresse übertragen ist, wird das gelesene Byte (data) zum Master rotiert. Dafür wird noch eine Transmission gebraucht.
-
Skizze aus dem Datenblatt jedes ATMegas:
Bild hier
Das sind zwei schieberegister. Wenn du als Master die Daten haben willst, die der Slave gerade im Datenregister hat, musst du auf der MOSI leitung 8 Bits reinstopfen, dass auf der anderen Seite des Registers im Slave die Bits über die MISO Leitung herausfallen und zum Master gelangen....
Ob es zwingend notwendig ist 0xFF zu senden weiß ich jetzt auch nicht. It aber so gesehen das sinnvollste... Was sagst du Sprinter?
-
Der Slave kann ja nicht in die Zukunft schauen oder die Adresse erraten, aus der er das Datum lesen soll. Die Adresse ist aber erst im Slave NACH dem spi_putc(adress). Daher muss noch eine Übertragung gemacht werden, um die Nutzinformation zu bekommen.
Wird noch besser klar, wenn man sich deine Skizze anschaut.