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); } }
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?
Hab leider kein Datenblaat von der LED_ Matrix... Nur von den einzelnen ICS die da verbaut sind.
Philipp K. schrieb: > Nur von den einzelnen ICS die da verbaut sind. Die da wären? Welche IC sind da verbaut?
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.
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...
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.
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.
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); } }
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... :-(
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 ?
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
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?
Du kannst noch so viele Forenzeilen schinden und haufenweise auskommentierten Code posten, ohne jede Rücksicht auf die Postingregeln. Ohne Schaltplan wird das nix!
Danke trotzdem für eure Hilfe:) Versuche es weiter ;)
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" ..
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.