www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wieder mal MAX7219 (Problem mit Programm oder Schaltung?)


Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich bin nun seid zwei Tagen schon am rumprobieren und lese hier im Forum 
alles mögliche.

Ich habe einen ATmega8515 auf einem STK500 Board. Die LEDs des Boards 
sind mit Port C verbunden. Pin PB7 ist am Pin 13 (CLK) vom MAX7219. Pin 
PB5 am Pin 1 des MAX und Pin PB3 (LOAD) am Pin 12 des MAX. Ist also so 
verkabelt wie im Datenblatt des MAX auf seite 1 unten rechts.

Dann bin ich beim suchen auf diesen Beitrag gestoßen: 
Beitrag "MAX 7219 mit SPI ansteuern?"
Da hab ich dann einfach mal den Quelltext kopiert und an meinen 
ATmega8515 angepasst (PB3 statt PB2).

+5 Volt und GND werden auch vom STK500 zum MAX geholt.

Ich sende in meiner main() nur den Code für den LED Test an den MAX. 
Aber es bleibt alles dunkel. Ich hab die Schaltung jetzt schon zwei mal 
kontrolliert, kann aber keinen Fehler finden.

Da der kopierte Code ja bei Christian funktioniert und meine LEDs auch 
blinken (das Programm also offensichtlich durchläuft) tippe ich auf ne 
kaputte Schaltung oder einen Gedankenfehler beim initialisieren des MAX.

Gibts ne Möglichkeit die Schaltung zu testen?
#include <avr/io.h>
#include <avr/delay.h>

void SPI_MasterInit(void)
{
    /* LOAD (DDB3), MOSI (DDB5) und SCK (DDB7) als Ausgänge schalten */
  DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB7);

    /* SPI einschalten, SPI Master aktivieren, Frequenz auf fck/16 */
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

    /* PullUp Wiederstände an SCK und SS aktivieren */
    PORTB |= (1 << PB5)|(1 << PB3);
}

void SPI_Transmit(char addr, char data) {
  PORTB &= ~(1 << PB3);         // LOAD auf low setzen

  SPDR = addr;                  // Byte in Register schreiben und damit Übertragung starten
  while(!(SPSR & (1<<SPIF)));   // Warten, bis SPIF gesetzt ist
  
  SPDR = data;                  // Byte in Register schreiben und damit Übertragung starten
  while(!(SPSR & (1<<SPIF)));   // Warten, bis SPIF gesetzt ist

  PORTB |= (1 << PB3);          // LOAD auf high setzen
}
 
int main (void) {
 
    DDRC  = 0xff;               // PORT C als Ausgang schalten
    PORTC = 0x00;               // alle LEDs an (invertiert wegen STK500)

    _delay_ms(1000);            // Pause

  SPI_MasterInit();           // SPI initialisieren
  SPI_Transmit(0x0F,0x00);    // Daten senden
   
    while(1){
        PORTC = 0xAA;           // LEDs blinken im wechsel
        _delay_ms(500); 
        PORTC = 0x55;
        _delay_ms(500); 
    };

    return 0;
}

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du solltest den 7219 erstmal initialisieren, ungefähr so:
.....
void max7219_Init(void) {
  transmit(0x0C,0x01);  // normal mode
  transmit(0x0A,0x01);  // set intensity 0x00 - 0x0F
  transmit(0x0B,0x07);  // scan digits 0-7, entsprechend deiner Schaltung
  transmit(0x09,0x00);  // no decoding, entsprechend deiner Schaltung
}
int main (void) {
 
    DDRC  = 0xff;               // PORT C als Ausgang schalten
    PORTC = 0x00;               // alle LEDs an (invertiert wegen STK500)

    _delay_ms(1000);            // Pause

  SPI_MasterInit();           // SPI initialisieren
  max7219_Init();
  SPI_Transmit(0x0F,0x00);    // Daten senden
......

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
transmit heißt bei dir natürlich SPI_Transmit

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, Danke für den Hinweis. Das ist natürlich selten dämlich von mir. Da 
mach ich mir die ganze Zeit Gedanken über das initieren des ATmega und 
vergesse den MAX dabei.

Ich hab das jetzt nachgeholt und es hat sich was getan. Leider nicht 
das, was ich erwartet habe.

Wenn das Programm startet, dann leuchten erst alle LEDs an Port C des 
µC. Dann wird der 8515 und danach der MAX initialisiert. Dann sieht man, 
wie bei den 7-Segment Anzeigen kurz ein paar Segmente aufblinken. Das 
sind immer unterschiedliche. Und danach sind die auch sofort wieder 
dunkel.

Danach blinken dann die LEDs an Port C des µC wieder. Also bin ich in 
der Endlosschleife der main() angekommen.

Woran kann das jetzt liegen? Hat jemand ne Idee, wie ich den MAX testen 
kann?

Hier noch mal mein abgeänderter Code:
#include <avr/io.h>

#ifndef F_CPU
#define F_CPU 1843200
#endif

#include <util/delay.h>

void SPI_MasterInit(void)
{
    /* LOAD (DDB3), MOSI (DDB5) und SCK (DDB7) als Ausgänge schalten */
  DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB7);

    /* SPI einschalten, SPI Master aktivieren, Frequenz auf fck/16 */
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

    /* PullUp Wiederstände an SCK und SS aktivieren */
    PORTB |= (1 << PB5)|(1 << PB3);
}

