MAX 7219 AVR Programm

Gast #1203357
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
Gast #1207851
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;

}
#1210404
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)
Gast #1213277
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;
  }

}

//----------------------------------------------------------------------
Gast #1213299
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
Gast #1213322
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?
Gast #1214139
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)
Gast #1214173
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.
Gast #1214208
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.
Gast #1214310
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren