CAN-Interface
Das CAN-Interface des SpartanMC besitzt 15 Ein-/Ausgaberegister zur Funktionsauswahl und Funktionssteuerung sowie einen DMA Speicherbereich für die zu sendenden und für die empfangenen CAN-Nachrichten. Im DMA-Speicher können 1 ... 18 Empfangspuffer und 1 ... 18 Sendepuffer installiert werden. Zusäzlich können auch 1 ... 18 Nachrichten Filter Installiert werden die bei ihrer Aktivierung dafür sorgen das nur noch Nachrichten einen Empfangsinterrupt auslösen die mit den eingestellten Filterwerten übereinstimmen. Das CAN-Interface kann Nachrichten mit dem Standard 11 Bit ID und auch mit dem Erweiterten 29 Bit ID empfangen und versenden. Beide ID Formen können gemicht auftreten. Die Datenrate ist von 5 KB/s bis 1000KB/s in den üblichen Stufen varierbar. Die DMA Puffer können beim Systemstart vorinitialisiert werden. Zum Anschluß an einen CAN-Bus muss nur noch der Treiber Schaltkreis MCP2551-I/P mit dem FPGA-Board verbunden werden. Die Schaltung dazu ist am Ende dieser Seite zu finden.Die 18 Rx und Tx Puffer werden entsprechend der Priorität gesendet, oder für den Empfang genutzt. Die Puffer Rx 0 und Tx 0 haben die höchste Priorität. Werden alle Tx Puffer im Regiter tx_request_buffer als belegt gekennzeichnet, dann wird mit dem Senden von Tx 0 (Bit 17 im Register) begonnen und erst nach dem Senden von Tx 17 (Bit 0 im Register) aufgehört. Nach dem senden eines der Puffer wird das zugehörige Bit im tx_request_buffer sofort gelöscht. Achtung, solange noch nicht alle Bits im Register gelöscht sind sollte kein Bit erneut gesetzt werden, da dann dieser Puffer eine höhere Priorität hat als die noch nicht gesendeten Puffer und damit vor den noch nicht gesendeten Puffern gesendet würde. Die Daten aller bereits gesendeten Puffer können aber schon mit neuen Daten belegt werden. Sie müssen dann nur noch freigegeben werden sobald alle Puffer des letzten Starts gesendet sind.
Beim Empfang wird immer nach dem höchsten nicht gesetzten Bit im Register rx_used_buffer gesucht und dort werden dann die Daten der empfangen Nachricht abgelegt. In den ersten 4 Worten stehen die maximal 8 Datenbyte der Nachricht. Danach stehen die unteren 18 Bit eines Extended ID, wenn die letzte Nachricht in diesem Format gesendet wurde. Daran folgt ein Wort mit einer Reihe von Statusbits, der Nachrichten Länge und den 11 Bit des Standard ID oder der oberen 11 Bit eines Extendet ID. Im Wort 7 werden die Ausgangssignale aller 18 Filter angezeigt. Hat ein Filter einen Treffer, so wird das Bit auf 1 gesetzt. Nicht initialisierte Filter (alle Bits in den Filterregistern sind 0) liefern immer eine 1. Die Bits sind aber nicht wirksam, wenn keines der Bits im Register acf_enable gesetzt ist. Sobald Bits in diesem Register gesetzt sind, werden auch nur noch diese Bits im 7. Wort angezeigt. Man kann daran erkennen welcher Filter beim Empfang der Nachricht aktiv war. Sobald ein oder mehrere Filter aktiv sind, können auch nur noch dies Nachrichten empfangen werden. Gefilter werden kann nach einem ID oder nach ID-Gruppen im Extendet oder Standard ID, auf Remoteframe und auf die oberen 4 Bit des 1. Bytes einer Nachricht. Dazu sind im Filter 2*36 Bit Register installiert. In den ersten 36 Bit muss der Wert eingetragen werden, nachdem gesucht werden soll in dem 2. Register werden die Bits maskiert, die vom Vergleich ausgeschlossern werden sollen. Damit kann man auch Teile des ID maskieren, wodurch die Auswahl von ID Gruppen möglich wird. Im 8. Wort des Rx Puffers wird der CRC der empfangenen Nachricht abgelegt.
Die Tx Puffer sind ähnlich aufgebaut. In den ersten 4 Worten stehen auch die 8 Datenbyte der zu sendenden Nachricht. Auch die nächten beiden Worte sind wie beim Rx Puffer mit den unteren 18 Bit des Extendet ID und das Wort 6 mit dem RTR-Bit, dem IDE-Bit, der Länge und den 11 Bit des Standard ID oder den oberen 11 Bit des Extendet ID zu laden. Im 7. Wort ist die Anzahl der Sendewiederholungen abzulegen. Null bedeutet die Nachricht soll nur einmal gesendet werden. Das 8. Wort im Puffer wird nicht genutzt.
Das CAN-Interface kann auch im Listen Only Mode eingesetzt werden um alle Nachrichten auf einem CAN-Bus zu protokollieren. Dabei werden auch fehlerhafte und nicht beantwortete Nachrichten angezeigt. Bei Aktivierung der Filter werden nur noch die Nachrichten an ein bestimmtes Gerät oder eine Gerätegruppe angezeigt. Mit diesem Mode kann gut nach Fehlern auf dem CAN-Bus gesucht werden.
Register des Kontrollers
Offset | Register-Name | Bit | Bez. in Verilog | Beschreibung (Rechte) | Initialwert | |||
0 | Arbeitsregister | work | Schreiben und Lesen immer möglich | |||||
17-10 | (nur Lesen) nicht genutzt | |||||||
9-8 | can_mode | setzt Arbeitsmodus des CAN-Controller | h3 | |||||
7 | abort_tx | bricht Telegrammsendung ab | b0 | |||||
6 | en_exception_ir | aktiviert/deaktiviert Exception Interrupt | b0 | |||||
5 | en_tx_successful_ir | aktiviert/deaktiviert TX Interrupt | b0 | |||||
4 | en_rx_successful_ir | aktiviert/deaktiviert RX Interrupt | b0 | |||||
3 | overload_request | fordert ein Overload Frame an | b0 | |||||
2 | transmitting | (nur Lesen) gesetzt wenn Gesendet wird | b0 | |||||
1 | receiving | (nur Lesen) gesetzt wenn Empfangen wird | b0 | |||||
0 | bus_free | (nur Lesen) gesetzt wenn der Bus frei ist | b0 | |||||
1 | Konfigurations Register | choose_config | ||||||
17-2 | (nur Lesen) nicht genutzt | |||||||
1 | sample_mode | schaltet 3-fach Abtastung an | b0 | |||||
0 | extended_mode | Ermöglicht das Versenden von Extended Frames | b1 | |||||
2 | Bus-Timing-Reg. | bustiming | Schreiben nur im Config_Mode | |||||
17-10 | baudrate_presc | BRP | h0 | |||||
9-8 | sync_jump_width | SJW | h2 | |||||
7-3 | time_segment1 | Länge des Prop_Seg & Phase_Seg1 in tq = tseg1 | h15 | |||||
2-0 | time_segment2 | Länge des Phase_Seg2 in tq-2 = tseg2 | h4 | |||||
3 | Fehlerzähler-Reg. | error_cnt | Schreiben und Lesen immer möglich | |||||
17-9 | rx_error_cnt | setzen oder lesen Empfangsfehlerzähler | h0 | |||||
8-0 | tx_error_cnt | setzen oder lesen Sendefehlerzähler | h0 | |||||
4 | Fehlerwarnungs-Reg. | warn_state | Schreiben nur im Config_Mode & Extended_Mode | |||||
17-8 | (nur Lesen) nicht genutzt | h0 | ||||||
7-0 | error_warning_limit | setzt Errorwarnungswert (96 = 0x60) | h60 | |||||
5 | ACF Adress-Reg. | acf_select | Schreiben nur im Config_Mode | |||||
17-5 | nicht genutzt | |||||||
4-0 | acf_adr | ACF-Adresse setzen übernimmt die Filterregeln in Register 6-9 | h0 | |||||
5 | ACF Freigabe | acf_enable | Schreiben und lesen, wenn kein Config_Mode | |||||
17-0 | acf_en | Jeder ACF-Filter wird mit einer 1 freigegeben. Sind alle Bits 0, werden alle Telegramme angenommen. | h0 | |||||
6 | ACF Code-Reg.1 | acf_ac1 | Schreiben nur im Config_Mode | |||||
17 | ac_rtr1 | setzt ACF Code für RTR Bit (SSR bei Ext. Frames) | b0 | |||||
16 | ac_rtr2 | setzt ACF Code für RTR Bit für Ext. Frames | b0 | |||||
15-12 | ac_data | setzt ACF Code für ersten 4 Bit des Datenteils | h0 | |||||
11 | ac_we | ist 1 solange das Schreiben noch nicht beendet (read only) | b0 | |||||
10-0 | ac_b_id | setzt ACF Code für die ersten 11 Bit Identifier | h0 | |||||
7 | ACF Masken-Reg. 1 | acf_am1 | Schreiben nur im Config_Mode (gesetzte Bits werden nicht Verglichen) | |||||
17 | am_rtr1 | setzt ACF Maske für RTR Bit (SSR bei Ext. Frames) | b0 | |||||
16 | am_rtr2 | setzt ACF Maske für RTR Bit für Ext. Frames | b0 | |||||
15-12 | am_data | setzt ACF Maske für ersten 4 Bit des Datenteils | hF | |||||
11 | frei | b0 | ||||||
10-0 | am_b_id | setzt ACF Maske für die ersten 11 Bit Identifier | h7FF | |||||
8 | ACF Code-Reg. 2 | acf_ac2 | Schreiben nur im Config_Mode | |||||
17-0 | ac_e_id | setzt den ACF Code für den zweiten 18 Bit Identifier | h0 | |||||
9 | ACF Masken-Reg. 2 | acf_am2 | Schreiben nur im Config_Mode (gesetzte Bits werden nicht Verglichen) | |||||
17-0 | am_e_id | setzt die ACF Maske für den zweiten 18 Bit Identifier | h3FFFF | |||||
10 | Fehler-Code-Reg. | error_code | (nur Lesen) Schreiben setzt Exception Interrupt zurück | |||||
17 | error_warning | gesetzt, wenn error_warning_limit überschritten | b0 | |||||
16 | error_dirction | 0 - CAN write / 1 - CAN read | b0 | |||||
15 | frei | b0 | ||||||
14-12 | error_typ | Bit-, Form-, Stuff-, CRC-, ACK-Error | h0 | |||||
11-9 | frei | h0 | ||||||
8-4 | Zustand des Rx Automat | h0 | ||||||
3 | node_error_passive | gesetzt, wenn der Controller nur noch passiv mithört (127 < Fehlerzähler <= 255) | b0 | |||||
2 | node_bus_off | gesetzt, wenn sich der Controller vom Bus getrennt hat (Fehlerzähler > 255) | b0 | |||||
1 | rx_buffer_full_q | gesetzt wenn RX Puffer voll | b0 | |||||
0 | send_failed_q | gesetzt wenn Senden endgültig fehlschlug | b0 | |||||
11 | TX Success-Reg. | tx_succ | (nur Lesen) Schreiben setzt TX Interrupt zurück | |||||
9-0 | tx_start_adr | Adresse die als letztes aus TX Puffer gelesen wurde | h0 | |||||
12 | RX Success-Reg. | rx_succ | (nur Lesen) Schreiben setzt RX Interrupt zurück | |||||
9-0 | rx_start_adr | Adresse die als letztes im RX Puffer geschrieben wurde | h0 | |||||
13 | TX Puffer-Reg. | tx_buffer | Schreiben und Lesen immer möglich | |||||
17-0 | tx_request_buffer | Belegungsstatus des TX Puffer (1= voll, 0= leer) | h0 | |||||
14 | RX Puffer-Reg. | rx_buffer | Schreiben und Lesen immer möglich | |||||
17-0 | rx_used_buffer | Belegungsstatus des RX Puffer (1= voll, 0= leer) | h0 |
Berechnung der CAN-Bitfrequenz aus den Werten im Bus-Timing Register
f = can_clk / ( (BRP+2)*(1+tseg1+tseg2+2) ) = 28000 kHz / ( (6+2)*(1+21+4+2) ) = 28000 kHz / (8*28) = 125 kHz- Je größer die Summe von (1+tseg1+tseg2+2), desto besser kann synchronisiert werden.
- Je größer SJW, desto mehr Bits kann der Synchronisationszeitpunkt automatisch verschoben werden.
- Mit SJW wird entweder die Periodendauer vergrößert durch (tseg1 + SJW) oder verkleinert mit (tseg2 - SJW) um den Synchronisationszeitpunkt von Sender und Empfänger wieder anzugleichen.
- Der Teilerwert, der sich aus 1+ tseg1 + tseg2 + 2 ergibt, ist die Anzahl der Zeitquanten (tq) der Nominal CAN Bit Time = 100%
- tseg2+2 Minimum sollte > (100 - 87,5)% = 12,5% von der Nominal CAN Bit Time betragen.
- tseg2+2 Maximum sollte < (100 - 75,0)% = 25,0% von der Nominal CAN Bit Time betragen.
Baudrate | BRP | SJW | tseg1 | tseg2 | Bus-Timing Reg. | tseg2+2 in % | tseg2+2 in % bei +SJW | tseg2+2 in % bei -SJW |
8 Bit | 2 Bit | 5 Bit | 3 Bit | Summe = 18 Bit | ||||
1000 kBit/s | 0 | 1 | 10 | 1 | 0x00151 | 21,4 | (3/(1+11+3))*100=20,0 | (2/(1+10+2))*100=15,4 |
500 kBit/s | 0 | 2 | 21 | 4 | 0x002AC | 21,4 | (6/(1+23+6))*100=20,0 | (4/(1+21+4))*100=15,4 |
250 kBit/s | 2 | 2 | 21 | 4 | 0x00AAC | 21,4 | (6/(1+23+6))*100=20,0 | (4/(1+21+4))*100=15,4 |
125 kBit/s | 6 | 2 | 21 | 4 | 0x01AAC | 21,4 | (6/(1+23+6))*100=20,0 | (4/(1+21+4))*100=15,4 |
100 kBit/s | 6 | 3 | 26 | 6 | 0x01BD6 | 22,9 | (8/(1+29+8))*100=21,1 | (5/(1+26+5))*100=15,6 |
50 kBit/s | 14 | 3 | 26 | 6 | 0x03BD6 | 22,9 | (8/(1+29+8))*100=21,1 | (5/(1+26+5))*100=15,6 |
20 kBit/s | 38 | 3 | 26 | 6 | 0x09BD6 | 22,9 | (8/(1+29+8))*100=21,1 | (5/(1+26+5))*100=15,6 |
10 kBit/s | 78 | 3 | 26 | 6 | 0x13BD6 | 22,9 | (8/(1+29+8))*100=21,1 | (5/(1+26+5))*100=15,6 |
5 kBit/s | 158 | 3 | 26 | 6 | 0x27BD6 | 22,9 | (8/(1+29+8))*100=21,1 | (5/(1+26+5))*100=15,6 |
* BRP | - | Baud Rate Prescaler | (0 ... 253) |
|
* SJW | - | Synchronization Jump Width | (1 ... 3) | |
* tseg1 | - | Time Segment 1 (= Prop_Segment + Phase_Segment_1) | (4 ... 31) | |
* tseg2 | - | Time Segment 2 -2 (= Phase_Segment_2 -2) | (0 ... 7) |
Bits des Fehler-Code-Register
Bit Nummern | cy - Feld (Fehlertype) | w - Error Warning 11 .111 ...0 0000 0000 | 001 Form-Error | 76 .432 ...8 7654 3210 | 010 Stuff-Error | cd - Datenrichtung Bit Felder und Signale | 011 ACK-Error | 0 - CAN write wc .ccc ...c cccc nnft | 100 CRC-Error | 1 - CAN read d .yyy ...s ssss po x | 101 Bit-Error | | 111 alle anderen | np - node error passiv --------------------------------------------------| cs - Feld (Zustand des Automaten) | no - node bus off 0 0000 - | 0 0001 - | f - rx Puffer alle belegt 0 0010 - id1 | 0 0011 - idle | tx - senden engültig fehlgeschlagen 0 0100 - rtr1 0 0101 - ide 0 0110 - id1 & (bit_cnt > 7) 0 0111 - id2 & (bit_cnt < 5) 0 1000 - crc 0 1001 - r0 0 1010 - data 0 1011 - dlc 0 1100 - rtr2 0 1101 - r1 0 1110 - id2 & (bit_cnt > 13) 0 1111 - id2 & (bit_cnt > 4) & (bit_cnt < 13) 1 0000 - error_lim 1 0001 - error & node_error_active 1 0010 - inter 1 0011 - 1 0100 - overload_lim 1 0101 - 1 0110 - error & node_error_passive 1 0111 - 1 1000 - crc_lim 1 1001 - ack 1 1010 - eof 1 1011 - ack_lim 1 1100 - overload 1 1101 - 1 1110 - data >0 1 1111 -
Offset im DMA Puffer für den TX Puffer mit der höchsten Priorität abgeleitet aus dem Inhalt vom TX Puffer-Register bei 18 Puffern.
Register Belegung von BlockRam Word Adresse tx_buffer Adressen in C 1x xxxx xxxx xxxx xxxx --> 00 0000 0000 = 0*8 = data_tx00 01 xxxx xxxx xxxx xxxx --> 00 0000 1000 = 1*8 = data_tx01 00 1xxx xxxx xxxx xxxx --> 00 0001 0000 = 2*8 = data_tx02 00 01xx xxxx xxxx xxxx --> 00 0001 1000 = 3*8 = data_tx03 00 001x xxxx xxxx xxxx --> 00 0010 0000 = 4*8 = data_tx04 00 0001 xxxx xxxx xxxx --> 00 0010 1000 = 5*8 = data_tx05 00 0000 1xxx xxxx xxxx --> 00 0011 0000 = 6*8 = data_tx06 00 0000 01xx xxxx xxxx --> 00 0011 1000 = 7*8 = data_tx07 00 0000 001x xxxx xxxx --> 00 0100 0000 = 8*8 = data_tx08 00 0000 0001 xxxx xxxx --> 00 0100 1000 = 9*8 = data_tx09 00 0000 0000 1xxx xxxx --> 00 0101 0000 = 10*8 = data_tx10 00 0000 0000 01xx xxxx --> 00 0101 1000 = 11*8 = data_tx11 00 0000 0000 001x xxxx --> 00 0110 0000 = 12*8 = data_tx12 00 0000 0000 0001 xxxx --> 00 0110 1000 = 13*8 = data_tx13 00 0000 0000 0000 1xxx --> 00 0111 0000 = 14*8 = data_tx14 00 0000 0000 0000 01xx --> 00 0111 1000 = 15*8 = data_tx15 00 0000 0000 0000 001x --> 00 1000 0000 = 16*8 = data_tx16 00 0000 0000 0000 0001 --> 00 1000 1000 = 17*8 = data_tx17 00 0000 0000 0000 0000 --> alle Puffer leer
In C werden die Puffer mit zB.: CAN_0_DMA->data_tx00 angesprochen.
Offset im DMA Puffer für den ersten freien RX Puffer abgeleitet aus dem Inhalt vom RX Puffer-Register bei 18 Puffern.
Register Belegung von Nummer des BlockRam Word Adresse rx_buffer rx_block Adresse in C 0x xxxx xxxx xxxx xxxx --> ( 0 0000 + 18 ) * 8 = 00 1001 0000 = ( 0+18)*8 = data_rx00 10 xxxx xxxx xxxx xxxx --> ( 0 0001 + 18 ) * 8 = 00 1001 1000 = ( 1+18)*8 = data_rx01 11 0xxx xxxx xxxx xxxx --> ( 0 0010 + 18 ) * 8 = 00 1010 0000 = ( 2+18)*8 = data_rx02 11 10xx xxxx xxxx xxxx --> ( 0 0011 + 18 ) * 8 = 00 1010 1000 = ( 3+18)*8 = data_rx03 11 110x xxxx xxxx xxxx --> ( 0 0100 + 18 ) * 8 = 00 1011 0000 = ( 4+18)*8 = data_rx04 11 1110 xxxx xxxx xxxx --> ( 0 0101 + 18 ) * 8 = 00 1011 1000 = ( 5+18)*8 = data_rx05 11 1111 0xxx xxxx xxxx --> ( 0 0110 + 18 ) * 8 = 00 1100 0000 = ( 6+18)*8 = data_rx06 11 1111 10xx xxxx xxxx --> ( 0 0111 + 18 ) * 8 = 00 1100 1000 = ( 7+18)*8 = data_rx07 11 1111 110x xxxx xxxx --> ( 0 1000 + 18 ) * 8 = 00 1101 0000 = ( 8+18)*8 = data_rx08 11 1111 1110 xxxx xxxx --> ( 0 1001 + 18 ) * 8 = 00 1101 1000 = ( 9+18)*8 = data_rx09 11 1111 1111 0xxx xxxx --> ( 0 1010 + 18 ) * 8 = 00 1110 0000 = (10+18)*8 = data_rx10 11 1111 1111 10xx xxxx --> ( 0 1011 + 18 ) * 8 = 00 1110 1000 = (11+18)*8 = data_rx11 11 1111 1111 110x xxxx --> ( 0 1100 + 18 ) * 8 = 00 1111 0000 = (12+18)*8 = data_rx12 11 1111 1111 1110 xxxx --> ( 0 1101 + 18 ) * 8 = 00 1111 1000 = (13+18)*8 = data_rx13 11 1111 1111 1111 0xxx --> ( 0 1110 + 18 ) * 8 = 01 0000 0000 = (14+18)*8 = data_rx14 11 1111 1111 1111 10xx --> ( 0 1111 + 18 ) * 8 = 01 0000 1000 = (15+18)*8 = data_rx15 11 1111 1111 1111 110x --> ( 1 0000 + 18 ) * 8 = 01 0001 0000 = (16+18)*8 = data_rx16 11 1111 1111 1111 1110 --> ( 1 0001 + 18 ) * 8 = 01 0001 1000 = (17+18)*8 = data_rx17 11 1111 1111 1111 1111 --> alle Puffer voll
In C werden die Puffer mit z.B.: CAN_0_DMA->data_rx00 angesprochen.
Anordnung der Telegramme im DMA-Speicher
Durch die oben dargestellte Zuordnung der Bits in den Registern rx_buffer = 0x36000 und tx_buffer = 0x2c000 ergibt sich folgender Aufbau Rx Puffer nach dem 1. Aufruf des Selbsttest.Word Adr. im Blockram | Inhalt des 18 Bit Wort | freie | Inhalt initialisiert durch can_init.c | Bemerkung | ||||
hexadezimal | Telegrammnummer/Inhalt | bits | hexadezimal | aus can_init.c | ||||
0x000 | TX 1 / frei, Byte 0, Byte 1 | 2 | 0x0f0f0 | 0,0,data0,data1 (00 11110000 11110000) | ||||
0x001 | TX 1 / frei, Byte 2, Byte 3 | 2 | 0x0aa55 | 0,0,data2,data3 (00 10101010 01010101) | ||||
0x002 | TX 1 / frei, Byte 4, Byte 5 | 2 | 0x0f0f0 | 0,0,data4,data5 (00 11110000 11110000) | ||||
0x003 | TX 1 / frei, Byte 6, Byte 7 | 2 | 0x0aa55 | 0,0,data6,data7 (00 10101010 01010101) | ||||
0x004 | TX 1 / Extended ID | 0 | 0x00000 | extID (00 00000000 00000000) | ||||
0x005 | TX 1 / RTR, IDE, DLC, frei, Standard ID | 1 | 0x28555 | stdID (10 1000 0 10101010101)Remoteframe 8 Byte | ||||
0x006 | TX 1 / frei, Retry Zähler -1 | 12 | 0x00003 | retry_tx -1 (00 0000 0000 00 000011) | ||||
0x007 | TX 1 / frei | 18 | 0x03000 | leere Speicherstelle | ||||
0x008 | TX 2 / frei, Byte 0, Byte 1 | 2 | 0x0cc33 | 0,0,data0,data1 (00 11001100 00110011) | ||||
0x009 | TX 2 / frei, Byte 2, Byte 3 | 2 | 0x0f0f0 | 0,0,data2,data3 (00 11110000 11110000) | ||||
0x00A | TX 2 / frei, Byte 4, Byte 5 | 2 | 0x0cc33 | 0,0,data4,data5 (00 11001100 00110011) | ||||
0x00B | TX 2 / frei, Byte 6, Byte 7 | 2 | 0x0f0f0 | 0,0,data6,data7 (00 11110000 11110000) | ||||
0x00C | TX 2 / Extended ID | 0 | 0x00000 | extID (00 00000000 00000000) | ||||
0x00D | TX 2 / RTR, IDE, DLC, frei, Standard ID | 1 | 0x0841f | stdID (00 1000 0 10000011111) 8 Byte | ||||
0x00E | TX 2 / frei, Retry Zähler -1 | 18 | 0x00000 | retry_tx -1 (00 0000 0000 00 000000) | ||||
0x00F | TX 2 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
0x010 | TX 3 / frei, Byte 0, Byte 1 | 2 | 0x0cc33 | 0,0,data0,data1 (00 11001100 00110011) | ||||
0x011 | TX 3 / frei, Byte 2, Byte 3 | 2 | 0x0f0f0 | 0,0,data2,data3 (00 11110000 11110000) | ||||
0x012 | TX 3 / frei, Byte 4, Byte 5 | 2 | 0x0cc33 | 0,0,data4,data5 (00 11001100 00110011) | ||||
0x013 | TX 3 / frei, Byte 6, Byte 7 | 2 | 0x0f0f0 | 0,0,data6,data7 (00 11110000 11110000) | ||||
0x014 | TX 3 / Extended ID | 0 | 0x00000 | extID (00 00000000 00000000) | ||||
0x015 | TX 3 / RTR, IDE, DLC, frei, Standard ID | 1 | 0x0841f | stdID (00 1000 0 10000011111) 8 Byte | ||||
0x016 | TX 3 / frei, Retry Zähler -1 | 18 | 0x00000 | retry_tx -1 (00 0000 0000 00 000000) | ||||
0x017 | TX 3 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
0x018 | TX 4 / frei, Byte 0, Byte 1 | 2 | 0x0f0f0 | 0,0,data0,data1 (00 11110000 11110000) | ||||
0x019 | TX 4 / frei, Byte 2, Byte 3 | 2 | 0x10000 | 0,0,data2,data3 (01 00000000 00000000) | ||||
0x01A | TX 4 / frei, Byte 4, Byte 5 | 2 | 0x00000 | 0,0,data4,data5 (00 00000000 00000000) | ||||
0x01B | TX 4 / frei, Byte 6, Byte 7 | 2 | 0x00000 | 0,0,data6,data7 (00 00000000 00000000) | ||||
0x01C | TX 4 / Extended ID | 0 | 0x3C3C3 | extID (11 11000011 11000011) | ||||
0x01D | TX 4 / RTR, IDE, DLC, frei, Standard ID | 1 | 0x12533 | extID (01 0010 0 10100110011) Extended ID 2 Byte | ||||
0x01E | TX 4 / frei, Retry Zähler -1 | 18 | 0x00000 | retry_tx -1 (00 0000 0000 00 000000) | ||||
0x01F | TX 4 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
0x020 | TX 5 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
... | ... | |||||||
0x08F | TX 18 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
Rx Inhalte nach Ausführung des Tests | ||||||||
0x090 | RX 1 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
... | ... | |||||||
0x09F | RX 2 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
0x0A0 | RX 3 / frei | 18 | 0x00000 | tx1 leere Speicherstelle | ||||
0x0A1 | RX 3 / frei | 18 | 0x00000 | tx1 leere Speicherstelle | ||||
0x0A2 | RX 3 / frei | 18 | 0x00000 | tx1 leere Speicherstelle | ||||
0x0A3 | RX 3 / frei | 18 | 0x00000 | tx1 leere Speicherstelle | ||||
0x0A4 | RX 3 / frei | 18 | 0x00000 | tx1 extID (00 00000000 00000000) | ||||
0x0A5 | RX 3 / frei | 18 | 0x28555 | TX1 stdID (10 1000 0 10101010101) Remoteframe 8 Byte | ||||
0x0A6 | RX 3 / frei | 18 | 0x3FFF2 | TX1 ACF match (11 11111111 11110010) | ||||
0x0A7 | RX 3 / frei | 18 | 0x0608E | CRC des empfangen Telegramms | ||||
0x0A8 | RX 4 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
... | ... | |||||||
0x0B7 | RX 5 / frei | 18 | 0x00000 | leere Speicherstelle | ||||
0x0B8 | RX 6 / frei | 18 | 0x0CC33 | TX3 0,0,data0,data1 (00 11001100 00110011) | ||||
0x0B9 | RX 6 / frei | 18 | 0x0f0f0 | TX3 0,0,data2,data3 (00 11110000 11110000) | ||||
0x0BA | RX 6 / frei | 18 | 0x0cc33 | TX3 0,0,data4,data5 (00 11001100 00110011) | ||||
0x0BB | RX 6 / frei | 18 | 0x0f0f0 | TX3 0,0,data6,data7 (00 11110000 11110000) | ||||
0x0BC | RX 6 / frei | 18 | 0x00000 | TX3 extID (00 00000000 00000000) | ||||
0x0BD | RX 6 / frei | 18 | 0x0841f | TX3 stdID (00 1000 0 10000011111) 8 Byte | ||||
0x0BE | RX 6 / frei | 18 | 0x3FFF1 | TX3 ACF match (11 11111111 11110001) | ||||
0x0BF | RX 6 / frei | 18 | 0x06A52 | CRC des empfangen Telegramms | ||||
0x0C0 | RX 7 / frei | 18 | 0x0f0f0 | TX4 0,0,data0,data1 (00 11110000 11110000) | ||||
0x0C1 | RX 7 / frei | 18 | 0x00000 | tx4 leere Speicherstelle | ||||
0x0C2 | RX 7 / frei | 18 | 0x00000 | tx4 leere Speicherstelle | ||||
0x0C3 | RX 7 / frei | 18 | 0x00000 | tx4 leere Speicherstelle | ||||
0x0C4 | RX 7 / frei | 18 | 0x3C3C3 | TX4 extID (11 11000011 11000011) | ||||
0x0C5 | RX 7 / frei | 18 | 0x12533 | TX4 extID (01 0010 0 10100110011) Extended ID 2 Byte | ||||
0x0C6 | RX 7 / frei | 18 | 0x3FFF8 | TX4 ACF match (11 11111111 11111000) | ||||
0x0C7 | RX 7 / frei | 18 | 0x007AA | CRC des empfangen Telegramms | ||||
... | ... | |||||||
0x11F | RX 18 / frei | 18 | 0x00000 | leere Speicherstelle |
Die Filter des CAN-Interface waren dabei wie folgt eingestellt:
/* Setzen der Filter mit der Funktion: void can_set_acf(struct can *can_p, unsigned int data1, unsigned int maske1, unsigned int data2, unsigned int maske2, unsigned int acf_sel); aus der Datei can.h */
#define ACF_DATA11 0x0041f // 00,0000. 0, 100_0001_1111 rtr1,rtr2,data0, frei ,stdID #define ACF_MASK11 0x3f800 // 11,1111, 1, 000_0000_0000 rtr1,rtr2,data0, frei ,stdID #define ACF_DATA21 0x00000 // exID #define ACF_MASK21 0x3ffff // maskierte Bits werden nicht verglichen #define ACF_SELECT_1 0x00001 // Filter Nummer #define ACF_DATA12 0x00555 // 00,0000. 0, 101_0101_0101 rtr1,rtr2,data0, frei ,stdID #define ACF_MASK12 0x3f800 // 11,1111, 1, 000_0000_0000 rtr1,rtr2,data0, frei ,stdID #define ACF_DATA22 0x00000 // exID #define ACF_MASK22 0x3ffff // maskierte Bits werden nicht verglichen #define ACF_SELECT_2 0x00002 // Filter Nummer #define ACF_DATA13 0x00720 // 00,0000. 0, 111_0010_0000 rtr1,rtr2,data0, frei ,stdID #define ACF_MASK13 0x3f800 // 11,1111, 1, 000_0000_0000 rtr1,rtr2,data0, frei ,stdID #define ACF_DATA23 0x00000 // exID #define ACF_MASK23 0x3ffff // maskierte Bits werden nicht verglichen #define ACF_SELECT_3 0x00003 // Filter Nummer #define ACF_DATA14 0x00533 // 00,0000. 0, 101_0011_0011 rtr1,rtr2,data0, frei ,stdID #define ACF_MASK14 0x3f800 // 11,1111, 1, 000_0000_0000 rtr1,rtr2,data0, frei ,stdID #define ACF_DATA24 0x3c3c3 // exID #define ACF_MASK24 0x00000 // nicht maskierte Bits werden verglichen #define ACF_SELECT_4 0x00004 // Filter Nummer can_set_acf(CAN_0, ACF_DATA11, ACF_MASK11, ACF_DATA21, ACF_MASK21, ACF_SELECT_1); // = 1 can_set_acf(CAN_0, ACF_DATA12, ACF_MASK12, ACF_DATA22, ACF_MASK22, ACF_SELECT_2); // = 2 can_set_acf(CAN_0, ACF_DATA13, ACF_MASK13, ACF_DATA23, ACF_MASK23, ACF_SELECT_3); // = 3 can_set_acf(CAN_0, ACF_DATA14, ACF_MASK14, ACF_DATA24, ACF_MASK24, ACF_SELECT_4); // = 4 CAN_0->acf_select = 0; // kein Filter freigegeben
can_init.c zur Vorinitialisierung der CAN-Telegramme im DMA-Speicher.
can.h mit der Register und Puffer Struktur des CAN-Interfaces.
Test der Funktion des SpartanMC CAN-Interface.
Dokumente zum CAN
- Schaltplan des verwendeten CAN-Treiber
- Leiterplatte des verwendeten CAN-Treiber
- ISO 11898
- ISO 16845
- Sontheim_CanFox_Dokumentation_de
- PCAN-USB Modul
- Informationen zum CAN-Bus
- CAN bus Waveform
- CAN im Wikipedia