Forum: Mikrocontroller und Digitale Elektronik 7219 funzt nicht mit Atmega8


von Jens (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

bin jetzt schon seit Tagen damit beschäftigt vier 7-Segment-Anzeigen mit 
einem Atmega8 und dem Maxim7219 Softwaremäßig anzusteuern.

Das gelingt aber nicht.

Wenn ich den µC starte gehen alle Segment-Led´s voll an und fallen dann 
in eine schwächere Anzeige zurück(die Initialisierung?). Allerdings regt 
sich dann nichts mehr. Egal wie viele Digits ich angebe, es gehen immer 
alle an und das wars.

Die Daten- CLK- und Load-Leitungen sind nicht länger als 10cm, die 
Digtit-Leitungen max. 5cm. Der V+ Pin ist nach Datenblatt mit 10µF und 
0.1µF gegen GND abgeblockt. Für den ISET Pin habe ich 12KOhm gewählt.

Die DIN Leitung kommt vom PB1, Load von PB2 und CLK von PC4.

Programmiert wird in C.

Vielleicht findet jemand etwas im Code oder kann mir Hardwaretips geben.

Gruß Jens

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Jens schrieb:
> kann mir Hardwaretips

Schaltplan?

von Jens (Gast)


Lesenswert?

Guten Morgen,

hab leider keinen digitalisierten Schaltplan am Start.Hilft ein Foto?

Die Beschaltung ist wie beschrieben, alle SEG sind angeschlossen sowie 
DIG 0-3. Beide GND sind auf Ground der Schaltung(Steckbrett).

Frage mich zum Bsp. was ich mit den freien DIG-Pins (4-7) machen soll?

Oder ist es möglich das durch die getrente Übertragung der adresse und 
der Daten etwas schief geht?

Jens

von Peter D. (peda)


Lesenswert?

Tu Dir nen Gefallen und nenne Programme *.c.
Leerzeilen sollte man nicht unnütz einfügen.
Du schiebst immer nur 1-Bits rein.
1
void shift_7219(uint8_t data)
2
{
3
  for (uint8_t i = 8;i > 0; i--)
4
  {
5
  CLK_OFF();
6
    DIN_PORT |= (1<<DIN_PIN);
7
                if((data & 0x80) == 0)
8
    {
9
      DIN_PORT &= ~(1<<DIN_PIN);  
10
    }
11
    data <<= 1;
12
  CLK_ON();    
13
  }
14
}


Peter

von Jens (Gast)


Lesenswert?

Guten Morgen Peter,

freut mich sehr das gerade Du antwortest. Ich weis das Du den 7219 
warscheinlich schon lange hinter dir gelassen hast, habe mir auch Deinen 
Code aus dem DCF77 Projekt angeschaut...zu hoch für mich, würde ja gern 
erst einmal wenigstens eine Digit-Led gezielt ansprechen können.

Habe den Code entsprechend Deinem Vorschlag geändert, kein Erfolg.

Schiebe ich falsch? Ziel soll sein das immer das 8te Bit (ganz links)auf 
1 geprüft werden soll und bei "wahr" der DIN-Pin high geschaltet wird.

Habe in deinem Code gesehen das Du in Hex-Schreibweise manchmal die Null 
weglässt z.B. 0xC statt 0x0C. Kann man das immer so machen?

Was meinst Du zu meinen Vermutungen weiter oben (getrennte Adr/Dat, 
freie DIG-Pins)?

Jens

von ... (Gast)


Lesenswert?

Jens schrieb:
> Frage mich zum Bsp. was ich mit den freien DIG-Pins (4-7) machen soll?

offen lassen.

von ... (Gast)


Lesenswert?

Du hast doch 4 Stück 7-Segment-Anzeigen angeschlossen. Warum schaltest 
du dann die Decodierung in deiner Initalisierung aus?
> send_7219(0x09, 0x00 );//decode mode: off
hier müsste es heißen:
send_7219(0x09, 0x0F );//decode mode digit 3-0: on

von Jens (Gast)


Lesenswert?

Hallo,

möchte ja die einzelnen Digit-Leds ansprechen, benötige also keinen 
Decode-Mode.

Noch einmal zum Schieben:
Möchte "data" immer um ein Bit weiter nach links schieben um auf dem 
8ten Bit der Maske(0x80) auf 1 zu prüfen. Ist das in meinem Code richtig 
gelöst?

Danke Jens

von ... (Gast)


Lesenswert?

Jens schrieb:
> Die DIN Leitung kommt vom PB1, Load von PB2 und CLK von PC4.

Warum nutzt du nicht die SPI-Einheit des ATmega8?

von Jens (Gast)


Lesenswert?

Die SPI Pins werden vom Programieradapter benutzt. Habe mir ausserdem 
vorgestellt das es ja nicht so schwer sein kann den MAX via Software 
anzusprechen.
Was sagst Du im übrigen zu der Software?

Jens

von ... (Gast)


Lesenswert?

du sendest immer 1 Bit und schaltest dann die LOAD-Leitung high. Das ist 
falsch.
Du must immer 16 Bit in einem Stück senden, in der Form B0,B1,B2...B15 
und dann erst die LOAD-Leitung auf high ziehen.

von ... (Gast)


Lesenswert?

Jens schrieb:
> Die SPI Pins werden vom Programieradapter benutzt.

Da könntest du in den Zuleitungen zum 7219 einen Tri-State-Buffer 
einbauen, der durch die Reset-Leitung gesteuert wird.

von Jens (Gast)


Lesenswert?

Hey,
meiner Meinung nach schalte ich in der Funktion send_7219 den Load_pin 
auf low, sende dann in shift_7219 ein  Bit, schalte die CLK-Flanke high 
und schalte die CLK wieder low bevor ich das nächste Bit hole. Nach 
2x8Bit schalte ich in send_7219 Load wieder high.

Macht mein Code etwas anderes?

Jens

von ... (Gast)


Lesenswert?

Du sendest in deiner Main eigentlich auch immer nur an das Register mit 
der Adresse 0x00
und das ist das "no op" Register:

send_7219(0x00, i );
  i++;

von Jens (Gast)


Lesenswert?

ja, das habe ich inzwischen auch festgestellt und geändert.
Trotzdem läuft es nicht, nach dem brennen leuchten zwar manchmal ein par 
Leds aber wenn ich aus und einschalte zeigt sich alles wie zuvor, 
nämlich nur sehr gedimmte Anzeigen mit allem an. Was kann ich probieren?
Jens

von Mike (Gast)


Lesenswert?

Jens schrieb:
> meiner Meinung nach schalte ich in der Funktion send_7219 den Load_pin
> auf low, sende dann in shift_7219 ein  Bit, schalte die CLK-Flanke high
> und schalte die CLK wieder low bevor ich das nächste Bit hole. Nach
> 2x8Bit schalte ich in send_7219 Load wieder high.
>
> Macht mein Code etwas anderes?

Ich habe mal einrn Kommentare eingefügt:
1
void shift_7219(uint8_t data)
2
{
3
uint8_t i = 0;
4
5
  for (i = 8;i > 0; i--)
6
  {
7
  CLK_OFF();
8
                if((data & 0x80) == 0)
9
    {
10
      DIN_PORT &= ~(1<<DIN_PIN);  
11
    }
12
    //bis hierher alles ok!!
13
    //hiernach setzt Du DIN_PIN direkt wieder auf high, falsch!
14
    //DIN_PIN sollte erst, nachdem der 7219 den Zustand
15
    //gelesen hat wieder high gesetzt werden! 
16
    //Am besten also direkt vor dem nächsten CLK_OFF
17
    data <<= 1;
18
    DIN_PORT |= (1<<DIN_PIN);
19
  CLK_ON();    
20
  }
21
22
return;
23
}

von Mike (Gast)


Lesenswert?

Hat Peter übrigens schon heute morgen genauso erkannt!
Ich dachte auch erst, er mein ein Bit und nicht Einser-Bits ;)

