Themen:

AVR, avr-gcc, CAN, CPLD, Elektronik, Mikrocontroller, MSP430, PIC, Roboter, Schaltungen, Sensoren, Software, Testboards

Universelle CAN Bibliothek

Tags: AVR, Software, CAN, avr-gcc
Stand: 16. Juni 2008, 15:57
86 Kommentar(e)

Motivation

Die Bibliothek ist für den Roboterclub Aachen e.V. entstanden. Vor zwei Jahren stand ein Wechsel des internen Bussystems an, die Wahl fiel dabei auf den CAN-Bus, da er eigentlich ideal für diese Anwendung ist.
Es gab nur leider keine Open-Source Bibliotheken für die Ansteuerung der gebräuchlichsten CAN-Controller, so dass selbst schreiben angesagt war.

Die Bibliothek ist jetzt seit einiger Zeit in Gebrauch und wurde dabei vom MCP2515 auf die anderen CAN-Controller erweitert.

Features

Die Bibliothek braucht ca. 1500 Byte Flash mit allen Funktionen. Verwendet man keine dynamischen Filter sind es 370 Byte weniger.

Filter

Für den MCP2515 gibt es zwei Arten die Masken und Filter anzusprechen, zum einen “statisch” mit einer Liste die zur Compile-Zeit angelegt wird oder “dynamisch” während der Laufzeit, dann aber mit größerem Flash Verbrauch.

Die AT90CANxxx kennen nur die dynamischen Filter.

Gleiches gilt für den SJA1000. Dieser bietet zwar theoretisch zwei Filter für Standard-Nachrichten bzw. einen für Extended-Nachrichten, in der Praxis sind diese aber mehr oder weniger unbrauchbar.

Einbinden ins eigene Programm

Zuerst einmal muss die Bibliothek erstellt werden: Dazu ändert man im src/-Ordner die Datei ‘config.h’ für seine Konfiguration ab und stellt im Makefile den verwenden AVR-Typ ein.

Dann kann die Bibliothek gebaut werden:

$ make lib

Wer WinAVR verwendet kann auch einfach im Programmers Notepad eine der Dateien aus dem src/-Ordner öffnen und dann “Tools > [WinAVR] Make All” auswählen.

Jetzt sollte eine Datei ‘libcan.a’ entstanden sein. Zusammen mit ‘can.h’ und ‘config.h’ können diese Dateien jetzt in das eigene Projektverzeichnis kopiert werden.

Um die Funktionen wirklich nutzten zu können muss nur noch den Linker mitgeteilt werden, dass er die Bibliothek einbinden soll. Bei dem Standard-WinAVR-Makefile muss dazu die folgende Zeile hinzugefügt werden (um Zeile 266ff):

...
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)

LDFLAGS += -L. -lcan        # hinzufügen

Der Linker sucht dann automatisch im aktuellen Verzeichnis nach der Datei libcan.a und fügt die benötigten Funktionen (und nur die) in den Quellcode ein.

Testprogram

Ein Programm was einfach eine Nachricht per CAN verschickt könnte folgendermaßen aussehen:

C:
int main(void)
{
    // initialisieren des MCP2515
    can_init(BITRATE_125_KBPS);
   
    // erzeuge eine Testnachricht
    can_t msg;
   
    msg.id = 0x123456;
    msg.flags.rtr = 0;
    msg.flags.extended = 1;
   
    msg.length = 4;
    msg.data[0] = 0xde;
    msg.data[1] = 0xad;
    msg.data[2] = 0xbe;
    msg.data[3] = 0xef;
   
    // Nachricht verschicken
    can_send_message(&msg);
   
    while (1) {
       
    }
}

In der Datei can.zip gibt es außerdem im demo-Ordner ein fertiges Programm für das CAN-Testboard, welches am Anfang eine Nachricht verschickt und danach alle Nachrichten die es empfängt mit einem um Eins vergrößertem Identifier zurückschickt.

Lizenz

Die Bibliothek steht unter der 2-Klausel-BSD-Lizenz und darf damit frei verwendet werden.

Wenn jemand Änderungen vornimmt würde ich bitten mir oder jemand anderem aus dem Roboterclub diese zukommen zu lassen, damit wir sie gegebenenfalls in die Software einbauen können, so dass dann alle etwas davon haben.

Update

2.1.08:

16.6.08:

19.8.08:

23.8.08

2.9.08

6.1.09

19.8.10

Downloads:

can-lib.zip [194.75 kB]

Zum Anfang

Kommentare

# Wolfram meinte am 21. März 2008, 18:26 dazu:

Hallo Fabian, sehr schöne CAN Lib. Funktioniert auf Anhieb mit ATMEGA 644
Grosses LOB !!! !!! !!! BEAR WARE License ist Dir sicher ;-)

# Christoph meinte am 21. März 2008, 20:03 dazu:

Ich bin begeistert!

Da ich in naher Zukunft Prozessstraßen für die Industrie entwickeln (und verkaufen) werde, die als Baukastensysteme über CAN vernetzt sind, wird mir diese Bibliothek viel Arbeit abnehmen. Wenn ich Verbesserungen habe, werde ich mich auf jeden Fall melden.

Und selbstverständlich gibt es bei den ersten verkauften Geräten eine entsprechende Spende an den Roboterclub der RWTH. Wenn ich nicht schon mehr als genug Arbeit hätte - autonome Roboter wären ein tolles Betätigungsfeld.

Nochmal ein herzliches Dankeschön für die Bibliothek und vielen Grüße aus der Eifel,
Christoph

# tuxlein meinte am 7. Juli 2008, 09:22 dazu:

Supper sache, muss man nicht alles ihmmer neu schreiben sondern nur anpassen!

Kleine anmerkung, was ich machen würde: ist die SPI Funcs auslagern.

Nice To have:

  • Unter anderm Tab durch 4 Spaces ersetzen.
  • keine Windows \r

ansonsten alles bestens nur weiter so!

# Simon meinte am 18. August 2008, 21:31 dazu:

Hi Fabian,

ich habe im Grunde den gleichen Aufbau wie beim CAN-Testboard, nur hängt noch ein Display am Controller mit dem ich die Debug-Ausgaben mache.

Sobald ich aber can_init() aufrufe (im Beispielprogramm oben) stürzt der controller ab. Alles was nach can_init() kommt wird nicht ausgeführt.

Fällt dir da auf die schnelle ein möglicher Grund ein der die can_init() evtl. in eine endlosschleife o.ä. laufen lassen könnte??

dank!

# Fabian Greif meinte am 19. August 2008, 08:51 dazu:

Das konnte passieren wenn der MCP2515 nicht ansprechbar ist. Ich habe gerade eine korrigierte Version hochgeladen in der can_init() in so einem Fall false zurückliefern sollte.

# Simon meinte am 19. August 2008, 12:33 dazu:

Danke für die schnelle Antwort! Ich habe gerade die can-lib.zip von oben runtergeladen und neu kompiliert. Am Verhalten hat sich aber nichts geändert: Er bleibt immer noch in der can_init() hängen.

Oder gibts vll. ein svn-rep von dem ich nix weiß?

# Fabian Greif meinte am 19. August 2008, 14:45 dazu:

Oder gibts vll. ein svn-rep von dem ich nix weiß?

Das gibt es zwar, ist allerdings nicht öffentlich. Die can_lib.zip von oben ist schon richtig.

Kannst du mir vielleicht mal per E-Mail deinen Code der das Problem erzeugt schicken, dann würde ich das mal bei mir ausprobieren.

Grüße Fabian

# Otmar Schmid meinte am 23. August 2008, 09:14 dazu:

