Forum: Mikrocontroller und Digitale Elektronik max7219 erst nach reset verwendbar


von Sam (Gast)


Lesenswert?

Ich proviere jetzt seit ein paar tagen meinen max zum laufen zu bringen, 
allerdings funktioniert das nur nach einem reset: Ich lege die Spanung 
an den Atmega an, drücke reset und erst dann leuchten alle segmente. 
Aufjedenfall mit diesem Code:
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
5
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
6
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
7
"nachträgliche" Definition hinweist */
8
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 definiert"
9
#define F_CPU 8000000UL /* Quarz mit 8 Mhz */
10
#endif 
11
#include <util/delay.h>
12
#include <stdlib.h>
13
14
void transmit(unsigned char, char);
15
16
void Load_Low()
17
{
18
  PORTB &= ~(1 << PB2);
19
}
20
21
void Load_High()
22
{
23
  PORTB |= (1 << PB2);
24
}
25
26
27
void SPI_MasterInit(void) {
28
29
    DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input
30
31
    SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4
32
33
    PORTB |= (1 << PB7)|(1 << PB2);
34
}
35
36
void transmit(unsigned char addr, char data) {
37
38
  SPDR = addr;                      // Start transmission
39
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete
40
41
  asm volatile("nop");
42
43
  SPDR = data;                      // Start transmission
44
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
45
}
46
47
void test_Init(void)
48
{
49
  Load_Low();
50
  for (int i = 0; i < 3; i++)
51
  {
52
  transmit(0x0C,0x01);            // normal mode  transmit(0x0C,0x01);
53
  }
54
  Load_High();
55
}
56
57
int main()
58
{
59
60
    SPI_MasterInit();
61
    _delay_ms(10);
62
    test_Init();
63
64
    //tu was....
65
66
      while (1) 
67
      {
68
69
     _delay_ms(10);
70
71
      }
72
73
   return 0;
74
75
}

Mit diesem hier geht es nur nach mehrmaligem reset:
http://www.mikrocontroller.net/attachment/7274/Max7219_Test.bas

Mit dem C Code war es früher genauso, bis ich die Wartezeit am Anfang 
auf 10ms von 10µs erhöht habe (so reicht es aufjedenfall).


Kann es sein, dass ich noch irgendwo Wartezeiten einbauen muss?

von ... (Gast)


Lesenswert?

Sam schrieb:
> for (int i = 0; i < 3; i++)

Die Anzahl der Stellen(bzw. MAX7219) ist richtig?

Du solltest mehr Informationen über deinen Hardwareaufbau geben.

Du hast zwingend einen 10µF und parallel dazu einen 0,1µF direkt an 
den Spannungversorgungs-Pins des/r MAX7219 gegen GND angeschlossen?

von Sam (Gast)


Lesenswert?

> Du hast zwingend einen 10µF und parallel dazu einen 0,1µF direkt an
> den Spannungversorgungs-Pins des/r MAX7219 gegen GND angeschlossen?

Du meinst einfach Kondensator zw. GND und VCC, oder?
Nein, ist vom usbasp vom USB anschluss. Also müsste das stabil sein.

> Sam schrieb:
>> for (int i = 0; i < 3; i++)
>
> Die Anzahl der Stellen(bzw. MAX7219) ist richtig?

da ich das erst mal testen wollte, hab ich einfach die digits 1 - 4 an 
die Pins 2,3,7 und 6 angeschlossen. Später änder ich natürlich die 
Reihenfolge.
Das gleiche auch bei den Segmenten, Zahlen könnte man nicht lesen. Aber 
es geht ja erstmal darum, das ich den Mega starte und alle Segmente 
leuchten sofort.

von ... (Gast)


Lesenswert?

Sam schrieb:
> Nein, ist vom usbasp vom USB anschluss. Also müsste das stabil sein.

Beratungs-Resistent?
Ob du deine Spannungsversorgung von sonst wo beziehst ist vollkommen 
egal. An die Versorgungsspannungsanschlüsse des 7219 gehören die oben 
bezeichneten Kondensatoren dran, sonst macht das Teil was es will.

Der Code oben ist von mir und ist gedacht für mehrere 7219 in Serie 
geschaltet und für 8x8-Matrix-Betrieb gedacht.
Wenn du jetzt nur einen 7219 in 7-Segment-Mode betreiben willst musst du 
ihn anders initialisieren. Schau dir mal das Datenblatt an.

von ... (Gast)


Lesenswert?

