Forum: Mikrocontroller und Digitale Elektronik MAX 7219 AVR Programm


von Anfänger (Gast)


Lesenswert?

Brauche ein AVR-Programm für den MAX 7219
Das Programm soll einfach von 1-9 hochzählen

von Stephan H. (stephan-)


Lesenswert?

Brauche ein Auto.
Es soll fahren.

von Anfänger (Gast)


Lesenswert?

Ja ich komm da halt nich weiter

ich hab zwar ein Code gefunden der geht aber nicht

Und hab halt nicht so viel erfahrung das ich weis wie man den 
umschreiebn muss  da der code geht

von ... .. (docean) Benutzerseite


Lesenswert?

dann zeig den Code doch mal...

von was-willst-du (Gast)


Lesenswert?

Was hat denn das Hochzählen einer Zahl mit dem Anzeigeprogramm zu tun???
Wie sieht denn die Hausaufgabe wirklich aus?

von Anfänger (Gast)


Lesenswert?

So das ist der Code hier sollten die for schleifen raus weil die nicht 
gehen und der befehl  next  auch nicht






; **********************************************************************
; *** Max7219 Displaytreiber-Ansteuerung
; *** Die Programmierung des Bausteins erfolgt seriell lt. Datenblatt
; *** (c) by Rainer Rick 3/2001
; **********************************************************************

; Quartzfrequenz: 12 MHz
; Prozessortyp (Es können natürlich auch andere verwendet werden):
INCLUDE 89c2051.mc

; Benutzte Portleitungen:
Max_Clock    EQU  P1.1
Max_ChipSelect  EQU  P1.2
Max_DataIn    EQU  P1.3

;Benutze Speicheradressen:
Max_Adresse    EQU  20h
Max_Daten    EQU  21h

;Benutze Register:
; A, R0, R1 = Zählregister (Temporär)


; **********************************************************************
; ***  Testprogramm:
; **********************************************************************
; ***  Zum Test des Displays werden alle Digits nacheinander hoch-
; ***  gezählt, jedes von 0 bis 9, um dann wieder bei 0 zu beginnen.
; **********************************************************************

Testprogramm:
  LCALL Max_DISP_INIT    ;Initialisierung des Max7219

  Endlosschleife:
    LCALL Max_DISP_CLEAR    ;Löschen der Anzeige
    FOR Max_Adresse = #1 to #8  ;Max_Adresse hochzählen
      FOR Max_Daten = #0h To #9h  ;Max_Daten hochzählen
        LCALL Max_DISP_OUT    ;Anweisung an den Max7219 senden
        LCALL Pause      ;Abwarten
      NEXT Max_Daten
    NEXT Max_Adresse
  LJMP Endlosschleife


; **********************************************************************
; *** Unterprogramm Max_DISP_INIT
; **********************************************************************
; *** Der Baustein Max7219 hat insgesamt 14 Register:
; ***   Adr.:    00: NOP (No Operation)
; ***         01-08: Digits 1-8
; ***            09: Dekodier-Modus (00h = 00000000 = keine Dekodierung
; ***                                01h = 00000001 = Dekodierung Dig0
; ***                                02h = 00000010 = Dekodierung Dig1
; ***                                ..  = ........ = Dekodierung ....
; ***                                FFh = 11111111 = Dekodierung 
Dig0-7)
; ***
; ***            0A: Helligkeit der Anzeige (00 = dunkel bis 0F = hell)
; ***            0B: Anzahl der verwendeten Digits
; ***            0C: Operation (1 = Normalbetrieb, 0 = Shutdown)
; ***            0F: Selbst Test (0 = Normalbetrieb, 1 = Display Test)
; *** genauere Beschreibung siehe Datenblatt!
; **********************************************************************

Max_DISP_INIT:
  MOV Max_Adresse,#0Bh  ;Adresse 0Bh = Scan Limit
  MOV Max_Daten,#07h  ;Scan Limit = 8 Digits
  LCALL Max_DISP_OUT  ;Anweisung an den Max7219 senden

  MOV Max_Adresse,#09h  ;Adresse 09h = Dekodiermodus
  MOV Max_Daten,#FFh  ;Dekodiermodus = FFh = > alle Digits dekodieren
  LCALL Max_DISP_OUT  ;Anweisung an den Max7219 senden

  MOV Max_Adresse,#0Ah  ;Adresse 0Ah = Helligkeit
  MOV Max_Daten,#0Fh  ;Helligkeit = 0Fh = > größte Helligkeit
  LCALL Max_DISP_OUT  ;Anweisung an den Max7219 senden

  MOV Max_Adresse,#0Ch  ;Adresse 0Ch = Operationsmodus
  MOV Max_Daten,#01h  ;Operationsmodus = 01h = > Normalbetrieb
  LCALL Max_DISP_OUT  ;Anweisung an den Max7219 senden
