www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik max7219 erst nach reset verwendbar


Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>

#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 definiert"
#define F_CPU 8000000UL /* Quarz mit 8 Mhz */
#endif 
#include <util/delay.h>
#include <stdlib.h>

void transmit(unsigned char, char);

void Load_Low()
{
  PORTB &= ~(1 << PB2);
}

void Load_High()
{
  PORTB |= (1 << PB2);
}


void SPI_MasterInit(void) {

    DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input

    SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4

    PORTB |= (1 << PB7)|(1 << PB2);
}

void transmit(unsigned char addr, char data) {

  SPDR = addr;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete

  asm volatile("nop");

  SPDR = data;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
}

void test_Init(void)
{
  Load_Low();
  for (int i = 0; i < 3; i++)
  {
  transmit(0x0C,0x01);            // normal mode  transmit(0x0C,0x01);
  }
  Load_High();
}

int main()
{

    SPI_MasterInit();
    _delay_ms(10);
    test_Init();

    //tu was....

      while (1) 
      {

     _delay_ms(10);

      }

   return 0;

}

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

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?

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code für deinen Aufbau (Test) müsste aussehen:
#include <avr/io.h>

#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 definiert"
#define F_CPU 8000000UL /* Quarz mit 8 Mhz */
#endif 
#include <util/delay.h>
#include <stdlib.h>

void transmit(unsigned char, char);

void Load_Low()
{
  PORTB &= ~(1 << PB2);
}

void Load_High()
{
  PORTB |= (1 << PB2);
}


void SPI_MasterInit(void) {

    DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input

    SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4

    PORTB |= (1 << PB7)|(1 << PB2);
}

void transmit(unsigned char addr, char data) {

  SPDR = addr;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete

  asm volatile("nop");

  SPDR = data;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
}

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

int main()
{

    SPI_MasterInit();
    _delay_ms(10);
    test_Init();

    //tu was....

      while (1) 
      {

     _delay_ms(10);

      }

   return 0;

}

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sam schrieb:
> ohne Klammern halt

ja, sorry.

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab doch noch ne Frage:

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

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

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

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

Autor: Sam (Gast)
Datum:
Angehängte Dateien:

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

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);      // set PB2(SS), PB3 (MOSI) and PB5 (SCK) output, all others input
SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4
PORTB |= (1 << PB7)|(1 << PB2);

transmit(0x0C,1); 
transmit(0x09,0);
transmit(0x0B,0x07);
while(1)
{
for(uint8_t i = 1; i!=9;i++)
        transmit(i,0);  
_delay_ms(500);
for(uint8_t i = 1; i!=9;i++)
        transmit(i,255);   
_delay_ms(500);

} 


und noch transmit
void Load_Low(void)
{
  PORTB &= ~(1 << PB2);
}

void Load_High(void)
{
  PORTB |= (1 << PB2);
}

void transmit(unsigned char addr, char data) 
{
     Load_Low();
  SPDR = addr;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete

  asm volatile("nop");

  SPDR = data;                      // Start transmission
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
      Load_High();
}

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.

Autor: ... (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
void max7219_Init(void) {
  transmit(0x0C,0x01);  // normal mode
  transmit(0x0A,0x01);  // set intensity 0x00 - 0x0F
  transmit(0x0B,0x07);  // scan digits 0-7
  transmit(0x09,0x00);  // no decoding
}

Digits angepassen auf deine Begebenheiten.

Autor: Sam (Gast)
Datum:

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

Autor: Sam (Gast)
Datum:

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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann nur lernen... ;)

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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