Forum: Mikrocontroller und Digitale Elektronik LED-Matrix 32x16 mit ATMEGA32_ Lauflicht darstellen


von Philipp K. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich bin grade in der Praxisphase und komme immernoch nicht weiter mit 
meinem
Projekt.
Deswegen brauche ich unbedingt Hilfe. ) Programmiere grad in C mit der 
32x16 LED_ Matrix(aus China, ist nicht arduino)
Als Prozessor benutze ich den ATMEGA32 auf einer extra Platine und
steuer damit das Modul an.

Dieser untenaufgeführte Code ist mein Beispielprogramm wie ich ein Pixel
durch das ganze Modul als eine Art Lauflicht darstelle.
Schaffe es derzeit mit dem Code nur so wie auf dem Bild die 
dargestellten Zahlen sind zu durchlaufen, so funktioniert auch die 
Matrix und so ist Sie aufgebaut.
Wie kann ich nun den Pixel erst komplett durch die Reihen schieben??
Also(Die Zahlen 0 bis 7, dann 32 bis 39, dann 64 bis 71, dann 96 bis 
103) und dann so weiter???
Iwie mit Schleifen oder evtl Funktionen?


#define F_CPU 14745600    //Quarz mit 14.745 MHz
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>



#define KANAL_A_DDR      DDRB
#define KANAL_A_PORT      PORTB
#define KANAL_A_NUMBER      PB7

#define KANAL_B_DDR      DDRB
#define KANAL_B_PORT      PORTB
#define KANAL_B_NUMBER      PB6

#define KANAL_C_DDR      DDRB
#define KANAL_C_PORT      PORTB
#define KANAL_C_NUMBER      PB5

#define CLK_DDR        DDRB
#define CLK_PORT      PORTB
#define CLK_NUMBER      PB4

#define LATCH_DDR      DDRB
#define LATCH_PORT      PORTB
#define LATCH_NUMBER      PB3

#define REDDATA_DDR      DDRB
#define REDDATA_PORT      PORTB
#define REDDATA_NUMBER      PB2

#define KANAL_D_DDR      DDRB
#define KANAL_D_PORT      PORTB
#define  KANAL_D_NUMBER      PB1

#define OUTPUTENABLE_DDR    DDRB
#define OUTPUTENABLE_PORT    PORTB
#define OUTPUTENABLE_NUMBER    PB0

int main(void){

//PORTB = Ausgang
DDRB = 0xff;

// Ausgangswerte auf 0 initialisieren, Reihe 1, 5, 9, 13
PORTB = 0xE7;
_delay_ms(10);

// Den Wert des ersten Pixels reinschieben.
PORTB |= (1<<PB2);
_delay_ms(10);

//Taktflanke erzeugen
PORTB |= (1<<PB4);
_delay_ms(10);

//fallende Flanke
PORTB &= ~(1<<PB4);
_delay_ms(10);

// Ausgangsposition alle drei Speicher werden auf 0 gesetzt
PORTB &= ~(1<<PB2);
_delay_ms(10);

// Latchflanke wird erzeugt
PORTB |= (1<<PB3);
_delay_ms(10);

  while(1){

       PORTB &= ~(1<<PB4);
       _delay_ms(10);


      PORTB &= ~(1<<PB2);
      _delay_ms(10);


      PORTB &= ~(1<<PB3);
      _delay_ms(10);


      PORTB |= (1<<PB2);
      _delay_ms(10);


      PORTB |= (1<<PB4);
      _delay_ms(10);


      PORTB &= ~(1<<PB4);
      _delay_ms(10);


      PORTB &= ~(1<<PB2);
      _delay_ms(10);


      PORTB |= (1<<PB3);
      _delay_ms(10);

  }
}

von yesitsme (Gast)


Lesenswert?

Zum Glück gibt es nur eine chinesische 32x16 LED Matrix...

Hast du ein Datenblatt?
Hat die einen Framebuffer oder muss die Anzeige ständig aktualisiert 
werden?

von Philipp K. (Gast)


Lesenswert?

Hab leider kein Datenblaat von der LED_ Matrix...
Nur von den einzelnen ICS die da verbaut sind.

von Thomas W. (diddl)


Lesenswert?

Philipp K. schrieb:
> Nur von den einzelnen ICS die da verbaut sind.

Die da wären?

Welche IC sind da verbaut?

von Karl M. (Gast)


Lesenswert?

Philipp K.,

da frage ich mich, wie will man ein Programm richtig schreiben, wenn man 
keinen Schaltplan und keine Ahnung von dem "Wie" hat.

Insgesamt gesehen ist das Programmdesign nicht nach den aktuellen Wissen 
der prog. Gesellschaft ausgerichtet.

Mal einfach skizziert:
* Bildausgabe über einen Timer Interrupt mit ausreichend hoher
Wiederholfrequenz.
Tip: Ich sehe, real mit meinen Augen/ Gehirn, noch <100 Hz als flackern 
an.

* 2 Frampuffer für das darzustellende "Bild"
# über einen Frampuffer wird das aktuelle Bild im Hintergrund 
dargestellt
# in den weiteren Frampuffer schreibt/ erstellt das Hauptprogramm ein 
neues "Bild". Anschließend wird der Frampuffer für den 
Hintergrundprozess umgeschaltet und wir sehen das "neue" Bild in der 
Ausgabe.

von Philipp K. (Gast)


Lesenswert?

Die ICs 74HC04, 74HC138, 74HC245, 74HC595 sind verbaut.

Das sind halt die Standardanweisungen wie ich das gelernt habe mit PORT, 
DDRB und so.
Bin halt auch nicht der super Programmierer in Mikrocontroller...
Kenne meist halt die Standardanweisungen wie Sie in meinem Skript 
stehen.
Deswegen brauche ich ja Hilfe ich hab keine Ahnung wie ich die LED 
Matrxi weiterbetreiben soll...

von Karl M. (Gast)


Lesenswert?

Philipp K.,

sei so nett und erstelle einen kompletten Schaltplan und poste ihn hier.

Falls Die ein Schaltplan und Platinen Zeichenprogramm fehlt, dann schaue 
bitte mal hier:

https://www.expresspcb.com/

Du hast in den Programmbeispiel schon einige Defines angelegt, aber 
arbeitest damit nicht.
1
#define CLK_DDR DDRB
2
#define CLK_PORT PORTB
3
#define CLK_NUMBER PB4
Daraus kann man weitere Macros oder Funktionen, wie diese hier, 
ableiten:
1
#define CLK_DELAY 1 // 1ms
2
3
void clk_toggle(void) {
4
CLK_PORT |= (1<< CLK_NUMBER);
5
_delay_ms(CLK_DELAY);
6
CLK_PORT &= ~(1<< CLK_NUMBER);
7
}
1
#define LATCH_DDR DDRB
2
#define LATCH_PORT PORTB
3
#define LATCH_NUMBER PB3
4
5
#define LATCH_OFF() LATCH_PORT &= ~(1<<LATCH_NUMBER)
6
#define LATCH_ON()  LATCH_PORT |= (1<<LATCH_NUMBER)

Durch diese "Zwischenschicht" wird ein Programm erst "lesbar" und 
selbsterklärend. Das ist sehr wichtig, für andere Leser und um es auch 
weiter Pflegen zu können.

Es gibt auch noch weitere Möglichkeiten, aber ich denke, wenn Du eine 
Idee und die bessere Lesbarkeit eines Programms erkennst, wirst Du einen 
Schritt weiter kommen.

von Karl M. (Gast)


Lesenswert?

Dann hilft Dir sicherlich auch diese Zusammenstellung für die avr gcc 
Programmierung:

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Natürlich muss man Einzelheiten immer am aktuellen Datenblatt deines 
Atmel AVR µC fest machen.

von Philipp K. (Gast)


Lesenswert?

Das ist mein Programm in AVR Studio 6.1. Die Sachen mit PORTB und DDRB 
habe ich so gelernt. Das mit den definierten Sachen mit Number habe ich 
von meinem Betreuer beigebracht bekommen das man es besser lesen kann.
Aber ich komme eher mit der PORT deklaration zurecht
Die sind in meinem Programm auskommentiert, sind aber die dieselben 
Befehle.



#define KANAL_A_DDR        DDRB
#define KANAL_A_PORT      PORTB
#define KANAL_A_NUMBER      PB7

#define KANAL_B_DDR        DDRB
#define KANAL_B_PORT      PORTB
#define KANAL_B_NUMBER      PB6

#define KANAL_C_DDR        DDRB
#define KANAL_C_PORT      PORTB
#define KANAL_C_NUMBER      PB5

#define CLK_DDR          DDRB
#define CLK_PORT        PORTB
#define CLK_NUMBER        PB4

#define LATCH_DDR        DDRB
#define LATCH_PORT        PORTB
#define LATCH_NUMBER      PB3

#define REDDATA_DDR        DDRB
#define REDDATA_PORT      PORTB
#define REDDATA_NUMBER      PB2

#define KANAL_D_DDR        DDRB
#define KANAL_D_PORT      PORTB
#define  KANAL_D_NUMBER      PB1

#define OUTPUTENABLE_DDR    DDRB
#define OUTPUTENABLE_PORT    PORTB
#define OUTPUTENABLE_NUMBER    PB0

#define TASTER_DDR        DDRC
#define TASTER_PORT        PORTC
#define TASTER_NUMBER      PC0
#define TASTER_PIN        PINC



int main(void){

  // Alle Ports als Ausgänge konfigurieren.
  //KANAL_A_DDR &= ~ (1<<KANAL_A_NUMBER);
  //KANAL_B_DDR |= (1<<KANAL_B_NUMBER);
  //KANAL_C_DDR |= (1<<KANAL_C_NUMBER);  // Kanal C nicht belegt
  //CLK_DDR |= (1<<CLK_NUMBER);
  //LATCH_DDR |= (1<<LATCH_NUMBER);
  //REDDATA_DDR |= (1<<REDDATA_NUMBER);
  //KANAL_D_DDR |= (1<<KANAL_D_NUMBER);  // Kanal D nicht belegt
  //OUTPUTENABLE_DDR |= (1<<OUTPUTENABLE_NUMBER);
  DDRB = 0xff;      //PORTB = Ausgang




  // OE auf 1 setzen.Ansonsten leuchtet gar keine LED auf der Matrix
  //OUTPUTENABLE_PORT |= (1<<OUTPUTENABLE_NUMBER);

        //Ausgangswerte auf 0 initialisieren, Reihe 1, 5, 9, 13
  //KANAL_A_PORT  |=  (1<<KANAL_A_NUMBER);
  //KANAL_B_PORT  |= (1<<KANAL_B_NUMBER);
  //CLK_PORT &= ~(1<<CLK_NUMBER);
  //REDDATA_PORT &= ~ (1<<REDDATA_NUMBER);
  //LATCH_PORT &= ~(1<< LATCH_NUMBER);
  //OUTPUTENABLE_PORT |= (1<<OUTPUTENABLE_NUMBER);
        //OE auf 1 setzen. Ansonsten leuchtet gar keine LED auf der 
Matrix
  PORTB = 0xB1;
  _delay_ms(10);

  // Den Wert des ersten Pixels reinschieben.
  //REDDATA_PORT |= (1<<REDDATA_NUMBER);
  PORTB |= (1<<PB2);
  _delay_ms(10);

  //Taktflanke(CLK) erzeugen, damit der erste Pixel in das 
Schieberegister uebernommen wird.
  //Alle Pixelwerte in den Schieberegistern rutschen dann nach rechts.
  //Latchflanke(LATCH) erzeugen, damit alle Pixel von den 
Schieberegistern in die Anzeige uebernommen(kopiert) werden.

  //Taktflanke erzeugen
  //CLK_PORT |= (1<<CLK_NUMBER);
  PORTB |= (1<<PB4);
  _delay_ms(10);

  //fallende Flanke
  //CLK_PORT &= ~(1<<CLK_NUMBER);
  PORTB &= ~(1<<PB4);
  _delay_ms(10);

  // Ausgangsposition alle drei Speicher werden auf 0 gesetzt
  //REDDATA_PORT &= ~(1<<REDDATA_NUMBER);
  PORTB &= ~(1<<PB2);
  _delay_ms(10);

  // Latchflanke wird erzeugt, die gespeicherten Daten in REDDATA werden 
in das Schieberegister ubernommen(kopiert).
  //LATCH_PORT |= (1<< LATCH_NUMBER);
  PORTB |= (1<<PB3);
  _delay_ms(10);



    for(int i = 0; i < 128; i++){



      //CLK_PORT &= ~(1<< CLK_NUMBER);
      PORTB &= ~(1<<PB4);
      _delay_ms(10);

      //REDDATA_PORT  &= ~(1<< REDDATA_NUMBER);
      PORTB &= ~(1<<PB2);
      _delay_ms(10);

      //LATCH_PORT &= ~(1<< LATCH_NUMBER);
      PORTB &= ~(1<<PB3);
      _delay_ms(10);

      //REDDATA_PORT |= (1<<REDDATA_NUMBER);
      PORTB |= (1<<PB2);
      _delay_ms(10);

      //CLK_PORT |= (1<<CLK_NUMBER);
      PORTB |= (1<<PB4);
      _delay_ms(10);

      //CLK_PORT &= ~(1<<CLK_NUMBER);
      PORTB &= ~(1<<PB4);
      _delay_ms(10);

      //REDDATA_PORT &= ~(1<< REDDATA_NUMBER);
      PORTB &= ~(1<<PB2);
      _delay_ms(10);

      //LATCH_PORT |= (1<<LATCH_NUMBER);
      PORTB |= (1<<PB3);
      _delay_ms(10);

        }
}

