Hallo Forum, ich habe immer noch Hardware mit einem ATmega16M1, der CAN benutzt. Ich kenne ein paar der verfügbaren CAN-Bibliotheken, z.B. http://www.kreatives-chaos.com/artikel/universelle-can-bibliothek . Auch bei Microchip findet man in der Application Note AN_8247 / AVR076 Beispielcode: https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591223 . Digikey hat auch angepassten Beispielcode: https://www.digikey.com/eewiki/display/microcontroller/CAN+Example+-+ATmega32M1+-+STK600#CANExample-ATmega32M1-STK600-ATmegaxxM1CANLibraries Diese Bibliotheken habe ich angeschaut und bisher auch benutzt, wenn auch stets widerwillig. Ich finde diese Bibliotheken viel zu kompliziert! Zugegeben brauche ich nur wenige CAN-Features (Senden, Empfangen). Vielleicht tun sich routinierte C-Programmierer auch leichter mit einer auf mehrere Files verteilten Bibliothek, als ich, der C, wenn überhaupt nur an hohen Feiertagen anfasst. Jedenfalls habe ich mich jetzt überwunden und eine ganz einfache Bibliothek gebaut, die ich hiermit der Allgemeinheit zur Verfügung stellen möchte. Doku ist in der Header-Datei. Getestet ist sie mit dem ATmega16M1, sie sollte aber auch mit dem ATmega32M1 und ATmega64M1 laufen. Anbei meine CAN-Bibliothek. Über Kommentare und Feedback würde ich mich freuen.
gibts da noch eine config.h dazu, beim builden wird gemeckert das diese Datei fehlt? Wollte das mal Schritt für Schritt durch simulieren.
Ja, sorry. In config.h hab ich auch andere defines wie F_CPU drin. Der relevante Teil in config.h ist: // CAN #define F_IO 8 // IO CLock 8 MHz #define CAN_BAUDRATE 100 #define CAN_USE_ISR
Ich hatte noch einen kleinen Fehler beim Setzen der DDR-Flags, anbei die neueste Version. (Ich hatte mir vorgenommen das auf github hochszustellen, aber man kommt ja zu nix.)
Verstehe ich es nicht oder nutzt du keine Interrupts wenn Nachrichten rein kommen? Wenn du es nicht nutzt, warum nicht?
Steht doch im Header:
1 | * This library requires you to poll for received messages. In order to save |
2 | * the planet, you should reduce power consumption, which requires you to use |
3 | * sleep mode. If you define CAN_USE_ISR, the library registers an (empty) ISR, |
4 | * to wake up from sleep on incoming CAN-Messages. |
5 | * For this to work, do not set PRCAN in the Power Reduction Register (PRR). |
6 | * If you do so, the CAN-receiver is turned off and requires can_init() again. |
Es gibt 2 Möglichkeiten und man kann in der config entscheiden welche man will. 1. Ohne Interrupt, dann muss man regelmäßig pollen 2. Mit Interrupt. Die ISR ist aber leer und hat nur die Aufgabe, den Controller aufzuwecken. Im Hauptprogramm muss man dann ggf. eingegangene Nachrichten abholen. Eine ISR, die die Nachricht abholt und irgendwo speichert habe ich nicht. Das wäre dann erstens eine ISR die lange dauert und damit vielleicht andere Interrupts blockiert. Zweitens müsste ich dann einen Fifo-Puffer allokieren, um die eingegangene Nachricht abzuspeichern. (Ein Ein-Nachrichten-Puffer bringt nichts, das wäre so gut wie meine jetzige Lösung)
Ich wollte halt den minimalsten Overhead und keine unnötigen Features haben. Eingehende Nachrichten sollten trotzdem nicht verloren gehen, weil ich 3 MOBs für den Empfang verwende. In der Hauptschleife Frage ich nach neuen Nachrichten bis keine mehr da sind:
1 | while (can_ReceiveExt(&msg.can) == can_OK) { |
2 | ... |
3 | } |
Ebenso als Vereinfachung gibt es nur einen möglichen Filter für eingehende Nachrichten und man muss sich entscheiden, ob man Standard- oder Extended-Nachrichten empfangen möchte. Hätte ich da Flexibilität gelassen, und Standard- und Extenden-Nachrichten zusammen behandelt, müsste ich im Code Fallunterscheidungen machen. In der Praxis interressiert mich aber eh nur eine Botschaftsart, d.h. ich hätte unnötigen Code aus der Bibliothek im Binary. Und im Code des Anwenders müsste vielleicht auch noch eine Fallunterscheidung rein.
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.