RET



; **********************************************************************
; *** Unterprogramm Max_DISP_CLEAR
; **********************************************************************
; *** Jedes Digit wird definiert zurückgesetzt (blank)
; **********************************************************************

Max_DISP_CLEAR:
  FOR Max_Adresse = #1 to #8  ;Digit 1-8 ansprechen
    MOV Max_Daten,#0Fh    ;0Fh = Alle Segmente aus, blank
    LCALL Max_DISP_OUT    ;Ausgabe an die Anzeige
  NEXT Max_Daten
RET


; **********************************************************************
; *** Unterprogramm Max_DISP_OUT
; **********************************************************************
; *** Adresse und Befehl werden seriell ausgegeben
; **********************************************************************

Max_DISP_OUT:
  CLR Max_ChipSelect  ;active LOW !

  ;HighByte (Adresse) ausgeben:
  MOV A,#10000000b
  MOV R2,A
  'Bit 0 - 7 der Max_Adresse in den MAX7219 schieben:
  FOR R3 = #0 to #7
  ANL A,Max_Adresse
  'Adressbit an den MAX7219 legen:
  IF A = #0 THEN
    CLR Max_DataIn
  ELSE
    SETB Max_DataIn
  END IF
  ;Bit in den MAX7219 schieben:
  SETB Max_Clock
  CLR Max_Clock
  ;Vergleichsbit durchrotieren
  MOV A,R2
  RR A
  MOV R2,A
  NEXT R3

  ;LowByte (Daten) ausgeben:
  MOV A,#10000000b
  MOV R2,A
  'Bit 0 - 7 der Max_Daten in den MAX7219 schieben:
  FOR R3 = #0 to #7
  ANL A,Max_Daten
  'Datenbit an den MAX7219 legen:
  IF A = #0 THEN
    CLR Max_DataIn
  ELSE
    SETB Max_DataIn
  END IF
  ;Bit in den MAX7219 schieben:
      SETB Max_Clock
      CLR Max_Clock
  ;Vergleichsbit durchrotieren
      MOV A,R2
      RR A
      MOV R2,A
  NEXT R3

  SETB Max_ChipSelect  'Übertragung der Adresse/Daten beendet
RET


; **********************************************************************
; *** Unterprogramm Pause
; **********************************************************************

Pause:
  FOR R0 = #0h To #5Fh
    FOR R1 = #0h To #FFh
      NOP
    NEXT R1
  NEXT R0
RET




Benutze das myavr LPT board falls das weiter helfen sollte

von Anfänger (Gast)


Lesenswert?

Antwort für  was-willst-du


Es soll halt erst auf den segmenten jeweils eine 1 angezeigt werden dann 
eine 2 und so weiter bis 9

Vielleicht hab ich mich ja falsch ausgedrückt

von Georg H. (schurli87)


Angehängte Dateien:

Lesenswert?

Habe einen Code von einem 8051. Kannst du 1:1 verwenden wenn du die I/O 
und Register, Headerfiles, etc... auf die AVR's anpasst.

Programmfehler darfst du nat. ausbessern und den anderen Usern zur 
Verfügung stellen.

Es wurden mehrere "Displays" mit je 5 7-Segment Anzeigen gebaut, die in 
serie Verbunden wurden.

mfg

von Stephan H. (stephan-)


Lesenswert?

@Georg,
ich glaube nicht das es was bringt.
Den andren Code bräuchte er ja auch nur anpssen.

>>So das ist der Code hier sollten die for schleifen raus weil die nicht
>>gehen und der befehl  next  auch nicht

von Stephan H. (stephan-)


Lesenswert?

@Anfänger,
Dir ist schon aufgefallen das der 1. Code für 8051 ist ???
Und der sieht eigentlich gut aus.
Die Schleifen sollten i.O. sein.