Der Code für deinen Aufbau (Test) müsste aussehen:
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
5
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
6
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
7
"nachträgliche" Definition hinweist */
8
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 definiert"
9
#define F_CPU 8000000UL /* Quarz mit 8 Mhz */
10
#endif 
11
#include <util/delay.h>
12
#include <stdlib.h>
13
14
void transmit(unsigned char, char);
15
16
void Load_Low()
17
{
18
  PORTB &= ~(1 << PB2);
19
}
20
21
void Load_High()
22
{
23
  PORTB |= (1 << PB2);
24
}
25
26
27
void SPI_MasterInit(void) {
28
29
    DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input
30
31
    SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4
32
33
    PORTB |= (1 << PB7)|(1 << PB2);
34
}
35
36
void transmit(unsigned char addr, char data) {
37
38
  SPDR = addr;                      // Start transmission
39
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete
40
41
  asm volatile("nop");
42
43
  SPDR = data;                      // Start transmission
44
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
45
}
46
47
void test_Init(void)
48
{
49
  Load_Low();
50
   {
51
  transmit(0x0F,0x01);            // Display Test-Mode  transmit(0x0F,0x01);
52
  }
53
  Load_High();
54
}
55
56
int main()
57
{
58
59
    SPI_MasterInit();
60
    _delay_ms(10);
61
    test_Init();
62
63
    //tu was....
64
65
      while (1) 
66
      {
67
68
     _delay_ms(10);
69
70
      }
71
72
   return 0;
73
74
}

von Sam (Gast)


Lesenswert?

... schrieb:
> nn du jetzt nur einen 7219 in 7-Segment-Mode betreiben willst musst du
> ihn anders initialisieren. Schau dir mal das Datenblatt an.
Ja, aber ich möchte auch Zeichen anzeigen, von dem her werde ich die 
Zahlen per Software erzeugen.

Kondensator hat bisher noch nicht geholfen, ich glaub die müssen wie 
beim Mega nah an den Max dran (ist auf dem Steckbrett grad ein bisschen 
schwierig). Muss man ein bisschen rumstecken.

von ... (Gast)


Lesenswert?

Sam schrieb:
> ich glaub die müssen wie
> beim Mega nah an den Max dran

Hatte ich so geschrieben. Aber den Code wirst du auch ändern müssen, 
siehe oben.

Sam schrieb:
> von dem her werde ich die
> Zahlen per Software erzeugen.

Nö, du musst nur den entsprechenden Registenr des 7219 die passenden 
Werte übergeben.

von Sam (Gast)


Lesenswert?

Sam schrieb:
> void test_Init(void)
> {
>   Load_Low();
>    {
>   transmit(0x0F,0x01);            // Display Test-Mode  transmit(0x0F,0x01);
>   }
>   Load_High();
> }

ohne Klammern halt, ok jetzt hab ich das verstanden.

Ich bau die Schaltung jetzt erst mal auf ne Platine. Ich glaub da sind 
irgendwo Wackelkontakte.

von Sam (Gast)


Lesenswert?

... schrieb:
> Sam schrieb:
>> von dem her werde ich die
>> Zahlen per Software erzeugen.
>
> Nö, du musst nur den entsprechenden Registenr des 7219 die passenden
> Werte übergeben.

ich möchte aber auch ein paar buchstaben schreiben, daher die direkte 
ansteuerung ohne decoder.

von ... (Gast)


Lesenswert?

Sam schrieb:
> ohne Klammern halt

ja, sorry.

von ... (Gast)


Lesenswert?

Sam schrieb:
> ch möchte aber auch ein paar buchstaben schreiben, daher die direkte
> ansteuerung ohne decoder.

ok, dann muss das Decode-Mode Register 0x09 als erstes den Wert 0x00 
bekommen.

Der Test-Mode von oben ist im Übrigen so lange wirksam bis du den wieder 
zurückstellst auf Normal Mode.

von Sam (Gast)


Lesenswert?

Danke ... oder wie ich dich nennen soll ,lag tatsächlich am Steckbrett. 
Ich hab jetzt ein 100nF im IC-Sockel vergraben, näher gehts nicht. auf 
den 10µF hab ich verzichtet. Die Spannung vom PC sollte stabil genug 
sein und der ist ja für gröbere dinge da. Netzbetrieb ist eh nicht 
vorgesehen, eher mit Batterie.

von Sam (Gast)


Lesenswert?

Ich hab doch noch ne Frage:

Wie funktioniert das genau mit dem Low and High.
Muss man vor jedem Befehl das machen?

von ... (Gast)


Lesenswert?

Sam schrieb:
> Wie funktioniert das genau mit dem Low and High.
> Muss man vor jedem Befehl das machen?

In deinem Fall vor und nach jedem "transmit", wie im Beispiel.

von Sam (Gast)


Lesenswert?

... schrieb:
> In deinem Fall vor und nach jedem "transmit", wie im Beispiel

Danke hab ich jetzt auch in einem anderen Codebeispiel gesehen.
Der Max hat allerdings doch nicht richtig funktioniert, jetzt 
funktioniert er aber. Ich hab ausversehen Pin 4 und 8 statt 4 und 9 mit 
GND verbunden. Außerdem den reset Taster um 90° falsch herum eingebaut, 
somit awr Reset die ganze zeit auf GND. Ich hoffe ich hab jetzt nicht 
schon irgendwie geschrottet wie damals mein tba820 als verstärker. Die 
Schaltung war richtig, der tba kaputt, verstärkte nicht richtig und 
rauschte.

