Neue, einfache CAN-Library für ATmega16M1

Persönliche Seite #6226308
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.
Angehängte Dateien:
#6278326
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.
Persönliche Seite #6278328
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)
Persönliche Seite #6278341
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren