Forum: Projekte & Code Bibliothek: MAX 7219 / 7221 an AVR (GCC)


von Philipp M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe eine kleine Bibliothek geschrieben um einen MAX 7219 mit einem 
AVR Mikrocontroller anzusteuren. Wer Interesse daran hat kann sie sich 
runterladen und sie ohne Einschränkungen benutzen. Getestet wurde sie 
mit einem 7219er jedoch sollte sie auch mit einem 7221er funktionieren.

Die meisten Funktionen dienen dazu eine Zahl auf einer bis zu 
8-Stelligen 7-Segment Anzeige, die gemäß des Datenblatts angeschlossen 
wurde, darzustellen. Die Funktion "max7219_send" kann jedoch mit 
beliebigen Parametern aufgerufen werden und dazu benutzt werden die 
angeschlossenen LEDs völlig individuell anzusteuren.

Das Archiv enthält die ausführlich kommentierte Header-Datei die 
Code-Datei sowie das Datenblatt des MAX 7219/7221.


Über Kritik und Verbesserungsvorschläge sowie Bilder von eueren 
Projekten würde ich mich freuen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Philipp M. schrieb:
> Über Kritik und Verbesserungsvorschläge sowie Bilder von eueren
> Projekten würde ich mich freuen.

1) Die Daten in max7219_hex() lassen sich effektiver aus einer
   kleinen Tabelle lesen
2) Der Header ist nicht geschützt gegen Mehrfach-Includes
3) Der Header verwendet uint16_t, includiert aber nicht <stdint.h>
4) Mach die Funktionen entweder extern im Header oder static im
   C-Modul. Das macht den Sichtbarkeitsbereich klarer und static
   ermöglicht dem Compiler Optimierungen
5) Der Header verwendet PORTD etc, includet aber nicht <avr/io.h>
6) max7219_disp_int8() könnte zurückgreifen auf max7219_disp_uint8()
7) Sowas ist teuer auf AVR:
1
   if (Data & (1<<(7-i)))
   Stattdessen schaust du besser immer auf Bit 7 und schiebst Data
   nach links in jedem Schleifendurchlauf
8) Du verwendest <util/delay.h>? Das solltest du mit Bedacht tun.
   Ich seh die Verwendung jedoch nicht --> Include überflüssig
9) In Funktionen wie max7219_disp_uint16() erhälst du die Anzahl der
   Ziffern während der Ausgabe, sie muss nicht extra und teuer vor-
   berechnet werden.

Johann

von Philipp M. (spannungsabfall)


Lesenswert?

Danke für die Hinweise.

ich habe jetzt Punkt 1,2,3,4,5,7,8 abgehandelt.

Wie ich allerdings die Ziffernanzahl bei der Ausgabe herausfinden soll 
weiß ich nicht. Es sei denn ich würde in die Ausgabeschleife zusätzliche 
Abfragen einbauen, und dann bräuchte es im Endeffekt genauso viel 
Rechenzeit wie wenn ich die Abfrage vorher mache.

Gruß

von Pete K. (pete77)


Lesenswert?

Kannst Du dann die aktualisierte Lib wieder zur Verfügung stellen?

von Philipp M. (spannungsabfall)


Angehängte Dateien:

Lesenswert?

Habe ich ganz vergessen. Hier die überarbeiteten Dateien.

von Noch Grün (Gast)


Lesenswert?

Danke Gute Lib sehr Liebevolle und ausführlich Kommentiert .
Bis her keine Probleme läuft Top!!!

von eProfi (Gast)


Lesenswert?

void max7219_disp_int8(int8_t Number)

Aufpassen!
-128 geht bei Dir nicht, da positive Zahlen nur bis 127 gehen --->
Anders herum lösen: positive Zahlen nach negativ wandeln, das geht 
immer:

void max7219_disp_int8(int8_t n){char d=1,i=0;
  if(n<0)    {max7219_send(1,d++);}else{n = -n;} //Vorz.
  if(n<=-100){max7219_hex (1,d++);n += 100;} //Hunderter
  if(n<= -10){n += 10;i = 1;while(n <= -10){n += 10;i++;}
    max7219_hex(i,d++);}//Zehner
  max7219_hex(-n,d);}//Einer



Code aus dem Stegreif getippt ohne Test!

Warum ist d=1 und nicht d=0 (im Originalcode: for (i=1;...) )?

von eProfi (Gast)


Lesenswert?

hier kann man ebenso sparen:

void max7219_clock_out(unsigned char d){
  unsigned char m=128;do{ //Maske und gleichzeitig "Schleifenzähler"
    max7219_PORT         &=~(1<<max7219_CLK); //Sclk lo
    if(d&m){max7219_PORT |= (1<<max7219_DIN);}//Sdta hi
    else   {max7219_PORT &=~(1<<max7219_DIN);}//Sdta lo
    max7219_PORT         |= (1<<max7219_CLK); //Sclk hi, Datenübernahme
    }while(m>>=1); //nächstes Bit, bis keine mehr da sind
  }

von Philipp M. (spannungsabfall)


Lesenswert?

Hallo,

was die -128 angeht hast du vermutlich recht. Muss ich mir mal 
anschauen. Der Code ist jetzt auch schon 4 Jahre alt.^^

Warum i bei 1 anfängt kann ich allerdings erklären.

Wie im Headerfile erklärt, nummeriret die Bibliothek die einzelnen 
Zeichenpositionen mit 1-8 und nicht wie in der Informatik üblich mit 
0-7. Das liegt daran, dass die Zeichnummern so direkt den 
Registeradressen des Max7219 entsprechen. Adresse 0 ist nämlich eine 
No-Op-Adresse. Befehle an diese haben keine Auswirkung (wird wohl fürs 
Dasy-Chaining gebraucht).
Die Resgister 1-8 beschreiben dann den Zusatnd der Zeichen 0-7. Um mir 
die dauernde Umrechnung von Register zu Zeichenposition zu ersparen habe 
ich sie einfach auch mit 1-8 nummeriert.

von eProfi (Gast)


Lesenswert?

Leider hat sich in meinem oberen Code (void max7219_disp_int8(int8_t n)) 
ein Fehler eingeschlichen, es werden alle Nullen wegrationalisiert, egal 
ob führend oder innerhalb der Zahl.

von Ich (Gast)


Lesenswert?

An welche Pins des Mikrocontrollers (ATMEGA16 ) muss ich die Pins 
DIN/LOAD/CLK des MAX7219 anschließen?

Und wie übertrage ich in meinem Programm Dezimalzahlen an das Display? 
Also wie spreche ich die Bibliothek von meinem Programm aus an, wenn ich 
die Bibliothek eingebunden habe? Ich nutze MyAVR Studio.

von Philipp M. (spannungsabfall)


Lesenswert?

Die Pinbelegung kann im unteren Teil der max7219.h eingestellt werden. 
Dezimalzahlen sind noch nicht unterstützt. Das wäre eine Sinvolle 
Erweiterung.

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.