Trotzdem klappt es nicht die Anzeige an und auszuschalten.

Hab ich vielleicht mein Prog falsch geschrieben? Wenn ich ihn anschalte 
leuchten alle Ziffern mehr nicht.

von ... (Gast)


Lesenswert?

Sam schrieb:
> Wenn ich ihn anschalte
> leuchten alle Ziffern mehr nicht.

Das war ja auch mit dem Testcode von oben so gewollt.

von Sam (Gast)


Angehängte Dateien:

Lesenswert?

... schrieb:
> as war ja auch mit dem Testcode von oben so gewollt.

Sorry.
Ich hab vergessen mein neuen Code hochzuladen.

Das Prog sollte jetzt  0 1 0 1 usw. anzeigen.

von ... (Gast)


Lesenswert?

irgendwie blick ich durch deinen Code nicht durch. Wo definierst du denn 
"mode"?
Und werden die Werte 0 oder 1 auch als hex-Wert interpretiert?

von Sam (Gast)


Lesenswert?

Mode ist unsigned (ich habs früher immer bool gennant bis ich Avrs 
programmierte und haufen fehlermeldungen bekam, dass der avr das nicht 
kennt).

MAX_MODE ist in der .h Datei definiert.

Ich schreib mal die Befehle raus:
1
DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input
2
SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4
3
PORTB |= (1 << PB7)|(1 << PB2);
4
5
transmit(0x0C,1); 
6
transmit(0x09,0);
7
transmit(0x0B,0x07);
8
while(1)
9
{
10
for(uint8_t i = 1; i!=9;i++)
11
        transmit(i,0);  
12
_delay_ms(500);
13
for(uint8_t i = 1; i!=9;i++)
14
        transmit(i,255);   
15
_delay_ms(500);
16
17
}

und noch transmit
1
void Load_Low(void)
2
{
3
  PORTB &= ~(1 << PB2);
4
}
5
6
void Load_High(void)
7
{
8
  PORTB |= (1 << PB2);
9
}
10
11
void transmit(unsigned char addr, char data) 
12
{
13
     Load_Low();
14
  SPDR = addr;                      // Start transmission
15
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete
16
17
  asm volatile("nop");
18
19
  SPDR = data;                      // Start transmission
20
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
21
      Load_High();
22
}

Achso die Anzeige sollte nach dem Code doch blinken, aber das tut sie 
nicht. Das mit der 1 und 0 war ein anderer test der nicht funktionierte.

von ... (Gast)


Lesenswert?

was ich meinte ist dies hier:

transmit(0x0C,1);
transmit(0x09,0);

da sollte stehen:

transmit(0x0C,0x01);
transmit(0x09,0x00);

Außerdem solltest du alle Register erst mal initialisieren.

von Sam (Gast)


Lesenswert?

... schrieb:
> was ich meinte ist dies hier:
>
> transmit(0x0C,1);
> transmit(0x09,0);
>
> da sollte stehen:
>
> transmit(0x0C,0x01);
> transmit(0x09,0x00);
>

Das ist doch genau das selbe, oder?

> Außerdem solltest du alle Register erst mal initialisieren.

Reicht 0x0C 0x01 nicht?


Im Datenblatt hab ich nichts dergleichen gesehen. Kannst du mir 
vielleicht ein Beispiel geben.

von ... (Gast)


Lesenswert?

Sam schrieb:
> Das ist doch genau das selbe, oder?

nur wenn du es als uint8 definierst hast.

Sam schrieb:
> Im Datenblatt hab ich nichts dergleichen gesehen. Kannst du mir
> vielleicht ein Beispiel geben.
1
void max7219_Init(void) {
2
  transmit(0x0C,0x01);  // normal mode
3
  transmit(0x0A,0x01);  // set intensity 0x00 - 0x0F
4
  transmit(0x0B,0x07);  // scan digits 0-7
5
  transmit(0x09,0x00);  // no decoding
6
}

Digits angepassen auf deine Begebenheiten.

von Sam (Gast)


Lesenswert?

hab grad was gemerkt, das ding geht auch ohne Atmega an. Das heißt es 
wurde nie initalisiert. Ich werd mal die Datenleitungen überprüfen.

von Sam (Gast)


Lesenswert?

Ich hab CS mit CLK vertauscht???
Wie konnte das mir passieren?
Also es klappt nun wirklich. Danke für deine Mühe ... ...wenn ich ein 
bisschen mehr aufgepasst hätte hätte ich deine Hilfe nicht beanspruchen 
müssen.

von ... (Gast)


Lesenswert?

Man kann nur lernen... ;)

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.