Hallo Fabian
Zuerst einmal ein grosses Lob und vielen Dank für diese can-lib. Ich will den CAN-Bus als Hausbus einsetzen. Zwei kleine Punkte:
- Der Filenamen at90can_disable_dynamic_filter.c ist zu lang (> 32 Zeichen) und erzeugt bei meinem Makefile einen Fehler.
- Das Label SUPPORT_FOR_MC2515__ in mcp2515_error_register.c in Zeile 33 ist falsch geschrieben.
Nun zu meinem eigentlichen Problem:
Ich habe zwei identische Testboards mit ATmega168 und MCP2515 nachgebaut. Auf beiden läuft bis auf die Identifier das gleiche Programm. Wenn ich die Programme nacheinander starte, funktioniert alles einwandfrei. Nur wenn ich beide geichzeitig starte (simultanes Power on bei beiden), dann zeigt sich der Fehler. Der eine MCP2515 sendet fälschlicherweise Daten die er vorher empfangen hat, oder die zufällig in den Registern stehen. Natürlich wird es auf dem CAN-Bus zu kollisionen kommen. Doch damit sollte der MCP2515 umgehen können. Gibt es eine Erklärung dazu? Das ganze Projekt ist unter (...) zu finden. Ich verwende Debian testing.
Vielen Dank für die Hilfe und schöne Grüsse Otmar

# Fabian Greif meinte am 23. August 2008, 10:22 dazu:

Die Fehler hab sind korrigiert, für den Rest hab ich dir eine E-Mail geschrieben.

# Marcus meinte am 20. Oktober 2008, 18:00 dazu:

Hallo,

mir ist aufgefallen, dass wenn ich den mcp2515 mit BITRATE_250_KBPS initialisiere, dann kann ich Daten mit meinem USB PEAK Adapter nur mit einer Baudrate von 125kBit/s empfangen oder senden. Stelle ich BITRATE_500_KBPS ein, dann kann ich mit dem PEAK Adapter die Daten mit 250kBit/s empfangen oder senden. usw?
Ich habe mir natürlich die can.h entsprechend angepasst.

Aber mich würde generell interessieren warum das so ist. Der Peak Adapter ist in Ordnung und funktioniert in anderen Anwendungen ohne Probleme?

# Frank meinte am 18. November 2008, 18:59 dazu:

Hallo!
Habe kürzlich gute Erfahrungen gemacht. Kompiliert und lief. Sehr schönes Stück Software. :-) Unter Welcher BSD-Lizenz steht sie eigentlich genau. Das ist ein wenig schwammig formuliert?

# Fabian Greif meinte am 20. November 2008, 11:17 dazu:

Ganz genau steht sie unter der “2-Klausel-BSD” oder auch FreeBSD-Lizenz.

Der genaue Text steht aber auch in Quelltext.

# Adrian meinte am 15. Dezember 2008, 10:53 dazu:

Hallo Fabian,

ich habe gelesen, dass Simon am 18.und 19. August den selben Fehler mit der Libary hatte, wie ich ihn jetzt habe. Auch bei mir bleibt das Programm bei can_init in einer Endlosschleife hängen. Wäre super, wenn Du mir da auch ggf helfen könntest.

Gruß Adrian

# Alex meinte am 16. Dezember 2008, 09:59 dazu:

Hallo,

ich hab eine kleine Frage zu deiner Lib. Ich bin dabei mit 2 AT90CAN128 CAN Nachrichten zu versenden. Der eine sendet, wie im Beispiel beschrieben. Allerdings nur 15 mal. Ich nehme an dass dann der Buffer voll ist. Der zweite CAN Knoten sollte eigentlich empfangen tut er aber nicht. Ich hab hier mal mein Codeausschnitt:

if (can_check_message())
{		
can_t msg;
// Try to read the message

  if (can_get_message(&msg))
  {
				   
    uart_putc(msg.data[0]);
  }
}

Vielleicht hast du ja ein Beispiel dass Senden und Empfangen zeit.

Gruß Alex

# Fabian Greif meinte am 16. Dezember 2008, 11:39 dazu:

@Adrian
In der aktuellen Version des Code sollte das eigentlich nicht mehr vorkommen. Kannst du mir mal deinen Code zur Initialisierung des MCP2515 per E-Mail schicken? Dann würde ich mir das mal anschauen.

@Alex
Dein Code zum Empfangen ist schon vollkommen richtig. Hast du denn beim Initialisieren einen Filter gesetzt?

Zum Beispiel folgendermaßen um alle Nachrichten zu empfangen:

// Initialize AT90CAN
can_init(BITRATE_125_KBPS);

// create a new filter for receiving all messages
can_filter_t filter = {
    .id = 0,
    .mask = 0,
    .flags = {
        .rtr = 0,
        .extended = 0
    }
};

can_set_filter(0, &filter);

// enable interrupts
sei();

Ansonsten könnte das voll-laufen des Sendepuffers des AT90CAN eigentlich nur an einer fehlenden Verbindung zwischen den beiden liegen.

Grüße
Fabian

# Alex meinte am 16. Dezember 2008, 20:58 dazu:

Nein hab leider kein Filter gesetzt gehabt. Werds aber mal austesten.

# Kristof Koch meinte am 10. Februar 2009, 11:58 dazu:

Ich habe ein ähnliches Problem wie Alex. Ich kann mit meinem AT90CAN128 nur 15 Nachrichten verschicken. Diese kommen auch an. Getestet mit USB-CAN-Adapter von Peak. Er ist in Ordnung. Eine andere Platine mit ATmega8 und MCP2515 läuft fehlerfrei.

Wenn ich den AT90CAN128 ab und zu mit can_init(BITRATE_125_KBPS); neu initialisiere ? schickt der Controller auch mehr Nachrichten ? Also Hardware sollte in Ordnung sein. Habt ihr eine Idee?

grüße Kristof

# Fabian Greif meinte am 11. Februar 2009, 00:28 dazu:

Es hört sich an als würde der AT90CAN128 nicht das Acknowledge vom Bus empfangen. Überprüfe doch mal mal die RX-Leitung vom CAN Transceiver zum AT90CAN.

Grüße
Fabian

# Kristof Koch meinte am 11. Februar 2009, 10:27 dazu:

Vom RXD des Transceivers zum RXCAN pin des AT90CAN 0 Ohm

Ich könnte aber mal ausprobieren. Ob der Controller Nachrichten empfangen kann …

# Frédéric meinte am 11. Februar 2009, 19:53 dazu:

Thanks you Fabien for your library, it’s the best thing since sliced bread :)

With the library (and an ATMEGA168 and a small LCD) I made an onboard gauge for CAN enabled cars that display fuel consumption, trip data, engine info, etc.

# Bernhard Ibertsberger meinte am 24. Februar 2009, 18:07 dazu:

Hallo,

erstmal gratuliere zu deiner offenbar tollen Arbeit! Ich habe eine Frage zum AT90128:

—-snip—-

$ make lib

[..]

-DF_CPU=1500000UL

[..]

at90can_private.h:54:3: error: #error only 16MHz supported!

—-snap—-

Mein Quarz hat 12Mhz. Habe ich jetzt ein Problem, oder kann ich im File at90can.c auf Zeile 171 einfach den Teiler (jetzt 199) ändern?

Grüße

Bernhard

# Fabian Greif meinte am 24. Februar 2009, 18:51 dazu:

Mein Quarz hat 12Mhz. Habe ich jetzt ein Problem,

Problem hast du keines, außer das du die Werte selbst anpassen musst.

oder kann ich im File at90can.c auf Zeile 171 einfach den Teiler (jetzt 199) ändern?

Das wäre das Eine. Viel wichtiger sind aber die Werte ab Zeile 39 in der ‘at90can.c’. Die Werte werden in die Register CNF1..3 geschrieben und bestimmten die Bitrate für den CAN Bus.

Grüße Fabian

# Bernhard Ibertsberger meinte am 25. Februar 2009, 15:58 dazu:

Das wäre das Eine. Viel wichtiger sind aber die Werte ab Zeile 39 in der ?at90can.c?.
Die Werte werden in die Register CNF1..3 geschrieben und bestimmten die Bitrate für den CAN Bus.

Aha, ich sehe?

Was mir dabei auffällt:

  • Register CNF finde ich in der Spec nicht. Wahrscheinlich verwechselt mit CANBTx.
  • Bei dem Timing für 1Mbps sind die Werte im Code {0x00, 0x0C, 0x37}. Laut meiner Spec sollte (bei 16MHz) sein: {0x00, 0x0c, 0x36}.

Im Datenblatt steht dazu:

'SMP=1' is not compatible with BRP=0...

Das heißt wenn der erste der drei Werte (CANBT1 = SMP) gleich Null, dann darf Bit 0 von CANBT3 ( = Sample Points) nicht gesetzt sein.

Übersehe ich das was, oder sollte man das in der Library reparieren?

Grüße

Bernhard

# Bernhard Ibertsberger meinte am 26. März 2009, 17:42 dazu:

Hallo Fabian,
die CANlib verrichtet ganz wunderbar ihren Dienst. Jetzt habe ich aber das Problem eine CAN verbindung mit einem Programm in der bootloader section aufzubauen. µC ist at90can128

Ein kleines Demo (verschickt jede Sekunde ein CAN message und toggled eine LED) funktioniert in der application section.
Wenn ich aber das Programm in die bootloader section verschiebe blinkt nur mehr die LED, es kommen aber keine CAN Telegramme an.
can_send_message liefert keinen Error.

Hast du eine Idee woran das liegen könnte? Ich bin schon ein wenig Ratlos.

lg Bernhard

# Manfred meinte am 10. Mai 2009, 00:28 dazu:

Hallo
Ich habe ein seltsames Problem. Solange der Programmer (von MyAVR) am Mega angeschlossen ist funktionirt deine CAN.lib wunderbar. wenn ich den Programmer abschliese geht nichts mer.
Kannst Du mir sagen woran das liegen kann ??
Prozessor AtMega16 mit interner Frequent 8Mhz

Danke Manfred

# Uwe Dierolf meinte am 22. Mai 2009, 12:36 dazu:

Hallo Florian, ich versuche gerade dein Testpogramm, das beim “CAN-Lib” download dabei war zu compailieren. Die “libcan.a” hab ich mit WIN-AVR erstellt und wie im Tutorium beschrieben in den Projektordner eingefügt. Jetzt versuch ich, da ich eigentlich nicht mit WIN-AVR Arbeite, mit AVR-Studio das Testprogramm zu compeilieren.

Er erkennt die Lib, da er wenn ich sie rausnehme meldet dass er die Funktionen nicht finden. aber wenn ich sie drin hab bekomme ich folgene Fehlermeldung. ” avr-gcc -mmcu=atmega32 -Wl,-Map=CAN_DEMO2.map CAN_DEMO2.o -lcan -o CAN_DEMO2.elf c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: cannot find -lcan make: *** [CAN_DEMO2.elf] Error 1 Build failed with 1 errors and 0 warnings… ” Leider weiss ich nicht was er mit “cannot find -lcan”
meint, da ich mit, aus mehreren Files zusammengestellten libs keine Erfahrungen hab.

Vielen Dank schon mal im Voraus MFG Uwe

# Fabian Greif meinte am 27. Mai 2009, 18:54 dazu:

cannot find -lcan

das bedeutet das der Linker die Datei libcan.a nicht finden kann. Liegt sie den in dem Verzeichnis des Makefiles?

# Uwe meinte am 28. Mai 2009, 21:51 dazu:

Hallo,
ja sie ist im selben wie im Makefile. Ich hab jetzt meine "main" in main umbenannt, was in AVR-Studio ja nicht von Haus aus so ist. Er bringt aber immer noch einen Fehler beim erstellen der Debugg-Datei was glaube ich mit "CAN_DEBUG_LEVEL" in can_private.h zusammenhängt. Code läuft jetzt, SPI und LCD, nur CAN, kann noch nicht so ;-)
Ich hab jetzt mal Alles gedruckt und kau es übers Wochenende durch, dann sehe ich villeicht klarer.

MFG
Uwe

# Fabian Greif meinte am 29. Mai 2009, 01:16 dazu:

Er bringt aber immer noch einen Fehler beim erstellen der Debugg-Datei

Was gibt es den genau für eine Fehlermeldung?

# Uwe meinte am 30. Mai 2009, 16:09 dazu:

