Hallo Leute, Bin gerade dabei ein kleines Programm mit Can-Bus zu schreiben. Funktioniert auch soweit mit der 11 Bit-ID. Nub benötige ich die extended ID. Leider funktioniert das nicht so wie ich mir das vorstelle. Ich bekomme immer eine andere ID als die, die ich deklariert habe. Vieleicht fällt ja jemanden der Fehler auf. Danke im vorraus! hier der Code: */ #include <avr/io.h> // Einbinden der Bibliothek #include <avr/interrupt.h> // Einbinden der Bibliothek volatile uint8_t ms_tick = 0; // wird alle 10ms aufgerufen ISR (TIMER3_COMPA_vect) // Interrupt aufrufen { ms_tick = 42; } void timer3_init(void) { // EMPFANGEN VON DATEN // Timer3 - 10ms bei 2 Mhz TCCR3B = 0x00; // Stop ---> timer/counter control register //TCCR3A = 0x00; //TCCR3C = 0x00; OCR3A = 19999; // TOP - Timer zählt bis zum maximalen wert von 19999 und gibt einen Interrupt aus (Seite 140 im Datenblatt) TIMSK3 |= (1<<OCIE3A); // Timer/Counter Interrupt Mask Register (Seite 142 im Datenblatt) TCCR3B |= (1<<WGM32) | (1<<CS31); // Modus = CTC, Vorteiler (prescaler) = 8 dies entspricht dann 2 MHz (Seite 138 im Datenblatt) } void can_init(void) // CAN initialisieren { uint8_t i,j; // deklarienen von Variabeln //uint16_t id; // Kurze ID aktiviren durch entfernen von uint32_t id; // Lange ID aktiv CANGCON = (1<<SWRES); // Reset ---> can general control register (Seite 252 im Datenblatt) // reset all message objekts for (i=0; i<15; i++) // Schleife { CANPAGE = (i<<4); // select message objekt CANCDMOB = 0x00; // disable message objekt CANSTMOB = 0x00; // Statusregister zurücksetzen // clear CAN identifier tag registers (Seite 263 im Datenblatt) CANIDT1 = 0x00; // Register 1 zurücksetzen CANIDT2 = 0x00; // Register 2 zurücksetzen CANIDT3 = 0x00; // Register 3 zurücksetzen CANIDT4 = 0x00; // Register 4 zurücksetzen // clear CAN identifier mask registers (Seite 265 im Datenblatt) CANIDM1 = 0x00; // Register 1 zurücksetzen CANIDM2 = 0x00; // Register 2 zurücksetzen CANIDM3 = 0x00; // Register 3 zurücksetzen CANIDM4 = 0x00; // Register 4 zurücksetzen // clear CAN data message register (Seite 266 im Datenblatt) for (j=0; j<8; j++) { CANMSG = 0x00; // Register 1 zurücksetzen } } // Einstellung für eine 250 kBit/s Baudrate mit 16 MHz Quarzoszillator (Seite 267 im Datenblatt) //CÁN bit timing register CANBT1 = 0x06; // Register 1 CANBT2 = 0x0C; // Register 2 CANBT3 = 0x37; // Register 3 CANGCON = (1<<ENASTB); // Aktivieren des CAN-Busses // CAN-Einstellung für den Mikrocontroller id = 0x18FF50E5; // ID vom Mikrocontroller CANPAGE = (0<<4); // Auswählen des MOB0 CANIDT1 = (id >> 3); // Setzen der Bits 3-10 der Nachrichten-ID in das CANIDT1 Register CANIDT2 = (id << 5); // Setzen der Bits 0-2 der Nachrichten-ID in das CANIDT2 Register CANIDM1 = 0xFF; // alles auf High-Pegel setzten CANIDM2 = 0xE0; CANIDM4 = (1<<IDEMSK); // setzten des identifier extension mask (Seite 265 im Datenblatt) CANCDMOB = (1<<CONMOB1) | (1<<IDE) | 8; // Empfangsmodus eingeschaltet für 8 Byte Nachrichtenlänge // CAN-Einstellung für den emfänger id = 0x1806E5F4; // ID vom Ladegerät CANPAGE = (1<<4); // Auswählen des MOB1 CANIDT1 = (id >> 3); // Setzen der Bits 3-10 der Nachrichten-ID in das CANIDT1 Register CANIDT2 = (id << 5); // Setzen der Bits 0-2 der Nachrichten-ID in das CANIDT2 Register CANIDM1 = 0xff; // alles auf High-Pegel setzten CANIDM2 = 0xe0; CANIDM4 = (1<<IDEMSK); // setzten des identifier extension mask (Seite 265 im Datenblatt) CANCDMOB = (1<<IDE) | 8; // Sendemodus eingeschaltet für 8 Byte Nachrichtenlänge CANSTMOB |= (1<<TXOK); // Interruptaufruf bei Versandbestätigung einleiten // CAN general interrupt enable register CANGIE = 0x00; // gesamtes CAN general interrupt enable register deaktivieren (Seite 255 im Datenblatt) CANIE1 = 0x00; // message objekt interrupts 8-14 deaktiviert (Seite 257 im Datenblatt) CANIE2 = 0x00; // message objekt interrupts 0-7 deaktiviert CANSIT1 = 0x00; // CAN status interrupt message objekt register 1 deaktivieren (Seite 257 im Datenblatt) CANSIT2 = 0x00; // CAN status interrupt message objekt register 2 deaktivieren } int main(void) { uint8_t data[8]; // deklaration von Variabeln uint8_t can_delay = 0; // deklaration von Variabeln int i; // deklaration von Variabeln float current; // deklaration von Variabeln current=32; // deklaration von Variabeln // deklaration der emfangenen Datenbytes int Byte1; // Ausgangsspannung HighByte int Byte2; // Ausgangsspannung LowByte int Byte3; // Ausgangsstrom HighByte int Byte4; // Ausgangsstrom LowByte int Byte5; // Fehlermeldungen int Byte6; // nicht belegt int Byte7; // nicht belegt int Byte8; // nicht belegt Byte1 = 0; // alle DatenBytes auf 0 setzten Byte2 = 0; Byte3 = 0; Byte4 = 0; Byte5 = 0; Byte6 = 0; Byte7 = 0; Byte8 = 0; // cli(); timer3_init(); //TIMER3 initalisieren can_init(); // CAN initalisieren sei(); // alle Interrupts aktivieren DDRB=0b00010101; PORTB=(0<<PB0) | (0<<PB2) | (0<<PB4); while (1) { if(ms_tick) { ms_tick = 0; CANPAGE = (0<<4); // Auswählen des MOB0 if(CANSTMOB & (1<<RXOK)) // Wurden Daten Empfangen? { Byte1= CANMSG; //Empfangene Nachricht in Byte1-8 abspeichern Byte2= CANMSG; Byte3= CANMSG; Byte4= CANMSG; Byte5= CANMSG; Byte6= CANMSG; Byte7= CANMSG; Byte8= CANMSG; if (Byte5==0b00000001) //Wenn im Byte5=1 steht { PORTB=(1<<PB0); // Fehler: Hardwarefehler PB0 aktiv } else if (Byte5==0b00000010) //Wenn im Byte5=2 steht { PORTB=(1<<PB2); //Fehler: Übertemperatur PB2 aktiv } else if (Byte5==0b00000100) // Wenn in Byte 5=4 steht { PORTB=(1<<PB0) | (1<<PB2); // Fehler: Eingangsspannung unzulässig } else if (Byte5==0b00001000) // Wenn in Byte 5=8 steht { PORTB=(1<<PB4); // Fehler Batterie nicht verbunden } else if (Byte5==0b00010000) //wenn in Byte 5=16 steht (in Hex=10) { PORTB=(1<<PB0) | (1<<PB4); //Fehler Can-Bus Fehler } else if (Byte5==0b00001100) // Wenn in Byte 5= 12 steht (in Hex=C) { PORTB=(1<<PB2) | (1<<PB4); //Fehler Keine Eingangsspannung } else { PORTB = (0<<PB0) | (0<<PB2) | (0<<PB4) ; } CANSTMOB &= ~(1<<RXOK); // Reset Flag CANCDMOB = (1<<CONMOB1) | 8; // Empfangsmodus eingeschaltet für 8 Byte Nachrichtenlänge } can_delay++; if(can_delay > 99) { can_delay = 0; CANPAGE = (1<<4); // Auswählen des MOB1 if(CANSTMOB & (1<<TXOK)) // Senden beendet? { CANSTMOB &= ~(1<<TXOK); // Reset flag CANMSG = 1; CANMSG = 2; CANMSG = 3; CANMSG = 4; CANMSG = 0; CANMSG = 0; CANMSG = 0; CANMSG = 0; CANCDMOB |= (1<<CONMOB0); // CAN übertragung einleiten } } } } } //Fehler Can-Bus Fehler } else if (Byte5==0b00001100) // Wenn in Byte 5= 12 steht (in Hex=C) { PORTB=(1<<PB2) | (1<<PB4); } else { PORTB = (0<<PB0) | (0<<PB2) | (0<<PB4) ; } CANSTMOB &= ~(1<<RXOK); // Reset Flag CANCDMOB = (1<<CONMOB1) | 8; // Empfangsmodus eingeschaltet für 8 Byte Nachrichtenlänge } can_delay++; if(can_delay > 9) { can_delay = 0; CANPAGE = (1<<4); // Auswählen des MOB1 if(CANSTMOB & (1<<TXOK)) // Senden beendet? { CANSTMOB &= ~(1<<TXOK); // Reset flag CANMSG = current; CANMSG = current; CANMSG = current; CANMSG = current; CANMSG = current; CANMSG = current; CANMSG = current; CANMSG = current; CANCDMOB |= (1<<CONMOB0); // CAN übertragung einleiten } } } } }
Du setzt die ID falsch.
1 | id = 0x18FF50E5; |
2 | id = (id << 3); |
3 | CANPAGE = (0<<4); |
4 | CANIDT = id; |
5 | CANIDM1 = 0xff; |
6 | CANIDM2 = 0xff; |
7 | CANIDM3 = 0xff; |
8 | CANIDM4 = 0xf8 | (1<<IDEMSK); |
9 | CANCDMOB = (1<<CONMOB1) | (1<<IDE) | 8; |
Danke schon mal, habe allerdings immmer noch das Problem das ich zwar die lange id bekomme aber gesendet wird mit ID:17d00000 aber er sollte ja mit 18FF50E5 senden.
hmm, habe das ganze jetzt noch einmal kontrolliert, und es um deine tipps erweitert, weiterhin bekomme ich am Can-Bus Interface die ID:17D00000 angezeigt und nicht wie gewünscht 18FF50E5. Danke für die bisherigen Tipps!:) Der aktualisierte Code befindet sich im Anhang, vielleicht findet ja noch jemand einen weiteren Fehler, bin um jede Hilfe dankbar.
Der Fehler ist in der Init. CANIDT1 = id; Das muss sein: CANIDT = id; Wenn das dann auch bei der Sende-ID alles richtig steht, dann klappt das auch mit dem Senden, im Moment ist das immer noch so als ob für 11 Bit ID eingestellt werden soll. Um das zu Testen habe ich extra eine Platine mit einem 90CAN128 ausgegraben.
Habe das ganze heute nochmals probiert, und genau so programmiert wie gesagt. Passt alles so, besten Dank!!
Hallo Rudolph R. , ich hab da leider noch immer ein kleines Problem mit der langen CAN ID. Sobald ich die lagen CAN ID aktiviere indem ich im CANCDMOB eine (1<<IDE) setze fängt das erste Byte an der Nachricht an irgendwelche Werte rauszusenden welche ich garnicht verschicken möchte. Wenn ich die ID wieder auf die kurze umstelle wird die Nachricht korreckt gesendet. Hast du vielleicht eine Idee woran das liegen könnte? Habe meinen Testcode nochmal im Anhang angefügt. Wie gesagt das mit der langen ID passt alles ich bekomme mit langer ID lediglich falsche Nachrichten gesendet (willkürliche Werte) und mit der kurzen nicht...
Unter zwei verschiedenen Namen und als .txt gepostet ist schon nicht nett. Eine Menge Deiner Kommentare ist übrigens überflüssig und ein paar falsch. Beispiele: #include <avr/io.h> // Einbinden der Bibliothek uint8_t i,j; // deklarienen von Variabeln if (Byte5==0b00000001) //Wenn im Byte5=1 steht Wenn Dir das hilft, super, so machen. Ich finde das anstrengend. Wie auch immer, schau Dir mal die Zeilen 102 und 114 genauer an.
ja, genau die beiden zeilen meine ich ja auch mit dem CANCDMOB. CANCDMOB = (1<<CONMOB1) | (0<<CONMOB0)| 8; CANCDMOB = (0<<CONMOB1) | (1<<CONMOB0)| 8; wenn ich dort dann (1<<IDE) bei beiden hinzufüge: CANCDMOB = (1<<CONMOB1) | (0<<CONMOB0)| (1<<IDE) | 8; CANCDMOB = (0<<CONMOB1) | (1<<CONMOB0)| (1<<IDE) | 8; dann ändert der zwar auf die extended ID, schreibt aber Mist in die CAN Nachricht.
Das ist alles ein wenig verwirrend. In der can_init() steht als Kommentar für MOB0 Sender und für MOB1 Empfänger. Obwohl das genau anders herum konfiguriert und benutzt wird. Und diese "(0<<CONMOB1)" Konstrukte machen das auch nicht lesbarer. In Zeile 114 steht: CANCDMOB = (0<<CONMOB1) | (1<<CONMOB0) | 8; Damit wird sofort eine Botschaft auf einer 11-Bit ID gesendet, obwohl die ID im 29-Bit Format in das CANIDT Register geschrieben wurde. Was da stehen sollte ist: CANCDMOB = (1<<IDE) | 8; Das CONMOB0 Bit wird nur gesetzt um die Botschaft einmal abzuschicken.
Rudolph R. schrieb: > Was da stehen sollte ist: > CANCDMOB = (1<<IDE) | 8; auch das ist nun geändert, aber leider keine Besserung. Noch immer macht das erste Byte was es will... Und ja bei den Kommentaren hast du recht, die waren vertauscht. So sollte es sein: // Sender id = 0x1806E5F4; // ID vom Sender id = (id << 3); CANPAGE = (0<<4); // Auswählen des MOB0 CANIDT = id; CANIDM1 = 0xFF; CANIDM2 = 0xFF; CANIDM3 = 0xFF; CANIDM4 = 0xF8 | (1<<IDEMSK); // setzten des identifier extension mask CANCDMOB = (1<<IDE) | 8; CANSTMOB |= (1<<TXOK); // Interruptaufruf bei Versandbestätigung //Empfänger id = 0x18FF50E5; // ID vom Empfänger id = (id << 3); CANPAGE = (1<<4); // Auswählen des MOB1 CANIDT = id; CANIDM1 = 0xFF; CANIDM2 = 0xFF; CANIDM3 = 0xFF; CANIDM4 = 0xF8 | (1<<IDEMSK); // setzten des identifier extension mask CANCDMOB = (1<<IDE)|8;
Günther M schrieb: > auch das ist nun geändert, aber leider keine Besserung. > Noch immer macht das erste Byte was es will... Da nuss immer noch irgendwas verdreht sein, probier es mal mit dem angehängten Test-Projekt. Das sendet alle 100ms auf 0x1806E5F4 und spiegelt dabei die Daten einer mit ID 0x18FF50E5 empfangenen Nachricht. > CANSTMOB |= (1<<TXOK); // Interruptaufruf bei Versandbestätigung Das ist nicht was damit ausgelöst wird, also der Kommentar passt nicht. > //Empfänger > CANCDMOB = (1<<IDE)|8; Damit wird noch nichts empfangen. CANCDMOB = (1<<CONMOB1) | (1<<IDE) | 8;
Rudolph R. schrieb: > Da nuss immer noch irgendwas verdreht sein, probier es mal mit dem > angehängten Test-Projekt. > Das sendet alle 100ms auf 0x1806E5F4 und spiegelt dabei die Daten einer > mit ID 0x18FF50E5 empfangenen Nachricht. wie im Bild zusehen sendet das erste Byte auch in diesem Programm einfach irgendwelche willkürlichen Daten.
Günther M schrieb: >> Das sendet alle 100ms auf 0x1806E5F4 und spiegelt dabei die Daten einer >> mit ID 0x18FF50E5 empfangenen Nachricht. hier nochmal ein kleines Video darüber dort kann man es besser sehen
Was ist das für eine Software und was für ein CAN-Interface? Ich bin jetzt extra noch mal mit der Schaufel in den Keller gegangen um das Board mit dem AT90CAN128 noch mal auszugraben. Und hier funktioniert das wie es soll. Das erste Bild ist einfach die Sende-Botschaft, das zweite Bild zeigt wie die Empfangs-Botschaft auf die Sende-Botschaft gespiegelt wird. Das ist eine proprietäre Software und das Interface ein Vector VN1630. Edit: die Forums-Software killt fast die Daten-Bytes, warum auch immer die .png überhaupt automatisch neu komprimiert werden. Dann eben noch mal als .jpg.
:
Bearbeitet durch User
Rudolph R. schrieb: > Das erste Bild ist einfach die Sende-Botschaft, das zweite Bild zeigt > wie die Empfangs-Botschaft auf die Sende-Botschaft gespiegelt wird. ersteinmal vielen vielen Dank für deine große Mühe!!! dann scheint es vielleicht wirklich einfach an der Software zu liegen, diese nennt sich CAN-Monitor mit deren CAN Interface. http://www.kmtecsoft.de/index.html ich hab im Anhang jetzt nochmal mein aktuelles Programm eingefügt und nochmal ein Video was meine Software mir gerade anzeigt, könntest du diesen code vielleicht mit deiner Software einmal auslesen? Dies würde mir enorm helfen, nochmals vielen vielen Dank!
Dein Testprogramm sendet hier gerade fröhlich vor sich hin, einmal pro Sekunde kommt da auf ID 0x1806E5F4: 01 02 03 04 00 00 00 00 Ich habe das direkt so wie das im Archiv ist compiliert und gebrannt. Auf meiner Platine ist ausser dem CAN nichts am Controller angeschlossen, da sind dann auch irgendwelche I/Os mit denen zusätzlich gewackelt wird egal. Mit 11 Bit IDs passiert sowas in der Software aber nicht? Schick denen auf jeden Fall mal einen Bug-Report. Das scheint schon etwas angestaubt zu sein, vor allem die Hardware, das wird aber wohl noch gepflegt. Die Ordner-Struktur von Deinem Testprojekt ist etwas seltsam, wo fallen solche Projekte raus?
Rudolph R. schrieb: > Dein Testprogramm sendet hier gerade fröhlich vor sich hin, einmal pro > Sekunde kommt da auf ID 0x1806E5F4: 01 02 03 04 00 00 00 00 Guten Morgen, bin heute morgen direkt einen anderes CAN Interface ausprobiert, siehe da funktioniert :) Danke die für deine ganze Mühe und Hilfe, hätte wahrscheinlich noch ewig gesucht...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.