von Anfänger (Gast)


Lesenswert?

Das Programm geht nur zählt der hier nichts sondern sorgt nur dafür das 
alle segmente leuchten


#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>

void transmit(unsigned char, char);

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

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


void SPI_MasterInit(void) {

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

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

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

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_us(10);
    test_Init();

    tu was....

      while (1) {

     _delay_ms(10);

      }

   return 0;

}

von Anfänger (Gast)


Lesenswert?

Das Programm ist übrigens auch von hier.

von Stephan H. (stephan-)


Lesenswert?

ja eben. Jetzt baue noch Deine Zählschleife ein und gut ist.

von Anfänger (Gast)


Lesenswert?

Wo muss ich die genau rein schreiben an welche stelle

von Georg H. (schurli87)


Lesenswert?

Mach einfach ein Unterprogramm
1
void zaehle()
2
{
3
 for(int i=1; i<=9; i++)
4
  {
5
   write_to_display(i); //oder wie die Funktion zur ausgabe heißt
6
   _delay_ms(1000); //1 Sekunde dazwischen warten, sonst siehst du vom 
7
                    //Zählen nichts
8
  }
9
}

Beachte dass du die "delay.h" einbinden musst. Steht im AVR-GCC wie 
delay funktioniert.

Aufrufen kannst du diese dann überall (in deiner while(1) oder sonst wo)

von Anfänger (Gast)


Lesenswert?

Da leuchten immer noch einfach alle Digits und weis nicht warum 
stimmt das was mit den werten???


//----------------------------------------------------------------------
// Titel     : C Grundgerüst für das myAVR-Board
//----------------------------------------------------------------------
// Funktion  : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt     : 3.6864 MHz
// Sprache   : C
// Datum     : ...
// Version   : ...
// Autor     : ...
//----------------------------------------------------------------------
#define  F_CPU 3686400  // Taktferquenz des myAVR-Boards
#include <avr\io.h>
#include <avr/io.h>        //definiert DDRB
#include <util/delay.h>  //definiert delay_ms
#include <stdlib.h>  // AVR Register und Konstantendefinitionen
//----------------------------------------------------------------------
void uebertragung(unsigned char, char);

void Low()
{

  PORTB &= ~(1 << PB4);  //Bit auf 0 setzen
}

void High()
{
  PORTB |= (1 << PB4);   //Bit auf 1 setzen
}

void Master(void)
{

  DDRB = (1<<PB4)|(1<<PB5)|(1<<PB7);      // ganzen Port deklarieren

  SPCR = (1<<SPE)|(1<<MSTR);
  PORTB |= (1 << PB7)|(1 << PB4);     //Bit auf 1 setzen bei beiden 
Ports
}

void uebertragung(unsigned char addr, char data)
{

  SPDR = addr;                          //adresse in Datenregister
  while(!(SPSR & (1<<SPIF)));           //warten bis bits übertragen 
sind

  asm volatile("nop");                  //passiert nichts

  SPDR = data;                            //daten in Datenregister
  while(!(SPSR & (1<<SPIF)));            // warten bis bits übertragen 
sind
}

void test(void)
{
  Low();                     //Aufruf von Low
  for (int i = 0; i < 3; i++)    //for-schleife
  {


        uebertragung(0x0b, 0x03);//4 Digits
    _delay_ms(10);      //10ms warten
    uebertragung(0x0f, 0x00);//Testmode aus
    _delay_ms(10);      //10ms warten
    uebertragung(0x0c, 0x01);//Display an
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x08);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x01);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x02);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x03);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x04);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x05);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x07);
    _delay_ms(10);      //10ms warten
    uebertragung(0x01, 0x03);
    _delay_ms(10);      //10ms warten



  }

  High();                 //Aufruf von High
}

int main ()            // Hauptprogramm, startet bei Power ON und Reset

{

  Master();
  _delay_us(10);
  test();

  while (1)
  {

    _delay_ms(10);      //10ms warten
    return 0;
  }

}

//----------------------------------------------------------------------

von gast (Gast)


Lesenswert?

man oh man wieso muss das froum mit solchen drolls zugedröhnt werden.

mann hast du einen pecker oder was?

10ms das siehst du bestimmt mit freien auge, wenn nciht dann geh mal zum 
optiker und besorgt dir linsen :D

von gast (Gast)


Lesenswert?

ach und deine while schleifen, eionfach genial - der joke ist wirklcih 
gut :-)

von Gast (Gast)


Lesenswert?

Anfänger (Gast) wrote:
> Brauche ein AVR-Programm für den MAX 7219. Das Programm soll einfach
> von 1-9 hochzählen

Das Programmbeispiel das du dir oben hier aus dem Forum gezogen hast, 
passt nicht zu deiner Aufgabenstellung. Das Programm oben bezieht sich 
auf eine 4-stellige 8x8-Punkt-Matrix, wobei du die Initialisierung noch 
unterschlagen hast.

Klären wir doch erst mal die Grundlagen:

1. was für eine Anzeige willst du mit dem 7219 ansteuern?(7-Segment oder 
8x8 Punktmatrix?)
2. Wieviel Stellen soll die Anzeige haben.
3. Welcher Prozessor wird verwendet?

von Anfänger (Gast)


Lesenswert?

Antworten:

1. 7-Segment
2. -
3.Atmega 8

von georg (Gast)


Lesenswert?

wenn du nicht verrätst wieviel stellen das Display, oder mehrere Display 
mit den 7-Segment Anzeigen habe soll, wird dir keiner helfen wollen.

Sollen mehrere Displays angeschlossen werden? (man kann diese in serie 
Schalten)

von Anfänger (Gast)


Lesenswert?

Es werden 6 Displays angeschlossen

von Gast (Gast)


Lesenswert?

da er ja nur von 1 bis 9 Zählen will, gehe ich mal davon aus, dass er 
nur eine Stelle hat bzw. haben will.

von Gast (Gast)


Lesenswert?

ups. zu früh gefreut ;)

von georg (Gast)


Lesenswert?

dann ist mein Code gut für dich geeignet. Es ist zwar noch was dabei 
dass du nicht brauchst(Timer, Tastenabfragen, UART), aber die Routinen 
passen.
Ein fertiges Programm wird dir hier niemand schreiben. Fragen aber sehr 
wohl beantworten.

von Anfänger (Gast)


Lesenswert?

http://myavr.de/shop/article.php?artDataID=4     ich hab dieses board 
das problem das ich noch hab ist halt das immer alle segmente einmal 
kurz blinken und dann wieder aus und wieder an gehen  usw.

von Gast (Gast)


Lesenswert?

wie sieht denn dein Stromlaufplan für die Anzeige aus? kannst du den mal 
posten? An den max7219 kannst du ja bis zu 8 Stellen (Displays) 
anschließen.

von Anfänger (Gast)


Lesenswert?

http://www.fernando-heitor.de/content/view/54/109/1/3/   hier ist halt 
der schaltplan den ich benutze    und ist mit dem board an pin 2,3 und 5 
verbunden

von Gast (Gast)


Lesenswert?

öhm, sorry? Aber das ist der Prinzip-Stromlaufplan aus dem Datenblatt, 
der da abgebildet ist. Danach hast du deine Anzeige bestimmt nicht 
verdrahtet.
Zeig uns bitte deinen Stromlaufplan in aufgelöster Darstellung.

von Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

Das ist mein Platinenlayout halt   (fehlen en paar bahnen kein platz 
mehr vorhanden gewesen deshalb mit draht realisiert)

von Georg H. (schurli87)


Angehängte Dateien:

Lesenswert?

Hab mir mal die Mühe gemacht und aus einer meiner Dokus den MAX7219 Teil 
rauskopiert.

Wenn du damit noch immer Probleme hast, sag ich nichtsmehr dazu. 
Programmanalyse wird dir nicht erspart bleiben...

von Gast (Gast)


Lesenswert?

Anfänger (Gast) wrote:
> Das ist mein Platinenlayout halt   (fehlen en paar bahnen kein platz
> mehr vorhanden gewesen deshalb mit draht realisiert)

Du, das tut mir Leid das sagen zu müssen, aber das wird selbst mit einem 
einwandfreien Programm nicht funktionieren.

Die Max 7219 sind sehr empfindlich gegenüber schlechten Layouts.

So wie es ausschaut hast du wirklich nicht sehr viel Ahnung von der 
Materie und solltest vielleicht erst mal mit einfacheren Sachen 
anfangen. Oder du kaufst dir eine fertige Anzeigeeinheit, die du dann 
"nur" noch programmieren musst.

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.