von Jens (Gast)


Angehängte Dateien:

Lesenswert?

Hey Mike,

danke für die nochmalige Klarstellung. Habe den Code auch heut morgen 
schon entsprechend umgeschrieben und inzwischen auch noch einmal 
ausgedünnt.
Im Anhang also noch einmal neu.

Trotzdem läuft es nicht, als würde die Datenübertragung nicht einmal ein 
bisschen, also fehlerhaft laufen. Load setze ich in der send_7219 
Funktion low/high, ich denke an der richtigen Stelle.

Wäre es vielleicht sinnvoll eine Pause vor dem Abschalten des CLK-Pins 
einzubauen?

Jens

von ... (Gast)


Lesenswert?

Jens schrieb:
> Möchte "data" immer um ein Bit weiter nach links schieben um auf dem
>
> 8ten Bit der Maske(0x80) auf 1 zu prüfen. Ist das in meinem Code richtig
>
> gelöst?

War das nicht so, dass man von Bit 0 aus zählt? D.h. wenn du 8 Bit 
übergeben willst musst du auf 0x70 abfragen.

von Peter D. (peda)


Lesenswert?

Jens schrieb:
> habe mir auch Deinen
> Code aus dem DCF77 Projekt angeschaut...zu hoch für mich

Die sollten aber funktionieren.
Hier die Init:
1
void display_write( uint16_t dc )
2
{
3
  MAX7219_DDR |= 1<<MAX7219_DO;
4
  MAX7219_DDR |= 1<<MAX7219_SCK;
5
  MAX7219_DDR |= 1<<MAX7219_STB;
6
  MAX7219_PORT &= ~(1<<MAX7219_STB);
7
8
  for( uint8_t i = 12; i; i-- ){
9
    MAX7219_PORT &= ~(1<<MAX7219_SCK);
10
    MAX7219_PORT |= 1<<MAX7219_DO;
11
    if( (dc & 0x0800) == 0 )
12
      MAX7219_PORT &= ~(1<<MAX7219_DO);
13
    dc <<= 1;
14
    MAX7219_PORT |= 1<<MAX7219_SCK;
15
  }
16
17
  MAX7219_PORT |= 1<<MAX7219_STB;
18
}
19
20
21
void display_init( void )
22
{
23
  display_write( 0xF00 );               // Testmode off
24
  display_write( 0x900 );               // Decode off
25
  display_write( 0xB07 );               // 8 Digits
26
  display_write( 0xC01 );               // Display on
27
  display_write( 0xA00 | brightness );  // Brightness
28
}


Peter

von Jens (Gast)


Lesenswert?

So, jetzt muss ich etwas ganz peinliches gestehen:

An meiner freifliegenden Spannungsversorgung waren die Kabel vertauscht 
(+ & - , blau & rot). So habe ich die 7-Segmentanzeige ausprobiert und 
eine gemeinsame Kathode festgestellt. Wenn die Kabel richtig stecken ist 
das Ding natürlich plötzlich mit gem. Anode. Der Max und auch meine 
Schaltung waren aber für gem. Kathode gedacht. So lief also nix bis ich 
mich heute entschlossen habe bim Händler eine Anzeige mit gem. Kathode 
zu kaufen. Beim "durchklingeln" der Pins ist mir dann der Fehler mit den 
vertauschten Kabeln aufgefallen.

Das ist natürlich auch ein großes Glück denn der Max LÄUFT 1A !!

Der Code ist also durchaus verwendbar und sicherlich leicht 
verständlich. Wünsche also allen viel Glück und Erfolg mit dem Max7219 
und bedanke mich für die Hilfe in diesem Forum.

Jens

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.