Jetzt hab ich meine Startprobleme überwunden, und wie immer ist es nichts Weltbewegendes,sonder was das man mit etwas ruhigem Nachdenken lösen kann. Wenn ich nur immer ruhig bleiben könnte :-(

  1. Er hat die Lib. nicht gefunden, da ich im "library Search Path" nichts eingegeben hab, es muss aber immer was drin stehen, wenn auch nur ein "./"

  2. Das mit der Debugg Datei war ein Namensfehler, da ich Deine Datei in Meinem anders benannten Projekt hatte.

Ich hätte AVR-Sudio villeicht erst updaten sollen, wenn die Lib. gelaufen wär. Zuviel Neues auf einmal geht meistens einfach schief.

Besten Dank noch mal für Alles.

jetzt mach ich mich an die Lösung des Eigentlichen Problems. MFG Uwe

# Simon meinte am 21. Juni 2009, 12:21 dazu:

Hi Fabian,

im Beispiel oben ist ein Fehler drin.

Wahrscheinlich hast du irgendwann tCAN in can_t umbenannt und oben nicht nachgezogen.

Da heißt es noch "tCAN msg;" müsste aber wohl "can_t msg;" sein.

Grüße Simon

# Fabian Greif meinte am 21. Juni 2009, 12:57 dazu:

Stimmt, das hatte ich mal geändert. Vielen Dank für den Hinweis, ist korrigiert.

Grüße Fabian

# Simon meinte am 21. Juni 2009, 21:58 dazu:

Sooo. Ich habe (mal wieder) das Problem dass er bei can_init() hängen bleibt^^

Habe mich jetzt mal dran gemacht die genaue Stelle herauszufinden (per LED mangels ICD für Atmels). Hier das Ergebnis: Er schmiert in der Funktion uint8_t spi_putc(uint8_t data) in spi.c ab bzw. bleibt in der folgenden schleife hängen:

while( !( SPSR & (1rrSPIF) ) )
         ;

(bei rr links shift denken - sonst beendet er der die ganze nachricht)

Allerdings nicht beim ersten aufruf von putc sondern wenn es in bool mcp2515_init(uint8_t bitrate) bei

RESET(MCP2515_CS);
spi_putc(SPI_WRITE);

aufgerufen wird. Also nach dem reset des MCP2515.

Irgendeine Idee warum das genau in der Schleife passiert? Die Beschaltung habe ich schon hundertmal überprüft.

Achja controller ist ein Atmega88 mit 8Mhz (interner Quarz).

# Fabian Greif meinte am 22. Juni 2009, 18:18 dazu:

Irgendeine Idee warum das genau in der Schleife passiert? Die Beschaltung habe ich schon hundertmal überprüft.

Nein, so spontan nicht. Es scheint so als würde die SPI Übertragung nicht richtig gestartet.

Kannst du mal versuchen ohne die canlib Daten per SPI zu übertragen und schauen ob er da auch beim zweiten Aufruf hängen bleibt?

Grüße Fabian

# Thomas R. meinte am 23. Juni 2009, 08:21 dazu:

Hallo,

die Jungs in diesem Thread haben schwierigkeiten mit der lib: http://www.mikrocontroller.net/topic/141667#1308894

Vielleicht könntest Du ihen weiterhelfen.

Grüße Thomas

# Fabian Greif meinte am 28. Juni 2009, 09:47 dazu:

Sooo. Ich habe (mal wieder) das Problem dass er bei can_init() hängen bleibt^^

Ich habe mir das nochmal genauer angeschaut, das Problem tritt eigentlich nur auf wenn man die Bibliothek für einen AVR kompiliert und dann einen anderen verwendet. Zwischen den verschieden AVRs verschieben sich nämlich auch die Registeradressen, dann wird dann darauf gewartet das sich ein Bit in einem vollkommen falschen Register setzt.

Schau mal nach nach ob die Einstellungen für dein Projekt und die für das Erzeugen der Bibliothek übereinstimmen.

Grüße Fabian

# Simon meinte am 30. Juni 2009, 13:59 dazu:

damisch natürlich - genau das Problem das ich damals auch hatte (wie mir natürlich erst jetzt wieder einfällt). Vielen dank Fabian dass du dich da nochmal drum gekümmert hast - ich bin jetzt seit Tagen dabei SPI Kommunikation zu sniffen und mit timings rumzuspielen.

Natürlich isses immer die einfachste Lösung, ich habe im makefile der library einfach den controllertyp nicht eingstellt.

Dass das anderen nicht auch passiert wäre es evtl. nicht schlecht das in der nächsten Version ins Readme aufzunehmen.

# CTruller meinte am 11. Juli 2009, 14:16 dazu:

Hallo Fabian,

ich möchte mich Deinen ersten Schreiber anschliessen und ein großes Lob aussprechen, einfach tolles Lib. Ich setze sie schon mehrfach mit großen Erfolg auf dem AT90CAN128 ein. Meine selbst kreierte Routine zum CAN-Bus hatte Macken, desshalb bin ich froh ein so gut funktionierende Lib gefunden zu haben.

Leider kommt jetzt doch ein ABER, ich wollte die Libcan.a auch im Bootloader einsetzen, weil meine Routine eben Macken hat, das ging solange gut wie mein Bootloader nicht im Flashspeicher ab 0x1E000 (bzw. im AVR-Studio 0xF000) laufen sollte, der Fehler ist reproduzierbar. Es kommen nur Fehlerdatentelegramme raus, beim Flashspeicher ab 0x0000 läuft das Programm wunderbar, richtige Datentelegramme. Ich habe schon gedebuggt, aber nichts aufälliges gefunden die Register vom CAN-Kontroller sind (so weit der Debugger (mit Eclipse) nicht lügt und ich das Richtige sehe) mit gleichen Daten gefüllt und ich habe alle Register mir direkt anzeigen lassen. Ich mach jetzt schon 3 Tage damit rum.

Es währe wirklich Super wenn Du einen Tip geben könntest.

Gruß CTruller

# CTruller meinte am 13. Juli 2009, 14:56 dazu:

Hallo Fabian,

nun ich hab, da die Zeit drängt, ein bisschen weiter gesucht und konnte feststellen das dieser Fehler (oben beschrieben am 11.Juli 2009) aus der Ecke der CAN-Baudrate kam, spricht die CANBT1-3 Register wurden mit 0xFF beschrieben obwohl das Array at90can_cnf eigendlich richtig vorhanden war und wie schon erwähnt das ganze wunderbar im Flash-bereich ab 0x0000 funktionierte. Nun nach einigen Googeln kam ich drauf. In Deiner Datei at90can.c holst Du mit dem Befehl pgm_read_byte() die Daten aus dem Flashspeicher, dieser Befehl arbeitet aber nur mit einem 16Bit Zeiger, sprich nur bis 0xFFFF. Wird aber Deine Libcan.a für einen Bootloader und das gilt nur für den at90can128 nicht für die at90can32 + can64, verwendet landet Dein Array at90can_cnf auf einer Adresse von ca. 0x1E094. Diese kann aber die Routine ?pgm_read_byte()? nicht erreichen da sie nur im 64K-Bereich arbeitet. Lösung für den at90can128: -> verwenden statt der Routine pgm_read_byte() die Routine pgm_read_byte_far() die auch 32Bit Adressen verarbeitet. Aber das ist noch nicht alles.

Erst mal eine 32Bit Adresse habe, denn der Aufruf ?&(var)? liefert maximal eine Adresse bis 0xFFFF (64K) zurück, da der AVR nur ein 16Bit Register für den Adresspointer hat, sprich im oben genannten Fall kommt bestenfalls 0xE094 zurück. Momentan habe ich mich mit einen define NO_BOOTBEREICH beholfen und für den Aufruf der pgm_read_byte_far(Adr) Funktion im Bereich ab 0x1E000 zum zurückgegebenen Wert die 0x10000UL dazu addiert und sonst eben nicht. Das funktioniert, ist nicht schön aber vielleicht hast Du noch einen besseren Vorschlag.

Gruß CTruller

# Fabian Greif meinte am 20. Juli 2009, 18:46 dazu:

Das funktioniert, ist nicht schön aber vielleicht hast Du noch einen besseren Vorschlag.

Nicht so wirklich. Die einzige andere Möglichkeit die mir noch einfällt wäre die Tabelle zu deaktivieren und die Registerwerte direkt zu setzen. Wenn ich wieder Zeit habe werde ich das mal einbauen.

Grüße Fabian

# Artur meinte am 23. Juli 2009, 15:50 dazu:

Hallo Fabian, ich mache zur Zeit eine projektarbeit und wollte dort Deine Lib einsetzen. Ich habe mein Programm so weit geschrieben doch leider bekomme ich keine Nachrichten auf den Bus… Ich verwende eine AT90can128 Controller.

can_t geschwindigkeit, licht;

can_init(BITRATE_500_KBPS);

geschwindigkeit.id = 0xcfe6cee;
geschwindigkeit.flags.rtr = 0;
geschwindigkeit.flags.extended = 1;
geschwindigkeit.length = 8;
geschwindigkeit.data[0] = 0;
geschwindigkeit.data[1] = 0;
geschwindigkeit.data[2] = 0;
geschwindigkeit.data[3] = 0xC0;
geschwindigkeit.data[4] = 0;
geschwindigkeit.data[5] = 0;
geschwindigkeit.data[6] = 0;
geschwindigkeit.data[7] = 60;

licht.id = 0x14b;
licht.flags.rtr = 0;
licht.flags.extended = 0;
licht.length = 1;
licht.data[0] = 2;


blinkLED();
_delay_ms(5000);

while(1)
{
    can_send_message(&licht);

    can_send_message(&geschwindigkeit);

    blinkLED();
    _delay_ms(zeitverzoegerung);
}

Hab ich da etwas übersehen in meinem Programm???

Vielen Dank für die Hilfe im Vorraus

Gruß

Artur

# Fabian Greif meinte am 27. Juli 2009, 16:44 dazu:

Hast du die Interrupts aktiviert?

Setzt mal ein sei() nach die Initialisierung des CAN Controllers.

Grüße Fabian

# Jens meinte am 2. August 2009, 17:38 dazu:

Hallo!
Schon mal vielen Dank für die hilfreichen Ausführungen. Wie sollte es aber auch anders sein: auch ich habe ein kleines Problem.
Ich arbeite mit avr-gcc (GCC) 3.4.6
Zum einen Versuche ich das ganze auf einem ATmega644 laufen zu lassen. Nachdem ich alle SPI-Register um eine ?0? ergänzt habe, klappt schon mal das compilieren, auch wenn ich alle Naselang ein warning ausgespuckt bekomme:
spi.h:74: warning: 'gnu_inline' attribute directive ignored
usw.

Im eigenen Code klappt wohl auch das Senden, aber nicht das empfangen. Ich bekomme auch dieses warning:
can.h:229: warning: type of bit-fieldrtr? is a GCC extension
can.h:230: warning: type of bit-field extended' is a GCC extension

Die dortige Syntax ist mir leider auch völlig unbekannt. Was bedeutet
uint8_t rtr : 2;

Kann es sein, daß ich deswegen nichts empfange? Danke!

# Fabian Greif meinte am 4. August 2009, 10:17 dazu:

spi.h:74: warning: ‘gnu_inline’ attribute directive ignored

Scheinbar kennt diese Version des GCCs __attribute__((gnu_inline)) noch nicht. Du solltest es durch static inline ersetzen können.

Die dortige Syntax ist mir leider auch völlig unbekannt. Was bedeutet uint8_t rtr : 2;

Das legt ein Bitfeld an, wobei rtr zwei Bit groß ist. Versuch mal das uint8_t durch int zu ersetzen.

Sag Bescheid ob es damit klappt.

Grüße Fabian

# Alex meinte am 4. August 2009, 10:20 dazu:

Hallo,

ich möchte gern ein Filter zum empfangen von nur einer bestimmten Botschaft definieren. Bin aber aus der Doku micht schlau geworden. Ich benutze den AT90CAN.

// create a new filter for receiving all messages

can_filter_t filter = {
    .id = 0x100,
    .mask = 0,
    .flags = {
        .rtr = 0,
        .extended = 0
    }
};

can_set_filter(0, &filter);

Was bedeutet hier mask?

Viele Grüße

# Fabian Greif meinte am 4. August 2009, 10:35 dazu:

Was bedeutet hier mask?

mask gibt an welche Bits von id zur Filterung der Nachricht herangezogen werden.

Mit mask = 0 werden alle Nachrichten empfangen, unabhängig von id. Mit mask = 1 werden alle Nachrichten empfangen bei denen das niederwertigste Bit mit dem Bit aus id übereinstimmt. Mit mask = 0x7ff werden bei Standard-Frames alle Bits von id überprüft usw.

Siehe auch Filter bei MCP2515.

# Jens meinte am 4. August 2009, 14:13 dazu:

Danke, das half alles schon mal, um fehlerfrei zu compilieren. Es ist zwar noch
static inline void spi_start(uint8_t data)
static inline uint8_t spi_wait(void)

doppelt drin gewesen, aber das habe ich einfach einmal auskommentiert. Senden klappt weiterhin, nur empfange ich immer noch nichts. Muss also irgendwo an mir liegen. Werde weiter suchen. Ich tippe ja irgendwie auf die Masken…

# maxf meinte am 17. August 2009, 17:44 dazu:

Hallo Fabian,

ich habe ein kleines Problem mit der Library. Ich benutze den MCP2515 an einem ATMega8. Aus irgendeinem Grund kann ich im normalen Modus (mit oder ohne Busteilnehmer) nur genau 3 Nachrichten verschicken. Im Loopback-Modus tritt dieses Problem nicht auf. Hast du eine Idee, wie das kommt? Wenn das Senden fehlschlägt, gibt die Methode can_send_message () 0 zurück, und auch die CAN_INDICATE_TX_TRAFFIC_FUNCTION wird nicht mehr ausgeführt…

# Fabian Greif meinte am 18. August 2009, 15:29 dazu:

Hallo maxf,

dein MCP2515 bekommt von den anderen Busteilnehmern kein ACK zurück, somit kann er die Nachrichten nicht verschicken und die Puffer bleiben belegt. Da er genau drei Puffer hat kannst du auch so viele Nachrichten “verschicken” bis das auffällt. Wenn du dir die Fehlerregister anschaust sollte der TX-Fehlerzähler auf 255 stehen und der MCP2515 im Bus-Off-Modus sein.

Überprüfe mal ob die Anbindung an den Bus korrekt ist und du die richtige Bitrate eingestellt hast.

Grüße Fabian

# Nik meinte am 20. August 2009, 10:40 dazu:

Ich verwende den AT90CAN128, das Demo-Programm sendet, aber scheint nichts zu empfangen, zu mindest anwortet es nicht durch zurücksenden der Message mit anderer ID. WOran kann das liegen ?

# maxf meinte am 20. August 2009, 15:03 dazu:

Stimmt, wenn ich einen zweiten mega8 mit mcp2515 und deinem Bootlader dranhänge, kann ich über meinen einfachen Adapter (der war das Problemkind) von der Linux-Kiste aus via Socketcan senden. Jetzt muss ich nur noch herausfinden, warum der Mega8 schon nach einem Datenblock direkt einen Fehler sendet… ;)

