[Erledigt] arduino+max7219

vor 2 years 18 weeks von S.E.P.P.

Ich bin gerade bei dem Versuch mit dem Arduino, über den "max7219" eine LED-Matrix zu betreiben. Erst einmal habe ich es mit dem Programm http://www.arduino.cc/playground/LEDMatrix/Max7219 hier probieren. Das ging allerdings völlig schief egal was ich mache es leutet immer die komplette matrix. Jetzt hab ich vor mir selber ein entsprechendes Programm zu schreiben und wollte fragen wie ich den "dataIn", "clock" und den "load" eingang beim max7219 ansteuern muss um bestimmte ausgänge am max7219 anzuschalten.

Ähnliche Posts

20 Antworten auf “arduino+max7219”


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
  1. uwe sagt:

    Hallo S.E.P.P

    Der max7219 hat ein serielles Interface eben "dataIn", "clock" und "load" .
    Es wird immer ein 16 bit Block übertragen. Bei der abfallenden Flanke von load beginnt die Übertragung. Dann 16 clock Signale. Bei der steigenden Flanke des clock wird der Zustand von datain in den Speicher des 7219 geladen.
    Der 16 bit Block setzt sich aus 4 nicht benutzten Bits, 4 Adress oder Komandobits und 8 Daten Bits zusammen.
    Wenn mehrere max7219 kaskadiert sind (data out des ersten mit datain des 2. verbunden und load un clock an alle gleichzeitig) dann müssen mehrmals nacheinander die Komandos gesendet werden)

    Anschluß an den Arduino über die Pins:
    dataIn = 2;
    load = 3;
    clock = 4;

    int maxInUse = 4; //change this variable to set how many MAX7219's you'll use
    auf 1 ändern; gibt an wieviele max7219 in Reihe über dataout-datain verbunden sind.
    funktionen zum schreiben:
    maxSingle( byte reg, byte col) //für einen max7219
    maxAll (byte reg, byte col) // für alle max7219
    maxOne(byte maxNr, byte reg, byte col) //maxOne is for adressing different MAX7219's, whilele having a couple of them cascaded
    um einen einzelnen der kaskadierten max7219 anzusteuern.

    Zuerst die Initialisation:
    //initiation of the max 7219
    maxAll(max7219_reg_scanLimit, 0x07); // set to use 8 digits
    maxAll(max7219_reg_decodeMode, 0x00); // using an led matrix (not decoding 7 segments)
    maxAll(max7219_reg_shutdown, 0x01); // not in shutdown mode
    maxAll(max7219_reg_displayTest, 0x00); // no display test
    for (e=1; e<=8; e++) { // empty registers, turn all LEDs off
    maxAll(e,0);
    }

    dann die Werte hineinschrieben über
    maxSingle(1,1); // + - - - - - - - wenn nur 1 max7219 verwendet wird
    maxAll(1,1); // + - - - - - - - an alle max7219
    oder
    maxOne(2,1,1); // + - - - - - - - an den 2. max 7219

    Genaueres unter :
    http://www.arduino.cc/playground/LEDMatrix/Max7219
    http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf

    Login or register to post comments

  1. S.E.P.P. sagt:

    Dieses Programm habe ich ja schon versucht zu benutzen. Ich habe maxInUse auf 1 geändert und sonst eigentlich nichts. Nur bei void setup(){} musste ich noch beginSerial(9600) in Serial.begin(9600) ändern da sonst nicht kompieliert werden konnte weil der befehl beginSerial nicht existiert. Keine ahnung warum das Fehlerhaft war. Aber wie gesagt das Programm führte dazu das die Matrix kommplett leuchtet (ich habe bei void loop(){} natürlich nur maxsingle() benutzt bzw. einfach mal gar nichts hineingeschrieben trozdem immer komplette matrix an.)

    Login or register to post comments

  1. S.E.P.P. sagt:

    Nochmal zum oberen Teil. Soll heißen als erstes muss ich "load" auschalten anschließend 16x "clock" einschalten und dabei wir jedes mal der zustand von "dataIn" in den Speicher geschrieben. Anschließend load wieder ein. Richtig so?
    Jetzt muss ich aber noch wissen welche auswirkungen das ganze auf die Ausgänge des max7219 hat.

    Login or register to post comments

  1. uwe sagt:

    Hallo S.E.P.P
    ja, richtig, das Übertragungsprotokoll ist im Datenblatt erklährt.
    Genau das machen ja die Funktionen maxSingle maxAll maxOne.
    Die serielle Schnittstelle wird nicht verwendet, darum kann beginSerial(9600) gelöscht werden.
    Die Erklährung der Befehle findest Du im Datenblatt.

    Das einzige was mir laut Datenblatt einfällt ist, daß Du das Display falsch herum angeschlossen hast (Anode und Katode der Leds vertauscht) und der MAX7219 in Shutdownmodus nach dem Reset bleibt, das heißt, daß die Programmierung nicht funktioniert.

    Falls Du den Fehler nicht findest schick mir ein Foto der Schaltung inclusive Arduino, Modell des Displays und den Programmcode. Vieleicht finde ich den Fehler. Meine Email kennst Du ja.
    Tschüß Uwe

    Login or register to post comments

  1. S.E.P.P. sagt:

    Nein es leuchtet ja das komplette display und vorher hat es ohne max 7219 problemlos geklappt. Ausserdem würde beim vertauschen doch nur falsche leds leuchten oder nicht? Beim Arduino habe ich es zumindest so gemacht das ich jeden Pin als OUTPUT deklariert habe und dann so die Spalten die leuchten sollen angeschaltet habe und die Zeilen die nicht leuchten sollen. Und das Datenblatt habe ich mir schon ausgiebig angeguckt aber ich versteh nicht was mit die X sagen sollen und wozu der sog. "HEX CODE" gut sein soll. Bisher bin ich soweit das ich zu wissen glaube das
    D1-D3 für A-G zuständig sind, D7 für den DezimalPunkt und D8-D11 für die digit0-7 ausgänge bzw. für irgendwelche zusatzsachen wie "scanlimit", "displaytest" usw.. -Und ich glaube jetzt hab ichs beim nochmaligem durchlesen verstanden. Die ganzen tabellen werden nur gebraucht wenn ich diesen "decodeMode" ausgeschaltet habe kann das sein? Wenn der an ist sind D0-D7 einfach für A-G, DP zuständig und D8-D11 weiterhin für die digit0-7 + Den rest. Das X heißt dann wohl immer das die unwichtig sind und nicht beachtet werden und dann macht der "HEX code" auch wieder sinn weil vorher hab ich ewig überlegt was dieses xX den bedeuten soll. Das dürfte im Hexadezimalsystem ja eigentlich nicht vorkommen.

    Login or register to post comments

  1. uwe sagt:

    Hallo S.E.P.P
    Im Datenblatt steht:
    Shutdown Mode: When the MAX7219 is in shutdown mode, the scan oscillator
    is halted, all segment current sources are pulled to ground, and all digit drivers are pulled to V+, thereby blanking the display.
    Das heißt, daß das die Led umgekehrt gepolt werden. Versuche die Spalten- und Reihenanschlüsse der displaymatrix umzutauschen. Nein, es müßten alle leuchten.
    X heist entweder daß es egal ist ob das bit 1 oder 0 ist, weil nicht benutzt.
    Der Hexadezimalcode wird verwendet da man 2 Stellen braucht um eine 8 Bit Binärzahl darzustellen.
    0x01 heist daß das eine Hexadezimalzahl ist, in diesem Fall 1 dezimal.
    0xXC heist daß die Sechzehnerstelle der hex-Zahl egal ist also 0x0C, 0x1C ecc sind gleich.
    Der MAX7219 hat 2 Betriebsmodi ( steht im Decode-Mode Register):
    Entweder die Daten D7 bis D0 werden direkt zum Einschalten der Led a bis gun DP verwendet,
    oder die zahl in D3 bis D0 wird decodiert und eine 7-Segmentanzeige zeigt die Zahl an (Table 5. Code B Font) die bit D7 bis D4 werden dann ignoriert.

    Scanlimit wird verwendet damit der 7219 weiß wieviele Stellen das Display hat. In Deinem Fall, da Du ein 7x5 Matrix Modul verwendest, sollte der Wert 5 bzw 7 sein, je nachdem wie die Leds in der Matrix sind. Da die Anzeige gemultiplext wird, die Stellen nacheinander angesprochen werden, erhält man bei weniger Stellen mehr Zeit für jedes einzelne.
    Die Bits D8 bis D11 sind die Befehle bzw die Adressse der Stellen des Displays
    Bei Werten von 1 bis 8 weden die Daten D0-D7 bzw D0-D3 bei Decodierung in den Speicher für die Ansteuerung der Segmente A-G und DP geladen.
    Die Werte 0, 9 bis 12 und 15 dezimal sind Befehle für die Einstellungen No Operation, Decode Mode, Intenity, Scan Limit, Shutdown und Display Test.

    Tschüß Uwe

    Login or register to post comments

  1. S.E.P.P. sagt:

    Also ich denke ich hab "eigentlich" alles verstanden nur ein Problem hab ich noch. Es funktioniert nicht.
    Ich hab es folgendermaßen gemacht:

    1.-0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0
    Das ganze sollte jetzt den "decodeMode" so einstellen das D0-D7 dierekt Dp, A-G regeln können
    2.-0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0
    Das sollte jetzt das "Scanlimit" auf 5 reduzieren
    3.-1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0
    Das sollte jetzt die Spalten 1(DP), 3(B), 5(D) und 7(F) in zeile 1(reg 0) ein bzw. ausschalten das weiss ich noch nicht genau auf jeden fall sollte in der ersten zeile immer abwechselnd eine LED an und eine aus sein.

    Allerdings leuchtet nach wie vor die ganze Matrix.

    Login or register to post comments

  1. uwe sagt:

    Hallo S.E.P.P

    Hab auch ein wenig denken müssen:
    Die Reihenfolge der Bits ist richtig.
    Ein Fehler in Deiner Zeile 2.; da muß 5 nicht 4 stehen. Das Scanlimit Register hat einen Wertebereich von 1 bis 8 nicht von 0 bis 7. Das ist aber kein gravierender Fehler. Eine Reihe Leds hätten nicht geleuchetet.

    Du vergißt nur den 7219 aus dem Standbymodus nach dem Einschalten zu holen.
    also folgendes:
    a) 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 // decode mode auf 0
    b) 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0 // scanlimit auf 5
    c) 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 // Shutdown ausschalten
    d) 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 // Werte für erste Zeile schreiben

    Beginnst Du die Spalten bei 0 zu zählen oder bei 1?

    Entschuldige, ich glaube immernoch daß Du das Display verkehrt herum ansteuerst. Leds sind verkehrt gepolt. Tausche Zeilen und Spalten um.
    Viel Glück
    Uwe

    Login or register to post comments

  1. S.E.P.P. sagt:

    Also ich hab dei Shutdownzeile in mein Programm eingefügt. Das Scanlimit mus übrigens doch auf 001 stehen, so steht es zumindest im pdf (0, 0, 1 für die ausgänge 0, 1, 2, 3 und 4). Das hat nichts gebracht (ich hab die Shutdownzeile auch vorher schon mal eingefügt, hab das nämlich so verstanden das dann einfach die richtung des Stroms verändert wird). Danach hab ich zum Wiederholten male die Kabel an dig0-4 mit DP, A-D vertauscht und umgekehrt die an DP, A-F mit dig0-6. Hat auch nichts gebracht. Desweiteren habe ich den max7219 gegen meinen zweiten ausgetauscht um zu gucken ob der Fehler hier liegt, wieder nichts. Es leuchtet immer die ganze Matrix bzw. nach dem umpolen der Matrix gar nichts.

    Login or register to post comments

  1. uwe sagt:

    Hallo S.E.P.P

    Entschuldige, so kommen wir nicht weiter.
    Bitte schick mir ein Foto Deiner Schaltung. Das Modell Deines Displays, das Programm und die Fehlerbeschreibung bei der gegebenen Schaltung und Programm.

    Schick es mir einfach an meine Email Adresse.

    Tschüß Uwe

    Login or register to post comments

  1. S.E.P.P. sagt:

    Gut werd ich machen ist wahrscheinlich die beste Lösung

    Login or register to post comments

  1. uwe sagt:

    Schlußerklährung
    Das Problem waren:
    1) die Reihenfolge der bits
    2) das Timing beim versenden
    Viele Grüße Uwe

    Login or register to post comments

  1. didi (not verified) sagt:

    Hi Sepp, Uwe,

    was war nun die Lösung? Ich habe dasselbe Problem. Steuere eine 8x8 LED Matrix mit einem Atmega16 über spi an und es leuchten immer alle LEDS.

    Meine Übertragungsfkt ist folgende:

    static void transmit(unsigned char addr, char data) {

    load_0();
    SPDR = addr; //Start transmission of register adress
    while(!(SPSR &(1<

    Login or register to post comments

  1. didi (not verified) sagt:

    Hi Sepp, Uwe,
    was war nun die Lösung? Ich habe dasselbe Problem. Steuere eine 8x8 LED Matrix mit einem Atmega16 über spi an und es leuchten immer alle LEDS.
    Meine Übertragungsfkt ist folgende:
    static void transmit(unsigned char addr, char data) {
    load_0();
    SPDR = addr; //Start transmission of register adress
    while(!(SPSR &(1<

    Login or register to post comments

  1. S.E.P.P. sagt:

    Um ehrlich zu sein habe ich das Problem "vorübergehen" (gut dieses vorübergehend ist schon ein halbes Jahr) mit der LED-Control Libary auf der Arduino Homepage gelöst. Das klappt super. Aber ich muss mir unbedingt nocheinmal den Code angucken, habe im Moment aber zuviel anderes zu tun.

    Login or register to post comments

  1. uwe sagt:

    Hallo didi
    Bitte gib mehr und genaurer infos.
    Grüße Uwe

    Login or register to post comments

  1. didi (not verified) sagt:

    Hi Uwe,
    sorry, wurde wohl abgeschnitten.
    void SPI_Masterinit(void) {
    DDRB = (1<

    Login or register to post comments

  1. didi (not verified) sagt:

    Hi Uwe,
    haut irgendwie nicht hin. Es wird immer abgeschnitten. Kann ich dir den code irgendwo hinschicken? Grüße, Didi

    Login or register to post comments

  1. uwe sagt:

    Versuch den Kode in [ c o d e ] und [ / c o d e ] tags einzuschließen. Ich hab Leerzeichen zwischen den Buchstaben geschrieben, damit der Tag nicht erkannt wird. Du mußt alle Leezeichen weglassen.
    Grüße Uwe

    Login or register to post comments

  1. didi (not verified) sagt:

    Hi Uwe, klasse jetz klappts. Anbei der Code.

     #include <avr/io.h>
    #include <stdlib.h>
    //#include <avr/interrupt.h>
    #include <util/delay.h>
     
     
    void static load_0()
    {
    	PORTB &= ~(1<<PB4);				//data prepared
    }
     
    void static load_1()
    {
    	PORTB |= (1<<PB4);				//data captured by max7219
    }
     
    Gruß,
    Didi
    void SPI_Masterinit(void) {
     
    	DDRB  = (1<<PB4)|(1<<PB5)|(1<<PB7);              //set PB4(SS), PB5(MOSI) & PB7(SCK output), all others input
    	SPCR  = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);  //enable SPI, set Master
    	PORTB |= (1<<PB7)|(1<<PB4);			//set SCK and SS high
    	SPSR = 0;
     
    }
     
     
    static void transmit(unsigned char addr, char data) {
     
    	load_0();
    	SPDR = addr;					//Start transmission of register adress
    	while(!(SPSR &(1<<SPIF)));  	//Wait for transmission to complete (SPIF = End of transmission flag)
     
    	asm volatile ("nop");
     
    	SPDR = data;					//Start transmission of data into register
    	while(!(SPSR & (1<<SPIF))); 	//Wait for transmission to complete
    	load_1();
    	load_0();
    }
     
    static void max7219_init(void)
    {
    		//transmit(0x0C,0x01);      //Display an
    		//transmit(0x0A,0x0F);      //Intensität 0x00 - 0x0F	
      		//transmit(0x0B,0x05);      // scan digits 0-7 Achtung, damit ist eine Stelle gemeint
      		//transmit(0x09,0x00);      // Dekodieren 
    		//transmit(0x0F,0x00);      //Testmode an
     
    }
     
     
    int main()
    {
    	SPI_Masterinit();
    	//max7219_init();
     
      while (1)
      {
    	transmit(0x0C,0x00);
    	_delay_ms(1000);
    	transmit(0x00,0x00);
    	_delay_ms(1000);
    	transmit(0x09,0x00);
    	_delay_ms(1000);
    	transmit(0x0C,0x01);
    	_delay_ms(1000);
    	transmit(0x01,0x00);
    	_delay_ms(1000);
     
     
      }
     
    return 0;
    }

    Login or register to post comments