von Mikro 7. (mikro77)


Lesenswert?

Karl M. schrieb:
> sei so nett und erstelle einen kompletten Schaltplan und poste ihn hier.

Das wird wohl sowas ähnliches wie das hier sein:

http://www.ebay.de/itm/371243010614?_trksid=p2055119.m1438.l2649&ssPageName=STRK%3AMEBIDX%3AIT

ABCD zur Zeilenauswahl. Da er "REDDATA" definiert hat gibt es vielleicht 
dann auch Grün, wie im Angebot, oder seins ist tatsächlich ein bisschen 
anders (im Angebot sind auch keine Level Shifter ICs).

Das Problem ist, dass der TS offensichtlich weder von der Ansteuerung 
noch von C-Programierung viel Ahnung hat (Ist auch schon sein zweiter 
Thread zum Thema hier.) Ich wüßte daher nicht wo man anfangen sollte um 
zu helfen... :-(

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Karl M. schrieb:
> Du hast in den Programmbeispiel schon einige Defines angelegt, aber
> arbeitest damit nicht.

> Daraus kann man weitere Macros oder Funktionen, wie diese hier,
> ableiten:

> Durch diese "Zwischenschicht" wird ein Programm erst "lesbar" und
> selbsterklärend. Das ist sehr wichtig, für andere Leser und um es auch
> weiter Pflegen zu können.

 Das nächste Mal etwas langsamer antworten, bitte.
 Worüber soll ich jetzt meckern ?

von Marco H. (damarco)


Lesenswert?

Dein Problem ist das du einen Pixel setzt und dann gleich den latch 
betätigst. Der Code ist grausam mit den Delay etc.  Der Tip C zu lernen 
ist nicht ganz verkehrt dann die Aufgabe ist schon etwas anspruchsvoll.

So schiebst du immer das selbe rein.

1. Zeilennummer wählen
2. Daten anlegen
3. Clock erzeugen
4. Daten anlegen
5. Clock erzeugen

usw.

1. Zeilennummer wählen
2. Daten anlegen
3. Clock erzeugen
4. Daten anlegen
5. Clock erzeugen


usw.

latch !

damit werden die Daten aus den Registern in die Output Register 
geschobenen und wenn OE aktiv ist werden diese aktiv. OE arbeitet bei 
vielen invers und kann dazu benutzt werden das ganze Panel auch zu 
dimmen

Um einzelne LEDs zu dimmen braucht man BCM und da ist beim AVR einiges 
an wissen gefragt um das zu realisieren.

http://www.batsocks.co.uk/readme/art_bcm_1.htm

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Warum machste für den selben Schmarren jetzt nen 2. Thread auf?
Beitrag "32x 16 LED_ Matrix, Wort- und Zeichenausgabe in C"

Zudem nutz doch endlich mal das C-Code Tag im Forum oder lads al Datei 
hoch.

Wie soll man dir hier helfen, wenn dasselbe problem in mehrere THreads 
gesplittet wird und du dann noch zu faul bist die Daten ordentlich zu 
liefern?

von Peter D. (peda)


Lesenswert?

Du kannst noch so viele Forenzeilen schinden und haufenweise 
auskommentierten Code posten, ohne jede Rücksicht auf die Postingregeln.

Ohne Schaltplan wird das nix!

von Philipp K. (Gast)


Lesenswert?

Danke trotzdem für eure Hilfe:)
Versuche es weiter ;)

von Karl M. (Gast)


Lesenswert?

Was ist nun deine Erkenntnis Philipp ?

"Ich kann das nicht!" oder "ich brauche noch 1-2 Jahre Lehrzeit ?" oder 
"Was wollen die alle nur mit den vielen Begriffen? - es ist ja alles so 
neu hier" ..

von Klugscheisser (Gast)


Lesenswert?


von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Philipp K. schrieb:
> Danke trotzdem für eure Hilfe:)
> Versuche es weiter ;)

Also dürfen wir uns bald auf den dritten Thread ohne Code Tags zum 
selben Thema freuen?

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.