# CTruller meinte am 24. September 2009, 11:47 dazu:

Hallo Fabian,

sorry, das ich die Frage über den RCA direkt an Dich schon mal gemailt habe. Wie schon am 11. und 13. Juli 2009 geschrieben setzen wir Deine Lib erfolgreich ein. Ich vermute mal das die nachfolgende Anfrage kein Fehler der Lib ist aber vielleicht hast Du oder jemand anderes einen Tip wie man ihn beheben kann. Beim verwenden der Funktion can_set_filter und can_disable_filter kommt es zu Errorframes auf dem CAN-Bus (Baudrate 250), wenn der CAN-Kontroller bereits gearbeitet hat, also anders gesagt, es kommt nicht dazu wenn can_set_filter gleich nach can_init aufgerufen wird. Auslöse Zeile ist in der Datei at90can_private.h in der Funktion _enter_standby_mode die Zeile 113 ?CANGCON=(1 kleinerals kleinerals ABRQ)?. Ab dieser Zeile kommtes bis zur Zeile in gleicher Datei bei der Funktion _leave_standby_mode Zeile 147 ?CANGCON=(1 kleinerals kleinerals ENASTB);? entsprechend der Durchlaufzeit von einem bis im Debughalt zu was weiß ich wie viele. Ich tippe mal auf ein Hardwareproblem, den wieso sendet der CAN-Kontroller weiter im Debughalt (ermittelt mit dem Canalyzer von Vector). Ich währe für jeden Tip dankbar, denn momentan kann ich die Funktion can_disable_filter nicht verwenden.

Danke schon mal im Voraus CTruller

# Marcel meinte am 3. Oktober 2009, 13:35 dazu:

Hallo Fabian,

ich benutze AVRStudio und bekomme ständig diesen Fehler:

c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: cannot find -l2srclibcan

Ich habe bei ?Configuration Options? im AVRstudio genau angegebnen, wo die lib ist, trotzdem funktioniert es nicht. Woran kanns liegen?

VG, Marcel

# Fabian Greif meinte am 7. Oktober 2009, 15:35 dazu:

Hallo Marcel,

Es muss -lcan heißen, unabhängig davon wo die Bibliothek liegt. Das gibt man über die Option -Lpfad/zur/bibliothek/ an. Wie man das genau im AVR Studio einstellen muss kann ich dir leider nicht sagen, da ich es selbst nicht verwende.

Grüße Fabian

# gaffa meinte am 26. Oktober 2009, 18:17 dazu:

Im Studio kann man unter Bibliotheken/Libraries in der Project Configuration hinzufügen. Ich habe folgende Probleme: ich habe zwei Boards die über CAN kommunizieren sollen. Das eine soll zwischen Rechner und Bus hängen (CAN2RS232) und das andere hat ein Display. Ich kann mir also alles schön zum debuggen ausgeben lassen. Nun machen beide das gleiche. can_init liefert true zurück. can_send_message liefert drei mal true und danach false (ich schicke einfach im Sekundentakt Nachrichten auf den Bus). Und zwar bei beiden. can_check_message liefert immer false. Verbunden sind beide Boards mit etwa 50cm Kabel. Bei beiden Boards ist ein 120 Ohm Abschlusswiderstand installiert. Ist irgendwo verständlich dokumentiert, wie das mit den Filtern läuft? Kann das der Grund sein, warum die Kommunikation nicht klappt? Bekommt nicht jeder Busteilnehmer seine eigene ID? Wo setzt man die? Ich bin noch etwas verwirrt?

# Fabian Greif meinte am 27. Oktober 2009, 11:49 dazu:

can_send_message liefert drei mal true und danach false

Das bedeutet das die beiden Boards nicht miteinander kommunizieren können. Überprüf noch mal sämtliche Leitungen und die CAN Transceiver.

Wenn du die Fehlerregister ausliest solltest du auch sehen können das keine Kommunikation zustande kommt.

Ist irgendwo verständlich dokumentiert, wie das mit den Filtern läuft?

Im Datenblatt des MCP2515 findet sich einiges.

Kann das der Grund sein, warum die Kommunikation nicht klappt?

Nein. Auch ohne Filter sollten sich Nachrichten verschicken lassen.

Bekommt nicht jeder Busteilnehmer seine eigene ID? Wo setzt man die?

Nein, dafür ist der Programmierer verantwortlich. CAN kennt nur Nachrichten mit Identifiern, wie diese belegt werden ist nicht festgelegt. Das spezifizieren dann weitere Protokoll die auf CAN aufsetzen. Da kannst du dir ein schönes aussuchen oder dir selbst was ausdenken.

Grüße Fabian

# Jens meinte am 9. November 2009, 10:09 dazu:

Hallo

Was mache ich falsch, wenn ich nur 8 Bytes als Antwort geliefert bekomme, die Antwort CAN Message aber mehr enthält? Ich sende eine 8 Byte Nachricht, habe aber in der can.h uint8_t data[25]; eingestellt.

Danke für die Hilfe.

# Fabian Greif meinte am 9. November 2009, 12:10 dazu:

Hallo Jens,

Was mache ich falsch, wenn ich nur 8 Bytes als Antwort geliefert bekomme, die Antwort CAN Message aber mehr enthält?

Du hast eine wichtige Einschränkung des CAN Protokolls nicht beachtet, nämlich das eine Nachricht maximal 8 Bytes an Nutzdaten enthalten kann.

Daher ist es vollkommen egal was du in der Software einstellst, der CAN Controller wird dir nicht erlauben mehr als 8 Bytes in einer Nachricht zu übertragen.

Grüße Fabian

# Lukas meinte am 12. November 2009, 15:09 dazu:

Hallo Fabian,
erst einmal herzlichen Dank für dies tolle Bibliothek! Ich habe nur leider folgendes Problem mit meinem AT90CAN: Er sendet schön brav bei 125kbps periodisch eine Nachricht nur ist DLC immer Null und die Nachricht enthält keine Daten. Die Daten sollten die gleichen sein, wie in deinem Testprogramm, das du zur Lib beigefügt hast.

Hast du vielleicht eine Idee woran das liegen könnte?
Danke für jede Hilfe.

# Georg meinte am 16. November 2009, 13:58 dazu:

Hallo Fabian, ich habe ein Problem und zwar habe ich ein CAN-Netzwerk mit insgesamt 8 Teilnehmern, davon 7 mit den mcp2515 und 1 atcan128. Jetzt habe ich aber das Problem, dass mir der MCP die Daten, die vom atcan128 gesendet werden, zwar empfängt, jedoch nicht löscht. Da muss ich danach die Daten wieder senden, damit ich überhaupt neue Daten empfangen kann. Meine Routine zum Empfangen: can_get_message;

v= (msg.data[0]-34)/3;

vor= msg.data[1];

zur= msg.data[2];

can_send_message(&msg);

Ich habe die ID in einem Empfangspuffer genau so konfiguriert, dass nur dieser 1 die Daten empfängt. Dieser Puffer soll aber jede neue Datei die mit dieser IP gesendet wird empfangen und die alte löschen. Gibt es eine bessere Möglichkeit um die Daten aus dem Empfangspuffer zu löschen als die Datei einfach wieder zu senden?

Schon mal vielen Dank!

# Fabian Greif meinte am 16. November 2009, 17:58 dazu:

Hallo Georg,

Jetzt habe ich aber das Problem, dass mir der MCP die Daten, die vom atcan128 gesendet werden, zwar empfängt, jedoch nicht löscht. Da muss ich danach die Daten wieder senden, damit ich überhaupt neue Daten empfangen kann

Das habe ich nicht verstanden. Welche Daten willst du löschen?

Wenn du per can_get_message() eine Nachricht ließt wird sie aus dem internen Empfangspuffer des MCP2515 gelöscht und ins RAM kopiert. Oder was meintest du? Das senden von Nachrichten ist davon vollkommen unabhängig.

Grüße Fabian

# Jens meinte am 18. November 2009, 08:43 dazu:

Leider hatte ich bei http://www.mikrocontroller.net/topic/157019#1484234 keine Antwort bekommen, also doch noch mal hier.

Ich nutze die CAN Bibliothek

Alle Nachrichten empfangen klappt auch.

Was ich irgendwie gar nicht kapiere ist, wie ich nur Nachrichten mit bestimmten IDs empfangen kann. Kann mir jemand ein Beispiel für zwei zugelassene IDs erstellen? Ggf. einmal für 11 und einmal für 29 Bit?

Danke.

# Fabian Greif meinte am 18. November 2009, 10:51 dazu:

Die Idee bei den Filtern und Masken ist folgende: Es wird überprüft ob alle Bits die in der Maske gesetzt sind bei der ankommenden Nachricht und dem Filter übereinstimmen. Ist das der Fall wird die Nachricht akzeptiert, wenn nicht wird sie verworfen.

Willst du also nur zwei unterschiedliche IDs empfangen solltest du alle Bits der Maske auf 1 setzten und im Filter die Gewünschte ID eintragen. Dann werden nur Nachrichten mit genau dieser ID durchgelassen.

Mit welchen CAN Controller arbeitest du denn?

Grüße Fabian

# Jens meinte am 19. November 2009, 09:14 dazu:

Ich arbeite mir dem MCP2515

# Jens meinte am 20. November 2009, 11:29 dazu:

Tja, ich stelle mich irgendwie zu dämlich an. Egal, was ich mache, es werden immer alle Botschaften empfangen. Kannst Du mir einen Codeausschnitt geben? Oder muß ich beim compilieren der library was einstellen?
Danke

# Fabian Greif meinte am 20. November 2009, 13:10 dazu:

Hallo Jens,

Oder muß ich beim compilieren der library was einstellen?

Nein, nichts was mit den Filtern zu tun.

Angenommen du willst nur Standard-Nachrichten mit den Identifiern 0x123 und 0x456 empfangen. Dann kann man die Filter zum Beispiel folgendermaßen einstellen:

prog_uint8_t can_filter[] = 
{
    // Group 0
    MCP2515_FILTER(0x123),  // Filter 0
    MCP2515_FILTER(0x123),  // Filter 1

    // Group 1
    MCP2515_FILTER(0x456),  // Filter 2
    MCP2515_FILTER(0x456),  // Filter 3
    MCP2515_FILTER(0x456),  // Filter 4
    MCP2515_FILTER(0x456),  // Filter 5

    MCP2515_FILTER(0x7FF),  // Mask 0 (for group 0)
    MCP2515_FILTER(0x7FF),  // Mask 1 (for group 1)
};
...
can_static_filter(can_filter);

Jetzt empfängt das erste Register nur die Identifier 0x123 und das zweite nur 0x456. Will man mit beiden Registern beide Identifier empfangen muss es folgendermaßen aussehen:

prog_uint8_t can_filter[] = 
{
    // Group 0
    MCP2515_FILTER(0x123),  // Filter 0
    MCP2515_FILTER(0x456),  // Filter 1

    // Group 1
    MCP2515_FILTER(0x123),  // Filter 2
    MCP2515_FILTER(0x123),  // Filter 3
    MCP2515_FILTER(0x456),  // Filter 4
    MCP2515_FILTER(0x456),  // Filter 5

    MCP2515_FILTER(0x7FF),  // Mask 0 (for group 0)
    MCP2515_FILTER(0x7FF),  // Mask 1 (for group 1)
};
...
can_static_filter(can_filter);

Beide Varianten sollten aber wirklich nur die beiden Identifier durchlassen und keine anderen.

Für Extended-Nachrichten musst du einfach MCP2515_FILTER durch MCP2515_FILTER_EXTENDED ersetzten und die Werte entsprechend anpassen.

Grüße Fabian

# Georg meinte am 27. November 2009, 10:31 dazu:

Hallo, ich weis auch nicht was da genau falsch ist, ich habe nur das Problem, dass ich nur mit dem befehl can_get_message; oft die Daten nicht empfange, obwohl ich die Filter richtig eingestellt habe. Erst wenn ich nach den can_get_message; wieder ein can_send_message; schreibe, empfängt der Controller wieder neue Nachrichten. Somit habe ich mir gedacht, dass der MCP-Controller die alten Daten aus den Puffern nicht löscht. Zur Sicherheit nochmal meine Filter:

prog_char can_filter[] = 
{
	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 0
	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 1

	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 2
	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 3
	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 4
	MCP2515_FILTER_EXTENDED(0x12345678),	// Filter 5
	
	MCP2515_FILTER_EXTENDED(0x1fffffff),	// Maske 0
	MCP2515_FILTER_EXTENDED(0x1fffffff),	// Maske 1
};

Ich möchte nur 1 Datei empfangen. Ich habe dann auch noch das Problem, dass ich 7 Can Controller habe, und alle unterschiedliche Nachrichten empfangen sollen. Das funktioniert aber nicht bei allen, wobei aber alle denselben Controller haben und den selben Programmcode mit unterschiedlichen ID?s.

Hat es vielleicht damit zu tun, dass ich die Interrupts des MCP?s ausgeschaltet habe und immer selber nach 10ms den Controller auslese (muss ich machen, da ich schon sonst zu viele Interrupts habe)?

Vielen Dank schon mal für die Hilfe !

# Frank meinte am 15. Januar 2010, 23:13 dazu:

Hallo, ich versuche gerade die Lib auf einen ATmega644 20PU zum laufen zu bringen. Nur leider bekomme ich folgende Fehlermeldung: spi.h: In function ‘spi_start’: spi.h:75: error: ‘SPDR’ undeclared (first use in this function) spi.h:75: error: (Each undeclared identifier is reported only once spi.h:75: error: for each function it appears in.) spi.h: At top level: spi.h:78: warning: ‘gnu_inline’ attribute directive ignored spi.h: In function ‘spi_wait’: spi.h:80: error: ‘SPSR’ undeclared (first use in this function) spi.h:80: error: ‘SPIF’ undeclared (first use in this function) spi.h:83: error: ‘SPDR’ undeclared (first use in this function) In file included from mcp2515.c:50: mcp2515_private.h: At top level: mcp2515_private.h:144: warning: ‘gnu_inline’ attribute directive ignored make.exe: *** [build/mcp2515.o] Error 1

Woran kann das liegen? Gruss Frank

# Fabian Greif meinte am 16. Januar 2010, 22:49 dazu:

Kann es sein das du eine ältere WinAVR Version verwendest? Generell läuft die Bibliothek ohne Probleme auf einem ATMega644, selbst schon häufiger getestet.

Grüße Fabian

# Frank meinte am 17. Januar 2010, 17:35 dazu:

Hallo Fabian,

danke!!! Daran hat es gelegen! Gruss Frank

# Helmut Mahr meinte am 30. Januar 2010, 11:02 dazu:

MCP2515/SAJ1000/AT90CAN Wenn man ganz am Anfang vor der Frage steht: “Was soll ich davon nehmen?”, gibts da eine Info, die Vor- und Nachteile der einzelnen Lösungen auflistet? Oder kann man das in ein paar Sätzen sagen? Nicht immer wird man einen AT90CAN einsetzen. Dann kommen noch die beiden anderen Lösungen in Frage. Was sind die Stärken und Nachteile jeweils?

# Carsten Komnik meinte am 10. Februar 2010, 14:59 dazu:

Hallo Fabian.
Nachdem ich es schon fast aufgegeben hatte, klappt der Empfang von CAN-Nachrichten mit deiner lib nun auch auf meinem AT90CAN128.
Problem war die fehlende Initialisierung des Filters wie unter deiner Antwort vom 16.12.2008 beschrieben.
Vielen Dank!
Nun muss ich nur noch den Hänger nach 15x Nachrichten senden lösen :-)

# Carsten Komnik meinte am 11. Februar 2010, 13:51 dazu:

Hi, der Hänger nach 15x gesendeten Botschaften ist nun ebenfalls weg.
Auch hier: nachdem ich im “sendenden” AT90CAN ebenfalls Interrupts aktiviert und den Filter initialisiert habe, läuft alles perfekt.

# Martin meinte am 8. März 2010, 16:27 dazu:

Hallo Fabian, Vielen dank für diese tolle Lib. Alles funktioniert einwandfrei, ob AT90CAN oder mit der spi Variante. SUPER!!! Nur schade, dass du das es keinen CAN-Bootloader für den AT90CAN gibt.

# Wolfram meinte am 16. Mai 2010, 12:18 dazu:

Hallo Fabian, ich verwende Deine Lib jetzt schon recht lange und sie funktioniert auch sehr gut. Jetzt habe ich eine Anwendung wo ich 2 CAN Busse parallel betreiben möchte. Ich denke mal dazu brauch ich erstmal zwei CAN Controller 8 aber wie kann ich die denn dann ansprechen. Du verwendest ja einen int Eingang am ATMEGA. Muss ich das quasi “zu Fuss” programmieren per separatem Port-Bit ? Gruß wolfram

# Fabian Greif meinte am 16. Mai 2010, 15:43 dazu:

Hallo Wolfram.

Zwei CAN Controller parallel ist mit der Bibliothek in der jetzigen Form noch nicht vorgesehen. Du müssest also wirklich die MCP-Funktionen kopieren, neu benennen und dann für den zweiten CAN Controller verwenden. Anders geht es im Moment leider nicht.

Erst mit der nächsten Version der Bibliothek (die dann in C++ geschrieben sein wird) wird das funktionieren. Allerdings ist diese noch nicht wirklich fertig und daher noch nicht öffentlich verfügbar.

Grüße Fabian

# Andi meinte am 26. Mai 2010, 14:36 dazu:

Hallo Fabian, ich benutze das AVR-Studio. Könntest du vielleicht nocheinmal genauer beschreiben wie man die Bibliothek erstellt und dann auch nutzen kann. Ich bekomme vom Compiler immer die Fehlermeldung “c:/winavr-20080610/bin/../lib/gcc/avr/4.3.0/../../../../avr/bin/ld.exe: cannot find -lcan”

Vielen Dank im Vorraus das wär echt dufte :) !!

Andi

PS: Echt tolle Arbeit! ^^

# Thorsten Krell meinte am 7. Juni 2010, 15:18 dazu:

Was muss ich eigentlich für eine Frequenz im Makefile einstellen, wenn ich den MCP2515 mit 8MHz betreibe und meinen ATMega128 mit 16MHz?

# Fabian Greif meinte am 8. Juni 2010, 15:21 dazu:

@Thorsten
Die Bibliothek funktioniert in ihrer jetzigen Form nicht mit einem 8 MHz Quarz für den MCP2515. Damit es klappt müsstest du die Tabelle mit den Werten für die Konfigurationsregister CNF1-3 anpassen.

Alternativ könnte man als schnellen Hack immer die doppelte Geschwindigkeit anstelle der eigentlich gewünschten auswählen. Wenn ich das richtig in Erinnerung habe, dann sollte das auch funktionieren.

Grüße Fabian

# Smon meinte am 20. Juni 2010, 17:59 dazu:

Grüße Fabian. Ich nutze derzeit deine Biliothek für ein kleines Hausbussystem an unserer Uni und ich bin auch schon recht weit gekommen. Bislang habe ich den Atmega8 verwendet aber nun stoße ich speichertechnisch an seine Grenzen und will deswegen auf den Atmege644 umsteigen und genau da liegt das Problem.

Die Initialisierung des CAN-Busses funktioniert nicht. Er liefert nicht nur ein “False” zurück, der Controller hängt sich komplett auf. Ich habe im Makefile für die MCU den Atemag644 angegeben. Das Aufspielen der Software ist kein Problem und auch andere Programme gehen tadellos. Ich habe auch das SPI-Interface selbst initialisiert (war beim Atmega8 nicht nötig), ohne Erfolg. Gibt es noch irgendwelche Einstellungen die ich vergessen/übersehen habe? Grüße, Simon

PS: Meine Schaltung ist richtig aufgebaut, habs auf dem Steckboard nun bestimmt schon 20 mal überprüft ;)

# Stefan meinte am 10. August 2010, 12:08 dazu:

Hallo Fabian,

habe dein Projekt schon erfolgreich mit einem MCP2515 und einem ATMega8 genutzt. Jetzt habe ich auf einen ATMega328PA umgesattelt und konnte soweit alles zum Laufen bringen. Allerdings musste ich dazu die MCP2515_private.h ändern und den IC zur Liste hinzufügen. (Hinweis für Beginner)

#if (BUILD_FOR_MCP2515 == 1)
#if defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) || defined(__AVR_ATmega644__)
    #define P_MOSI  B,5
    #define P_MISO  B,6
    #define P_SCK   B,7
    #define SUPPORT_FOR_MCP2515__
#elif defined(__AVR_ATmega8__)  || defined(__AVR_ATmega48__) || \
      defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)

    #define P_MOSI  B,3
    #define P_MISO  B,4
    #define P_SCK   B,5
    #define SUPPORT_FOR_MCP2515__
#elif defined(__AVR_ATmega128__)
    #define P_MOSI  B,2
    #define P_MISO  B,3
    #define P_SCK   B,1
    #define SUPPORT_FOR_MCP2515__
#elif defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    #define P_MOSI  B,0
    #define P_MISO  B,1
    #define P_SCK   B,2

    #define USE_SOFTWARE_SPI        1
    #define SUPPORT_FOR_MCP2515__
#else
    #error  choosen AVR-type is not supported yet!
#endif
#endif

Jetzt befindet sich mein Mega allerdings nach Aufruf der can_init allerdings in einer Endlosschleife, in der er ständig über SPI mit dem MCP2515 kommunizieren will (MOSI periodisch ausgelastet), über MISO allerdings nur ein paar Bits zurückkommen, und zwar immer die selben. Ich kann den Fehler nicht entdecken. Habe mir die letzte Version der Blbliothek runtergeladen.

Hoffe, du kannst mir eine Tipp geben.

Danke dir. Viele Grüße

# Benjamin meinte am 12. August 2010, 09:08 dazu:

Hallo,

ich habe Deine Lib bei meiner Diplomarbeit in Verbindung mit einem SJA1000-Soft-IP-Core auf einem FPGA verwenden können und sage dafür einfach mal Danke :) Einen Fehler habe ich allerdings gefunden, in der sja1000_get_message.c liest Du die Register 17 und 18 in der falschen Reihenfolge aus (Zeile 81+82). Also einfach die 17 und 18 vertauschen, und dann kann man auch die ID der empfangenen Nachricht korrekt weiterverarbeiten ;)

Gruß Benjamin

# Stefan meinte am 16. August 2010, 15:01 dazu:

So, ich habe jetzt herausgefunden, woran es bei mir lag. Die UART Bibliothek war nicht an den ATMega328PA angepasst. ich hatte zwar die neuste Version von Peter Fleurys Webseite runtergeldane, in der sich auch der ATMega328P findet, allerdings scheinen die Interrupt Vektoren nicht zu stimmen und so hing der Controller immer im der Routine fest. Habe die upgedatete Bibliothek von hier benutzt, die einwandfrei funktioniert. Sie basiert auf der von Peter Fleury.

Viele Grüße und herzlichen Dank für diese Bibliothek!

# Fabian Greif meinte am 19. August 2010, 22:06 dazu:

@Stefan
Freut mich das es jetzt funktioniert. So was ist natürlich ein hinterhältiger Fehler.

@Benjamin
Da merkt man das ich den SJA1000 noch nicht wirklich viel eingesetzt habe ;-) Über einen Test auf meinem Testboard ist er nicht hinausgekommen.

Der Fehler ist jetzt korrigiert und ein aktualisiertes Archiv online. Danke für den Fehlerbericht ;-)

Grüße Fabian

# Sascha meinte am 2. September 2010, 11:07 dazu:

Hallo,
danke für die Erstellung der Lib. Sie spart mir sehr viel Arbeit.
Leider tue ich mich sehr schwer die SPI Funktionen auszulagern. Ich möchte am SPI Bus noch zwei weitere Gerätschaften betreiben.
Gibt es eine einfache möglichkeit eine externe spi.c Datei zu verwenden.
Ich hoffe ich habe mich verständlich ausgedrückt.

Gruß Sascha

# Fabian Greif meinte am 2. September 2010, 15:07 dazu:

Hallo Sascha,

du kannst einfach die SPI-Funktionen der canlib verwenden. Das ist nur eine Funktion nämlich spi_putc(). Leg einfach eine entsprechende Deklaration oberhalb der Stelle an der du die Funktion verwenden willst an:

uint8_t spi_putc(uint8_t data);

Grüße Fabian

Deine Meinung:

  • Textformatierung ist mit Markdown möglich.
  • HTML wird entfernt.
  • Kommentare werden moderiert und sind daher eventuell nicht sofort sichtbar.
  • Irrelevante Kommentare werden gelöscht.