void SPI_Transmit(char addr, char data) {
    
    PORTB &= ~(1 << PB3);         // LOAD auf low setzen

    SPDR = addr;                  // Byte in Register schreiben und damit Übertragung starten
    while(!(SPSR & (1<<SPIF)));   // Warten, bis SPIF gesetzt ist
  
    SPDR = data;                  // Byte in Register schreiben und damit Übertragung starten
    while(!(SPSR & (1<<SPIF)));   // Warten, bis SPIF gesetzt ist

    PORTB |= (1 << PB3);          // LOAD auf high setzen
}

void max7219_Init(void) {
    SPI_Transmit(0x0C,0x01);  // normal mode
    SPI_Transmit(0x0A,0x08);  // set intensity 0x08
    SPI_Transmit(0x0B,0x01);  // scan digits 0-1
    SPI_Transmit(0x09,0xFF);  // Code B for all
}

int main (void) {
 
    DDRC  = 0xff;               // PORT C als Ausgang schalten
    PORTC = 0x00;               // alle LEDs an (invertiert wegen STK500)

    _delay_ms(1000);            // Pause

  SPI_MasterInit();           // SPI initialisieren
    max7219_Init();             // MAX initialisieren

  SPI_Transmit(0x01,0x01);    // Digit 1 auf Zahl 1
    SPI_Transmit(0x02,0x02);    // Digit 2 auf Zahl 2

    while(1){
        PORTC = 0xAA;           // LEDs blinken im wechsel
        _delay_ms(500); 
        PORTC = 0x55;
        _delay_ms(500); 
    };

    return 0;
}

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Brehme schrieb:
> Pin PB3 (LOAD)

PB3 ist nicht der SS-Pin der SPI Einheit im ATmega8515.
Das kannst du natürlich so machen, musst aber dafür Sorge tragen, dass 
der SS-Pin des ATmega8515 (PB4) auf 1-Potential liegt, ansonsten 
schaltet die SPI-Einheit in den Slave-Modus.
/* LOAD (DDB3), MOSI (DDB5) und SCK (DDB7) als Ausgänge schalten */
    DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB7)|(1<<DDB4);
 /* PullUp Widerstände an SCK und SS und PB3 aktivieren */
    PORTB |= (1 << PB5)|(1 << PB3)|(1 << PB4);

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
btw. es ist immens wichtig, das direkt an dem V+ -Pin gegen GND-Pin des 
Max ein 10µF Kondensator geschaltet ist. Ansonsten macht der 7219 was er 
will.

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die beiden Hinweise. Das mit dem SS auf high hab ich - jetzt 
wo du es schreibst - irgendwo gelesen, aber leider nicht mehr auf dem 
Schirm gehabt.

Das mit dem Kondensator ist mir neu. Aber auch das werde ich heute abend 
ausprobieren.

Martin

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo " ... (Gast) ",

sollten wir uns mal über den Weg laufen, erinner mich drann, das du ein 
Bier von mir bekommst. Der Kondensator wars! Man was hat mich das Nerven 
gekostet :-)

Nun gut. Nun kanns ja weitergehen ...

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin,

schön das es  jetzt funktioniert.

Das mit dem Kondensator steht aber auch im Datenblatt:

"Applications Information

Supply Bypassing and Wiring

To minimize power-supply ripple due to the peak digit
driver currents, connect a 10µF electrolytic and a 0.1µF
ceramic capacitor between V+ and GND as close to
the device as possible. The MAX7219/MAX7221 should
be placed in close proximity to the LED display, and
connections should be kept as short as possible to
minimize the effects of wiring inductance and electro-
magnetic interference. Also, both GND pins must be
connected to ground."

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, was lerne ich daraus: In E-Technik bin ich noch schlechter als im 
programmieren :-)

Ich werd wohl die Datenblätter demnächst nur noch mit nem Textmarker in 
der Hand lesen - ich hab das echt nicht mehr auf dem Schirm gehabt.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Brehme schrieb:
> Tja, was lerne ich daraus: In E-Technik bin ich noch schlechter als im
> programmieren :-)

Jetzt aber nicht verzweifeln, zur Not gibt es ja noch so alte Männer wie 
mich und das Forum hier... ;)

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Martin Brehme schrieb:
>> Tja, was lerne ich daraus: In E-Technik bin ich noch schlechter als im
>> programmieren :-)
>
> Jetzt aber nicht verzweifeln, zur Not gibt es ja noch so alte Männer wie
> mich und das Forum hier... ;)

Ne, wenn ich verzweifeln würde, hätte ich den Smilie weggelassen. 
Allerdings hat mir das jetzt deutlich meine Grenzen in der E-Technik 
aufgezeigt. Ich bin aber froh, das ich nun endlich - nach langer Pause - 
wieder am µContrller sitze.

Die nächsten Fragen sammeln sich hier schon ... dann aber in nem neuen 
Thread.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[Neugier an]
Darf man fragen, was das werden soll?
[Neugier aus]

Autor: Martin B. (methusalem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Anzeigen von Daten auf den 7 Segment Bausteinen war ein Einstieg in 
die AVR µController für mich. Das geht auch noch weiter ... nebenher 
acker ich die Tutorials hier durch.

Ziel ist das hier: Beitrag "Konzept zum Auswerten von Lichtschranken gesucht"

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.