Forum: Projekte & Code Neue, einfache CAN-Library für ATmega16M1


von Tilo R. (joey5337) Benutzerseite


Angehängte Dateien:

Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

gibts da noch eine config.h dazu, beim builden wird gemeckert das diese 
Datei fehlt? Wollte das mal Schritt für Schritt durch simulieren.

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

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

von Tilo R. (joey5337) Benutzerseite


Angehängte Dateien:

Lesenswert?

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.)

von Klemmen (Gast)


Lesenswert?

Verstehe ich es nicht oder nutzt du keine Interrupts wenn Nachrichten 
rein kommen? Wenn du es nicht nutzt, warum nicht?

von Lutz B. (lutzbroszio)


Lesenswert?

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.

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

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)

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.