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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tilo R. (joey5337) Benutzerseite


Angehängte Dateien:

Bewertung
2 lesenswert
nicht 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 O. (kosmos)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Steht doch im Header:
 * This library requires you to poll for received messages. In order to save 
 * the planet, you should reduce power consumption, which requires you to use 
 * sleep mode. If you define CAN_USE_ISR, the library registers an (empty) ISR, 
 * to wake up from sleep on incoming CAN-Messages.
 * For this to work, do not set PRCAN in the Power Reduction Register (PRR).
 * If you do so, the CAN-receiver is turned off and requires can_init() again.

von Tilo R. (joey5337) Benutzerseite


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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:
while (can_ReceiveExt(&msg.can) == can_OK) {
   ...
}

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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.