www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MAX7219 Ansteuerung


Autor: bän (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi ich habe Probleme den MAX7219 anzusteuern. Ich habe mir eine LED 
Matrix gebaut und versuche gerade die Matrix über den IC anzusteuern.

Für die Ansteuerung nehme ich einen Controller aus der 8051er Reihe. 
Hier ist das Programm welches ich für die Ansteuerung geschrieben habe:

#include <reg517a.h>

sbit CLOCK = P4 ^ 0x00;
sbit DIN = P4 ^ 0x01;
sbit LOAD = P4 ^ 0x02;

void sendData(unsigned char reg_adr, unsigned char daten);

void main(void)
{
  LOAD = 1;
  CLOCK = 0;
  DIN = 1;
  
  sendData(0x09, 0x00); // No Decode Mode
  sendData(0x0A, 0x0B); //mittlere Helligkeit einstellen
  sendData(0x0B, 0x07); //max. Scan Limit
  sendData(0x0C, 0x00); //Normal Operation
  sendData(0x0f, 0x00); //Test Normal Operation

  sendData(0x0C, 0x01);

  sendData(0x01, 0x00);
  sendData(0x02, 0x00);
  sendData(0x03, 0x00);
  sendData(0x04, 0x00);
  sendData(0x05, 0x00);
  sendData(0x06, 0x00);
  sendData(0x07, 0x00);

  while(1);
}

void sendData(unsigned char reg_adr, unsigned char daten)
  { 
  unsigned char Teiler = 128;      // Hilfsvariable zum maskieren der 8 Bit
  unsigned char i;          // Schleifenvariable
    LOAD = 0;              // Startsignal der seriellen Datenübertragung zum MAX7219!
  for(i=1; i<=8; i++)          // Schleife zum seriellen Ausgeben der 8 Adress-Bits!
    {
    if(reg_adr & Teiler) DIN = 1;  // Entsprechendes Bit mit Hilfe der bitweisen UND-Verknüpfung 
      else DIN = 0;          // maskieren und auf der DIN-Leitung ausgeben!
    CLOCK = 1;            // Takt auf Taktleitung ausgeben, also zuerst Taktleitung
    CLOCK = 0;            // auf log. 1, danach wieder auf log. 0 setzen!
    Teiler = Teiler / 2;      // Hilfsvariable für nächsten Schleifendurchlauf vorbereiten!
    }
  Teiler = 128;            // Hilfsvariable wieder auf Startwert setzen!
  for(i=1; i<=8; i++)          // Schleife zum seriellen Ausgeben der 8 Daten-Bits!
    {
    if(daten & Teiler) DIN = 1;    // Entsprechendes Bit mit Hilfe der bitweisen UND-Verknüpfung 
      else DIN = 0;          // maskieren und auf der DIN-Leitung ausgeben!
    CLOCK = 1;            // Takt auf Taktleitung ausgeben, also zuerst Taktleitung
    CLOCK = 0;            // auf log. 1, danach wieder auf log. 0 setzen!
    Teiler = Teiler / 2;      // Hilfsvariable für nächsten Schleifendurchlauf vorbereiten!
    }
  DIN = 0;              // Serielle Datenleitung auf log. 0!
  LOAD = 1;              // Stoppbedingung der seriellen Datenübertragung zum MAX7219!
  }

Durch Recherchen habe ich erfahren wie ich diesen IC Initialisieren 
muss. Ich hoffe ich habe soweit alles richtig gemacht. Da die LEDs 
immernoch permanent leuchten weiß ich nicht mehr weiter. Eigentlich habe 
ich sie per Programmcode ausgeschaltet.

Gruß
bän

Autor: Vorsicht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der MAX7219 liest die Daten auf die poitive Clock Flanke ein.

Du erzeugst aber nach dem Ausgeben der Daten eine negative Flanke.

Ich schreibe so:
void max7219WriteReg( UInt8 reg, UInt8 value ) {

  UInt8 mask;
  
  //printf( "Register %02X\n", reg );
  //printf( "Value    %02X\n", value );
  
  PDR5_P50     =    0;  // load low
  
  mask = 0x80;
  while ( mask ) {
    PDR4_P47     =    0;  // clock low
    if ( mask & reg ) {
      PDR4_P46     =    1;  // data high
      //printf( "1", value );
    }
    else {
      PDR4_P46     =    0;  // data low
      //printf( "0", value );
    }
    PDR4_P47     =    1;  // clock high
    mask >>= 1;
  }
  //printf( "\n", value );
  
  mask = 0x80;
  while ( mask ) {
    PDR4_P47     =    0;  // clock low
    if ( mask & value ) {
      PDR4_P46     =    1;  // data high
      //printf( "1", value );
    }
    else {
      PDR4_P46     =    0;  // data low
      //printf( "0", value );
    }
    PDR4_P47     =    1;  // clock high
    mask >>= 1;
  }
  //printf( "\n", value );
  
  PDR5_P50     =    1;  // load high
  PDR4_P46     =    0;  // data low
  PDR4_P47     =    0;  // clock low
  
}

Damit klappt es bei mir wunderbar.

Gruss

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

void displaywrite( uint dc )
{
  uchar i = 12;
  do{
    DISDAT = dc & 0x0800;
    dc <<= 1;
    DISCLK = 1;
    DISCLK = 0;
  }while( --i );
  DISDAT = 0;
  DISSTB = 1;
  DISSTB = 0;
}


void displayinit( void )
{
  DISCLK = 0;
  DISSTB = 0;
  displaywrite( 0xF00 );                // Testmode off
  displaywrite( 0x900 );                // Decode off
  displaywrite( 0xB07 );                // 8 Digits
  displaywrite( 0xC01 );                // Display on
  displaywrite( 0xA00 | BRIGHT );       // Brightness
}



Peter

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.