Hallo erstmal
Ich bastel im Moment an einem Board mit 32 einzeln ansteuerbaren Leds
und einem DIsplay mit Laufschrift.Die Leds werden über 2 Multiplexer
(4067) angesteuert. Beim letzten Mal hatte ich das Problem, dass mein
Programm nicht richtig auf die Tasterdrücke reagiert hat, wonach wir zu
dem Schluss gekommen sidn, dass ich erstmal ein übersichtliches Programm
schreiben sol ;) (Bin noch C Anfänger) Dabei habe ich mir auch direkt
ein schöneres Konzept ausgedacht um die Leds anzusprechen. Ursprünglich
wurde einfach eine Variable genommen ud diese dann +1 oder +2 oder so
genommen und das dann soundsooft udnd as dann einfach an den Port für
die Leds ausgegeben. Nun ahbe ich mir gedacht, ich speicher einfach den
"Code" für jede Led ab und gebe dann nacheinander alle aus. Dadurch kan
man viel schönere Muster machen. das Problem ist nun, das diese Methode
ziemlich speicheraufwändig ist udn ich das ganze mit ne AtMega8 mache^^.
Nun meine Frage: Hat Jemand einen Vorschlag, wie man das ganze nun so
realisieren könnte, sodass ähnlich wie ich das vorhatte Muster erzeugt
werden können aber weniger Speicher verbraucht wird? Das Beispielmuster
lässt alle Leds gleicheitig leuchte und dann geht eine nach der anderen
aus und bleibt aus. Dieses Muster verbraucht allerdings schon 70% meines
Programspeichers (laut AvrSTudio) Aber eigentlch sollte das Programm
noch so weitergehen, dass eine anch der anderen wieder angeht.
Bitte helft mir :)
Speichere die Abfolge der LEDs in einem Array ab. Dann holst Du Dir in
einer Schleife die Werte nacheinander aus dem Array und weist sie in
jedem Schritt Led_Port zu.
Mal so als kleine Hinführung auf meinen Hinweis mit den Folgen:
Schau Dir mal Deine Sequenz
1
charLed1=(0b00100000);
2
charLed2=(0b00100001);
3
charLed3=(0b00100010);
4
charLed4=(0b00100011);
5
charLed5=(0b00100100);
6
charLed6=(0b00100101);
7
charLed7=(0b00100110);
8
charLed8=(0b00100111);
9
charLed9=(0b00101000);
10
charLed10=(0b00101001);
11
charLed11=(0b00101010);
12
charLed12=(0b00101011);
13
charLed13=(0b00101100);
14
charLed14=(0b00101101);
15
charLed15=(0b00101110);
16
charLed16=(0b00101111);
17
charLed17=(0b00010000);
18
charLed18=(0b00010001);
19
charLed19=(0b00010010);
20
charLed20=(0b00010011);
21
charLed21=(0b00010100);
22
charLed22=(0b00010101);
23
charLed23=(0b00010110);
24
charLed24=(0b00010111);
25
charLed25=(0b00011000);
26
charLed26=(0b00011001);
27
charLed27=(0b00011010);
28
charLed28=(0b00011011);
29
charLed29=(0b00011100);
30
charLed30=(0b00011101);
31
charLed31=(0b00011110);
32
charLed32=(0b00011111);
Du wirst mir sicher zustimmen, dass man aus der LED-Zahl 1 - 32 den
links stehenden Wert berechnen kann. Das vereinfacht eine Menge,
jedenfalls aber das schreiben von Code.
Sei n die Led-Nummer, so ergibt sich der links stehende Wert, nennen wir
ihn k gemäß folgenden Ausdrücken:
1
if(n<17)k=32+n-1;elsek=n-1;
Grundsätzlich muss n dabei zwischen einschliesslich 0 und 32 liegen.
Das ganze immer wieder neu zu schreiben
LED1 ...
LED2 ...
LED3 ...
...
kannst Du Dir also sparen.
Genauso bei Deiner ursprünglichen Fragestellung:
Versuche herauszufinden, ob die Abfolge, die Du erreichen willst einer
Regel gehorcht, die Du als mathematische Formel ausdrücken kannst. Evtl.
mache Fallunterscheidungen.
Danke für deine Antwort dummy.
Aber ich bin anscheinend zu doof dafür... will auch nicht dass mir
irgendeiner das ganze vorkaut^^ dabei verliere ich dann auch den spaß.
Ich denke mal dass du meinst dass man den rechten Wert berechnen kann.
Wie die If-Abfrage funktioniert ist mir auch klar aber wie sie die Chars
beschreiben soll verstehe ich nicht. Entweder ist es echt zu Spät oder
ich bin echt zu doof...
Guck dir doch mal
http://oldwiki.blinkenarea.org/bin/view/Blinkenarea/BlinkenLEDs an.
Evtl. findest du dort etwas. Was ich aber gerade sehe, du solltest dir
doch noch mal ein paar Tutorials antun, z.B. über Bitmanipulation oder
das AVR GCC Tutorial.
Eine kleine Hilfe:
Du nimmst ein 32Bit-Array, das deine Sequenz enthält und noch ein paar
Steuerinformationen. Um es einfach zu halten, enthält Index 0 die Anzahl
der einzelnen Schritte deiner Sequenz und Index 1 die
Laufgeschwindigkeit (hier x * 10ms), danach sind die einzelnen Schritte
deiner Sequenz gespeichert.
Deine Countdownsequenz würde z.B. so aussehen:
Guck dir doch mal
http://oldwiki.blinkenarea.org/bin/view/Blinkenarea/BlinkenLEDs an.
Evtl. findest du dort etwas. Was ich aber gerade sehe, du solltest dir
doch noch mal ein paar Tutorials antun, z.B. über Bitmanipulation oder
das AVR GCC Tutorial.
Eine kleine Hilfe:
Du nimmst ein 32Bit-Array, das deine Sequenz enthält und noch ein paar
Steuerinformationen. Um es einfach zu halten, enthält Index 0 die Anzahl
der einzelnen Schritte deiner Sequenz und Index 1 die
Laufgeschwindigkeit, danach sind die einzelnen Schritte deiner Sequenz
gespeichert.
Deine Countdownsequenz würde z.B. so aussehen:
1
unsignedcharsequenz[34]={32,1000,
2
0b11111111111111111111111111111111,
3
0b11111111111111111111111111111110,
4
0b11111111111111111111111111111100,
5
0b11111111111111111111111111111000,
6
0b11111111111111111111111111110000,
7
0b11111111111111111111111111100000,
8
usw.
9
}
Der Programmteil würde ungefähr so aussehen:
1
for(k=2;k<sequenz[0]+2;k++){
2
for(delay=0;delay<sequenz[2];delay++){
3
for(i=0;i<32;i++){
4
if(sequenz[k]&(1<i))Led_Port=Led[i]
5
delay_us(10)
6
}
7
}
8
}
Die delay-Schleife musst du für deine CPU-Frequenz und
Schritgeschwindigkeit anpassen. Ausserdem sollte die Led-Definition in
ein Array.
dies ist kein getesteter Code, sondern nur eine schnelle und grobe
Vorstellung, wie es gehen könnte.
OK. Noch ein Beispiel. Deine Funktion led_minuseins ist geradezu ein
Paradebeispiel.
Du iterierst immer wieder...
1
intumrechnung(intn){
2
if(n<17)
3
return(32+n-1);
4
else
5
return(n-1);
6
}
7
8
// Alle sind an udn eine anch der anderen geht aus
9
voidled_minuseins(void)
10
{
11
intn;
12
for(chark=0;k<200;k++){
13
for(n=1;n<=32;n++){
14
Led_Port=umrechnung(n);
15
_delay_us(10);
16
}
17
}
18
for(chark=0;k<200;k++){
19
for(n=2;n<=32;n++){
20
Led_Port=umrechnung(n);
21
_delay_us(10);
22
}
23
}
24
for(chark=0;k<200;k++){
25
for(n=3;n<=32;n++){
26
Led_Port=umrechnung(n);
27
_delay_us(10);
28
}
29
}
30
31
for(chark=0;k<200;k++){
32
for(n=4;n<=32;n++){
33
Led_Port=umrechnung(n);
34
_delay_us(10);
35
}
36
37
}
38
// uswusf.
39
for(chark=0;k<200;k++){
40
Led_Port=Led32;
41
_delay_us(320);
42
}
43
}
Schon sehr viel kürzer, oder?
Aber fällt Dir was auf?
Der Start-Index der inneren Schleife folgt wiederrum einer Regel. Er
läuft von 1 bis 32.
Also noch eine Möglichkeit zur Vereinfachung.
1
voidled_minuseins(void)
2
{
3
intn;
4
intl;
5
for(l=1;l<=32;l++){
6
for(chark=0;k<200;k++){
7
for(n=l;n<=32;n++){
8
Led_Port=umrechnung(n);
9
_delay_us(10);
10
}
11
}
12
}
13
}
Aber schreib bitte nicht, das sei genial.
Das ist so ziemlich das simpelste Beispiel dafür warum programmierbare
Rechner überhaupt einen Sinn machen.
DrD schrieb:> @ Dummy:> müsste es nichtif (n < 17) k = 32 + n - 1; else k = 16 + n - 1;> heißen?
Das kannst Du Dir selbst ausrechnen. Was kommt raus wenn n = 32 ist und
was soll heraus kommen?
DrD schrieb:> Wenn die Verdrahtung so bleibt, ist es ja ok. Falls die sich ändern> sollte, ist eine explizite Definition doch besser, oder?
Das kommt darauf an...
An sich macht es keinen Sinn die Verdrahtung immer wieder zu ändern.
Aber wenn, dann würde ich eher eine Zwischenschicht (z.B. ein Makro)
einführen, die es erlaubt die physischen LED-Positionen als Binaerzahl
so zu interpretieren, das die am meisten rechte den niedrigsten und jede
links folgende einen jeweils um den Faktor 2 höheren Stellenwert hat.
Andernfalls wäre es sicherlich unübersichtlicher eine Musterfolge in
eine mathematische Formel umzusetzen.
Übrigens, wie Karl-Heinz B. immer wieder und mit einer gewissen
Berechtigung anmerkt, ist es übel für eine Variable die nur als Zahl
interpretiert wird den Typ char zu verwenden. Nimm int. Das ist ein
Zahlenwert. char nimmt man für Zeichen.
Dummy schrieb:> Nimm int. Das ist ein> Zahlenwert. char nimmt man für Zeichen.
Am besten sogar noch die inttypes:
uint8_t , uint16_t ...
Da weis jeder mit/ohne Vorzeichen und die gewollte Datenbreite.
Nils Wiechert schrieb:> Dieses Muster verbraucht allerdings schon 70% meines> Programspeichers (laut AvrSTudio)
Ne, ne, so wird das nix.
Du must schon das Gehirn einschalten, denn dazu ist es ja da und das ist
es auch, was am Programmieren Spaß macht.
Schalte den PC aus, nimm Papier und Stift und beschreibe in Worten in
welcher Folge die LEDs schalten sollen.
Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in
Programmcode umsetzen.
Eine Regel kann leicht 1000 Zustände beschreiben.
Was ist wohl einfacher:
Eine Regel hinzuschreiben und die 1000-mal durchlaufen zu lassen oder
ganz stumpfsinnig 1000 Zustände hintereinander zu klatschen?
Falls man aber wirklich völlig ungeordnete Zustände ausgeben will, kann
man ne Tabelle nehmen oder ne Pseudozufallsfunktion.
Peter
Peter Dannegger schrieb:> Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in> Programmcode umsetzen.
Also weisst Du, Du hast ja ne Menge Ahnung und so aber kannst Du bitte
höflicherweise die Threads mal vollständig lesen ehe Du Tips gibst die
hier schon lang und breit mit Beispiel genannt worden sind? Das wäre
nett.
Das Verhalten ist mir bei Dir schon öfter aufgefallen.
Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.
Dummy schrieb:> Peter Dannegger schrieb:>> Und danach kannst Du dann daraus eine Regel ableiten und diese Regel in>> Programmcode umsetzen.>> Also weisst Du, Du hast ja ne Menge Ahnung und so aber kannst Du bitte> höflicherweise die Threads mal vollständig lesen ehe Du Tips gibst die> hier schon lang und breit mit Beispiel genannt worden sind? Das wäre> nett.> Das Verhalten ist mir bei Dir schon öfter aufgefallen.> Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.
Freu dich doch bitte überhaupt, dass jemand wie Peter hier antwortet.
Auch wenn es möglicherweise nichts neues bringt.
Dummy schrieb:> Ist ja nicht wirklich übel gemeint von mir, aber es nervt allmählich.
Ist ja auch nicht für Dich gedacht, der die richtige Vorgehensweise
schon kennt.
Der Mensch ist ja keine Maschine.
Daher ist es durchaus nicht vergebens, etwas mehrmals zu sagen und auch
in etwas abgewandelter Form. Dadurch prägt es sich leichter ein.
Ansonsten wären ja Seminare völlig nutzlos, in denen der Stoff der
Vorlesung vertieft wird.
Peter
Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar
auch sehr schön ist, aber mehr Speicher braucht.
Ich habe den Code etwas umegwandelt, damit er auch funktioniert, anaj
tut er eigentlich nicht aber egal... Auf jedenfall sieht r jezt so aus:
1
voidled_minuseins(void)
2
{
3
intk;
4
inti;
5
intdelay;
6
for(k=2;k<sequenz[0]+2;k++){
7
//for (delay=0;delay<sequenz[2];delay++){
8
for(i=0;i<32;i++){
9
if(sequenz[k]&(1<i)){
10
Led_Port=Led[i];
11
}
12
_delay_us(10);
13
}
14
//}
15
}
16
}
Die Speicherung des Muster folgendermaßen :
1
uint32_tsequenz[34]={32,1000,
2
0b11111111111111111111111111111111,
3
0b11111111111111111111111111111110,
4
0b11111111111111111111111111111100,
5
0b11111111111111111111111111111000,
6
0b11111111111111111111111111110000,
7
0b11111111111111111111111111100000,
8
0b11111111111111111111111111000000,
9
0b11111111111111111111111110000000,
10
0b11111111111111111111111100000000,
11
0b11111111111111111111111000000000,
12
0b11111111111111111111110000000000,
13
0b11111111111111111111100000000000,
14
0b11111111111111111111000000000000,
15
0b11111111111111111110000000000000,
16
0b11111111111111111100000000000000,
17
0b11111111111111111000000000000000,
18
0b11111111111111110000000000000000,
19
0b11111111111111100000000000000000,
20
0b11111111111111000000000000000000,
21
0b11111111111110000000000000000000,
22
0b11111111111100000000000000000000,
23
0b11111111111000000000000000000000,
24
0b11111111110000000000000000000000,
25
0b11111111100000000000000000000000,
26
0b11111111000000000000000000000000,
27
0b11111110000000000000000000000000,
28
0b11111100000000000000000000000000,
29
0b11111000000000000000000000000000,
30
0b11110000000000000000000000000000,
31
0b11100000000000000000000000000000,
32
0b11000000000000000000000000000000,
33
0b10000000000000000000000000000000,
34
};
Aber das Schreiben des Ledarrays habe ich so gemacht wie Dummy es
vorgeschlagen hat (mit ner Funktion). Das funktioniert auch (dank Hilfe
meines Bruders).
Mein Problem ist nun, dass beim Ausgeben des Arrays auf die Leds ja
eigentlich ein Bit nach dem anderen abgefragt werden sollte. Aber
stattdessen leuchtet die vorletzte Led hell und die erste und die letzte
Led garnicht. Die anderen leuchten so dunkel, dass man es kaum sieht
aber das liegt daran, dass ich die Delay Schleife zu Testzwecken
rausgenommen habe. Weiß einer warum das nicht funktioniert?
Danke schonmal für eure bisherige Hilfe :)
Liebe Grüße
Nils
Peter Dannegger schrieb:> Der Mensch ist ja keine Maschine.> Daher ist es durchaus nicht vergebens, etwas mehrmals zu sagen und auch> in etwas abgewandelter Form. Dadurch prägt es sich leichter ein.
Hmm. Naja. Auch ein Gesichtspunkt. Ist anscheinend auch nötig. Angenehm,
das Du so cool auf mein Posting reagiert hast.
Nils Wiechert schrieb:> Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar> auch sehr schön ist, aber mehr Speicher braucht.
Was vergleichst Du denn da? Meine Version braucht für das Muster 0 Bytes
Speicher (abgesehn von den Laufindizes) und die von DrD braucht 33 * 32
Bit = 132 Bytes.
Das Muster, das Du im letzten Post geschrieben hast, ist auch wieder
regelmäßig. Es läuft von 0xFFFFFFFF bis 0x80000000
Poste mal deinen ganzen Code.
Dummy hat dir den Weg erklärt, die Sequenzen zu programmieren, ich habe
den Vorschlag gemacht, die Sequenzen zu speichern und einfach
auszugeben. Sequenzen als Bitfolgen zu speichern benötigt mehr Speicher,
als die Algorithmen der Sequenz zu programmieren.
1. Möglichkeit benötigt weniger Speicher
2. Möglichkeit ist einfacher umzusetzen bezüglich verschiedener
Sequenzen, da diese nicht als Algorithmus beschrieben werden müssen,
sondern nur als Ablauf
Welchen Weg man nimmt, ist Geschmackssache.
Nils Wiechert schrieb:> Probiere grade die Varianten von DRD umzuetzten weil die von Dummy zwar> auch sehr schön ist, aber mehr Speicher braucht.> Ich habe den Code etwas umegwandelt, damit er auch funktioniert, anaj> tut er eigentlich nicht aber egal... Auf jedenfall sieht r jezt so aus:> ....
Die Tabelle kannst du dir sparen.
Du fängst mit 0xffffffff an und für jeden Schritt wird um 1 nach links
geschoben, sowie das letzte bit gelöscht.
Nils Wiechert schrieb:> Das stimmt zwar, allerdings würde ic gerneauch das Muster so> abspeichern, der Vollständigkeit halber, da ja später noch andere Muster> dazukommen.
Ich würd pro Musterablauf ne Funktion machen, damit die Schnittstelle
einheitlich ist.
Je nach Muster kann die Funktion ja dann rechnen oder in einer Tabelle
nachschlagen.
Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist,
dass die FUnktion, welche das Array auslesen soll nicht das macht was
sie soll und ich nicht weiß warum^^
Nils Wiechert schrieb:> Das stimmt zwar, allerdings würde ic gerneauch das Muster so> abspeichern, der Vollständigkeit halber, da ja später noch andere Muster> dazukommen.
Du sagst es: später.
Ich würde vorschlagen, du konzentrierst dich erst mal auf einfache Dinge
und siehst zu, dass du die beherrscht und verstehst.
Auch wenn hier im Forum gerne in die Richtung 'allgemeine Lösungen'
gegangen wird: Für einen Einsteiger ist das oftmals tödlich, wenn man in
zu früh in Richtung total allgemeine Lösungen drängt. Dazu muss man
schon über relativ viel Grundlagenwissen verfügen und auch verstehen,
welche Techniken bei allgemeinen Lösungen angebracht sind.
Solange es dir Schwierigkeiten macht, aus einer Aufzählung von
angestrebten Zuständen, deren Bitmuster sich relativ trivial in Form von
Formeln und Regeln beschreiben lässt, ebendiese Regel und Formeln zu
sehen und zu programmieren, solltest du da mehr Aufwand reinstecken.
Nils Wiechert schrieb:> Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist,> dass die FUnktion, welche das Array auslesen soll nicht das macht was> sie soll und ich nicht weiß warum^^
Anstatt da jetzt großartig zu künsteln, mach eine gaaaaanz einfache
Tabellenabarbeitung.
Nils Wiechert schrieb:> void led_minuseins (void)> {> int k;> int i;> int delay;> for (k=2;k<sequenz[0]+2;k++){> //for (delay=0;delay<sequenz[2];delay++){> for (i=0;i<32;i++){> if (sequenz[k]&(1<i)){> Led_Port=Led[i];> }> _delay_us(10);> }> //}> }> }
Meinst du das?
Würd ich eher in der Richtung schreiben (nur als Vorgehensweise):
uint32_t temp = sequenz[4]; //als Beispiel einlesen
PORTA = (temp & 0xFF);
PORTB = (temp>>8) & 0xFF);
PORTC = (temp>>16) & 0xFF);
PORTD = (temp>>24) & 0xFF);
so setzt du alle LEDs entsprechend der Bitstellen, vorausgesetzt sie
sind an PORTA,B,C,D angeschlossen.
Kannst ja mal deine Pinbelegung erwähnen :-)
Karl heinz Buchegger schrieb:
>Solange es dir Schwierigkeiten macht, aus einer Aufzählung von>angestrebten Zuständen, deren Bitmuster sich relativ trivial in Form von>Formeln und Regeln beschreiben lässt, ebendiese Regel und Formeln zu>sehen und zu programmieren, solltest du da mehr Aufwand reinstecken.
Das sehe ich ein :)
Karl heinz Buchegger schrieb:> Nils Wiechert schrieb:>> Aber das ist ja im Moment garicht mehr das Problem. Mein Problem ist,>> dass die FUnktion, welche das Array auslesen soll nicht das macht was>> sie soll und ich nicht weiß warum^^>> Anstatt da jetzt großartig zu künsteln, mach eine gaaaaanz einfache> Tabellenabarbeitung.
Du hast eine Tabelle
Led, die 34 Elemente umfasst.
Element 0 und Element 1 lässt du für erste links liegen, und die
restlichen Elemente 2 bis 31 gibst du der Reihe nach aus. Jeweils eine
Wartezeit dazwischen.
1
voidled_minuseins(void)
2
{
3
intk;
4
inti;
5
intdelay;
6
for(k=2;k<sequenz[0]+2;k++){
7
//for (delay=0;delay<sequenz[2];delay++){
8
for(i=0;i<32;i++){
9
if(sequenz[k]&(1<i)){
10
Led_Port=Led[i];
11
}
12
_delay_us(10);
13
}
14
//}
15
}
16
}
Das muss dir doch selbst auffallen, dass das für die beschriebene
Funktionalität viel zu kompliziert ist. Da gibt es ein k, ein i, ein
sequenz und ein Led
Was machen diese Variablen alle?
Schmeiss das wegt und schreibs neu. Aber diesmal nicht einfach nur
abschreiben, sondern selber überlegen.
Und nenn die Funktion nicht "led_minuseins", denn das tut sie nicht. Die
Funktion gibt einfach nur eine Tabelle an einen Port aus. Mehr tut sie
nicht (und soll sie auch nicht tun).
Wie schon am Anfang vom Thread erwähn, liegen die Leds an 2 16er
Multiplexern, sonst wäre das alles kein Problem :D. Sind an PortD die
Datenleitungen sind die gleichen. "Ausgewählt" wird über die Inhibit
Eingänge der Multiplexer.
Nils Wiechert schrieb:> Wie schon am Anfang vom Thread erwähn, liegen die Leds an 2 16er> Multiplexern, sonst wäre das alles kein Problem :D.
2 Dinge
a) wie ist der verschaltet
b) was um alles in der Welt hat dich geritten, gleich mit
Multilexern anzufangen.
Mit gemultiplexten LED muss man völlig anders arbeiten. Und nachdem was
ich bisher von dir an Code gesehen habe, fehlen dir da massive
Grundlagen.
DAs ist der Schaltplan. AUf die Idee mit den Multiplexern hat mich ein
Freund gebracht... Dann habe ich mir die DInegr mal egnauer angegckt u
habs auch für eine gute Idee gehalten. Wie viel zu hoch ist das denn für
den Anfang?
der kann sowohl analog als auch digital. Kommt auf die Betriebsspannung
an. Mir wurde der so verkauft, dass ich dann mit einem IC 16 Leds
ansteuern kann. mir ist schon klar, dass richtiges Multiplexen anders
geht aber so war es... "einfacher"
Nils Wiechert schrieb:> der kann sowohl analog als auch digital. Kommt auf die Betriebsspannung> an. Mir wurde der so verkauft, dass ich dann mit einem IC 16 Leds> ansteuern kann. mir ist schon klar, dass richtiges Multiplexen anders> geht aber so war es... "einfacher"
Der IC ist unsinnig für den Job.
Mit einem stink normalen 595 Schieberegister wärst du besser bedient
gewesen. Bzw. wenn schon multiplexen, dann richtig: Aufbau als Matrix
mit einem Spaltentreiber und einem Zeilentreiber
Das is ja ach der Grund warum ich das Array nun Bitweise abfragen muss.
um dann zu sehen ob an der stelle ne 1 oder eine 0 steht und dann
entweder die Led die der stelle im Array entspricht ansteuert oder
nicht.
Ich weiß jetzt nicht recht, was ich dir raten soll.
* Dein Hardwareaufbau ist nicht besonders glücklich
* Du stehst mit Bitoperatioenn auf Kriegsfuss
* Um sinnvoll Multiplexen zu können, müsstest du eigentlich mit
Timern auf Du-und-du stehen
Da sind so viele Detailprobleme und du hast dich leichtsinnig in einen
Mehrfrontenkrieg eingelassen, das es nicht einfach ist, da jetzt eine
sinnvolle Schritt-für-Schritt Strategie für die weitere Vorgehensweise
vorzuschlagen.
Natürlich kann 'man' mit diesem Aufbau 32 LED betreiben. Aber dazu muss
'man' schon über ein nicht unbeträchtliches Grundwissen verfügen. Und
dein Eröffnungsposting zeigt mir, dass du das nicht hast.
Nils Wiechert schrieb:> Scheiße :D (Tschuldigung).> Das sieht so aus als wäre es für mich undmöglich as ganze bis samstag> fertigzubekommen...
Das kommt drauf an, was es werden soll.
Wenn es nur darum geht, einzelne LED nacheinander tabellengesteuert
ein/aus zu schalten, wobei jede LED eine bestimmte Zeitdauer brennen
soll, dann ist das relativ simpel möglich.
Wenn du aber mehrere LED "gleichzeitig" brennen haben musst, dann führt
kein Weg an einem "aufwändigem" Multiplexen vorbei. Wobei ... ein 1:32
Multiplex ... das könnte haarig werden.
Bisher bei TEsts bin ich für mehrere Leds gleichzeitig einfach
hingegangen und habe alle möglichen pausen rausgenommen. Dann ging das
schnell genug um das einzene leuchten nicht sehen zu können. Wäre
soetwas ähnliches nicht auch mit der Arraymethode möglich?
Nils Wiechert schrieb:> Bisher bei TEsts bin ich für mehrere Leds gleichzeitig einfach> hingegangen und habe alle möglichen pausen rausgenommen. Dann ging das> schnell genug um das einzene leuchten nicht sehen zu können. Wäre> soetwas ähnliches nicht auch mit der Arraymethode möglich?
Bis zu einem gewissen Grad ja. Wird aber kompliziert.
Ob Du die Arraymethode anwendest oder die Formelmethode ist nicht Dein
eigentliches Problem. Vielmehr die Kontrolle des Zeitablaufs, die ohne
Hilfe von Timern (das solltest Du Dir bis nächsten Samstag nicht
versuchen anzutun) um einiges komplexer wird.
Zunächst wäre es gut, wenn Du Dir das Ganze anhand eines Ablaufdiagramms
(Flussdiagramms) klarmachst. Ich meine nicht so sehr das Du eine
bestimmte formale Form einhalten sollst, sondern Dir klarmachst, welche
Operationen in welcher Reihenfolge ablaufen, wo die Wiederholpunkte sind
und wo genau die Delays zum tragen kommen und wie die Kombination aus
dem Delay für das Multiplexen und dem Delay für den visuellen Ablauf
zusammenwirkt. Die Auswahl der konkreten LEDs aus dem Muster ist dabei
nebensächlich und kann erstmal nur durch einen groben Namen
gekennzeichnet werden. Die Auswahl der LED für das Multiplexing aus dem
jeweils momentanen Muster ist wichtiger.
Dann hast Du vielleicht eine Chance, aber das wird ein hartes Stück
Arbeit für Dich. Viel Glück.
So wieder da. Hatte unterwegs eine Idee. Wenn ich jetzt für jedes Muster
eine eigene FUnktion schreiben würde (ich weiß... Umständlich, könnte
man auch mit einer machen) dann könnte ich ja bei den zusätlichen Werten
im Array nich nur Pause abspeichern sonern auch wie oft jede einele
Variable aus dem Arary ausgegeben werden soll oder? und das könnte cih
ja dann ohne Pause machen und danach die Pause einfügen. Ist nur so ne
Idee... Aber würde diese Idee funktionieren?
Das mit den Multiplexern ist ein voller Schuß ins Knie, sobald mehr als
eine LED gleichzeitig leuchten soll.
Sollen alle leuchten, ist das ein Tastverhältnis 1/32, d.h. die glimmen
nur noch leicht.
Multiplexen ohne Timerinterrupt ist programmtechnisch gesehen ein
Albtraum und ergibt in der Regel ein elendes Geflackere.
Schmeiß sie runter und nimm 4 Stück 74HC595 kaskadiert, die Ansteuerung
findest Du im Tutorial.
Peter
Nils Wiechert schrieb:> @ Peter : Geht leider nichtmehr... hab wohl nicht ordentlcih geplant und> auch schon alles verlötet... s. Bild
Ist aber deine beste Option.
Ich zermatere mir auch schon eine Weile das Hirn, wie man diesen
verkorksten Aufbau retten könnte. Hab schon in Richtung 5-er Multiplex
oder 8-er (also 5 aus 32, bzw 8 aus 32) gedacht. Das also nur maximal 5
bzw. 8 LED gleichzeitig brennen können. Mit einem Timerinterrupt wäre
das gar nicht mal so schlimm. Aufwändig ist nur der Ansteuerteil, der
aus dem Muster die jeweiligen 5 LEd rausholt, bzw. die Beschreibung des
Musters.
Wenn du morgen die Multiplexer gegen 595 austauschen würdest, würden
sich eine Menge Probleme im Nichts auflösen. So wild ist dieser
Austausch auch wieder nicht.
PS: Wieviele LED willst du den maximal gleichzeitig brennen lassen?
DOch :D ist er wohl... mach ich aber trotzdem... für die schieberegister
brauche ich jeweils 3 Bit zum ansteuern oder? könnte knapp werden am
atmega8... selbst wenn ich die noch mit an die Programmierschnittstelle
dranhänge würde es leider nicht passen da ich dann doch 3*4 = 12 Pins
brauche oder sehe ichd as falsch? ;(
aber dann muss ich auch erst zu meinem Vater oder den vorher fragen ob
der noch 4 595 rumliegen hat. (ich hofe mal dass die Antwort JA lautet)
Nils Wiechert schrieb:> DOch :D ist er wohl... mach ich aber trotzdem... für die schieberegister> brauche ich jeweils 3 Bit zum ansteuern oder?
Nicht jeweils.
Du benötigst genau und einmalig 3 Bit. Punkt.
Nils Wiechert schrieb:> Ah ok dann hauts ja besser hin als mit den Multiplexern... Scheißteile
Die sind ja auch für ganz andere Anwendungszwecke gedacht.
jo^^ ICh glaueb so wie ich hat noch niemand versucht die dinger zu
zweckentfremden. dann fahr ich morgen mal zu meinem vater und such mal
nach ein paar 595
Nils Wiechert schrieb:> DOch :D ist er wohl...
Du musst doch nur die ganzen Drähte von den LED zu den Multiplexern
aufmachen. Der Rest kann ja bleiben.
Du weißt aber schon, dass es für solche Sachen:
* Fädeldraht gibt
* man 'Bahnen' auch dadurch erzeugen kann, dass man mit Lötzinn
nebeneinanderliegende Pads verbindet und so mit einer Lötzinnwurst
eine Leiterbahn aufbaut
von Fädeldraht hab ich noch nie gehört hört sich aber super an... wie
geht das denn dan genau? (nur antworten wennde bock has eigentlich eghts
hier ja um was anderes :P) und statt mit ner Lötzinnwurst hätt ich dann
ach direkt Silberdraht nehmen können abre is ja kein Platz aufer Platine
Nils Wiechert schrieb:> hier ja um was anderes :P) und statt mit ner Lötzinnwurst hätt ich dann> ach direkt Silberdraht nehmen können abre is ja kein Platz aufer Platine
Weil alles voller Drähte ist und du dir vorher nicht überlegt hast, wie
du zumindest die IC und das LCD so anordnen könntest, dass du möglichst
geradelinie Leitungen zum Verbinden dieser Komponenten hast, du du dann
mit Lötzinnleitungen (oder Silberdraht wenn du schon auf Draht stehst)
simpelst realisieren kannst.
Stimmt... die Planung ist wirklich zu kurz gekommen^^ aber ich habds
halt dummerweise auch zum Großteil darauf angelegt dass alles optisch
gut aussieht
Karl heinz Buchegger schrieb:> Nils Wiechert schrieb:>> von Fädeldraht hab ich noch nie gehört hört sich aber super an... wie>> geht das denn dan genau?>> So sieht das dann aus> http://de.wikipedia.org/wiki/F%C3%A4deltechnik
Der Draht ist im Stift auf einer Spule aufgewickelt und schaut beim
Stift unten an der Spitze raus.
Ich machs so:
Drahtende in das Loch reinstecken und ein paar mal um den IC Pin
wickeln. Das in das Loch reinstecken hat den Grund, dass der Draht dann
fixiert wird und ich den Draht dann auch wirklich ein paar mal rund um
das Beinchen wickeln kann.
Dann mit dem Stift zum Zielbeinchen fahren, wobei sich der Draht
abwickelt.
Dort wieder ein paar mal rund ums Beinchen wickeln.
Stift zur Seite legen und Lötkolben her.
Normal löten, eventuell einen kleinen Tick länger als normal, damit die
Isolierung vom Draht auch sicher im flüssigen Lötzinn schmilzt.
An beiden Enden löten und dann noch am Ziel den Draht an der Lötstelle
mit einem kleinen Messer direkt am Zinn abschneiden.
Und schon kann die nächste Verbindung gemacht werden.
Nachdem die gezogene Verbindung im Schaltplan abgehakt wurde,
selbstverständlich. Tut man das nicht, verliert man bei komplexeren
Schaltungen ganz schnell den Überblick.
Mit ein bischen Übung geht das ganz schnell.
Hab ich mich verhaut, dann wird der Draht an beiden Enden mit dem
Messerchen abgeschnitten und wenn möglich herausgezogen. Wenn das nicht
leicht geht, dann bleibt er eben drinnen.
Nils Wiechert schrieb:> machst du das wie bei Wikipedia mit diesen Bänkchen wo der Draht dann> zwischenliegt?
Bei komplexeren IC-Gräbern: ja
MIch störts, wenn die Einzeldrähte da so kreuz und quer über die ganze
Platine laufen.
Aber eigentlich war das sogar besser, weil die Einzeldrähte dann nicht
parallel laufen und sich gegenseitig Signale einkoppeln. Ich hatte damit
allerdings noch nie wirkliche Probleme.
So gehts halt von jedem IC-Bein in die IC-Mitte zum Kamm und von dort
läuft dann das Bündel vom IC weg und verteilt sich bis es beim Ziel-IC
wieder aus dem Bündel und dem Kamm herauskommt und zum Zielbeinchen
führt.
Nils Wiechert schrieb:> Jetzt sag nur noch dass man alles entweder bei Pollin, Reichelt oder> Cnrad bekommt dann bekommste nen Knutscher :)
Und warum soll man das dort nicht bekommen?
Karl heinz Buchegger schrieb:> Auch wenn das Zeugs (insbesondere die Stifte) unverschämt teuer sind, es> lohnt sich.
ja denk ich mir. Mal sehen ob ich mir so ein set noch diesen Monat oder
erst nächsten anschaffe. Praktisch ist es ja.
SO die Ics sind bei reichelt bstellt hoffe mal die kommen schnell an.
Das mit SCL werd ich dann noch ändern. Wenn ich das im Datenblatt
richtig gesehen habe dann muss der auf High weil der bei Low alle
Ausgänge auf 0 setzt richtig? Alels klar dann hoff ich mal das Reichelt
schnell liefert und mache mich schonmal an den Umbau des Boards. Wenn
ich auf Probleme stoße melde ich mich wieder ok? Wenn der Umbau fertig
ist fang ich schonmal mit dem Programm an. Wenn ich auf Probleme stoße
melde ich mich wieder ok?
Liebe Grüße und danke für die viele bisherige Hilfe.
Nils
Karl heinz Buchegger schrieb:> Bedenke aber, das C die Apotheke unter den Vermarktern ist. D.h. bei den> anderen gibts die wahrscheinlich billiger.
Bei Reichelt heißen die Fädelstifte und kosten nicht den halben
Conrad-Preis, aber fast. ;-)
Seit wann gibt es denn reicheltpedia?
http://www.reicheltpedia.de/index.php/F%C3%A4delstift
Da ist mir ja was entgangen und das ist allemal besser als diese üblen
eingescannten Peudo-Datenblätter von Conrad...
Stimmt Reicheltpedia kannte ich bis du es gepostet hast auch noch
nicht^^. ichsuche immer bei google nach datenblättern. funktioniert
eigentlich immer ganz gut.
So mit löten bin ich fertig. Hat deshalb so lange gedauert weil ich
gestern meine Tablete nicht genommen hab. Habe AdHS und mich gestern
deshalb immer wieder mit anderen Sachen abgelenkt... So ne Scheiße ich
hassen das, aber ich schweife ab... Ich wollte mich jetzt ans
programmieren machen. Aber ich habe immer noch nicht verstanden wie das
mit dem bitweisen Auslesen von Arrays funktioniert. Kann mir das bitte
nocheinmal einer erklären? habe im Forum schon danach gesucht aber
nichts gefunden.
Liebe Grüße
Nils
Nils Wiechert schrieb:> programmieren machen. Aber ich habe immer noch nicht verstanden wie das> mit dem bitweisen Auslesen von Arrays funktioniert.
Vergiss das bitte für erste (noch dazu wenn du unter Zeitdruck stehst)
Mach ein Array mit 32 Elementen. Jedes Element steht für eine LED. Ist
es 0 dann soll die LED nicht brennen, ist es 1 soll die LED brennen.
Und diese 32 Elemente ackerst du in einer Schleife durch und gibst ein 1
Bit bzw. ein 0 Bit an die Schieberegisterkette aus.
Speichersparender wäre es natürlich, wenn man die 32 LED in einem
uint32_t unterbringen würde. Aber wenn du mit Bitoperationen sowieso
noch auf Kriegsfuss stehst, musst du nicht sparen.
PS: Vergiss nicht SCL auf 1 zu halten! Ansonsten werden dir die
Schieberegister was husten.
Das hatte cih ja vor, aber muss ich dazu nicht das Arary bit für bit
(bitweise) auslesen undann ausgeben? Das Schieberegister hat doch nur
einen serielen Eingang. Oder meintest du das so:
Karl heinz Buchegger schrieb:> Speichersparender wäre es natürlich, wenn man die 32 LED in einem> uint32_t unterbringen würde. Aber wenn du mit Bitoperationen sowieso> noch auf Kriegsfuss stehst, musst du nicht sparen.
So hatte ic das eigentlich vor, und das ganze dann in einem Array mit 32
uint32_t damit ich das komplette Muster in einem Arary habe.
Nils Wiechert schrieb:> Das hatte cih ja vor, aber muss ich dazu nicht das Arary bit für bit> (bitweise) auslesen undann ausgeben?
Wozu?
1
for(i=0;i<32;++i){
2
if(Led[i]==0)
3
// LEd i soll nicht brennen ( 0 ausgeben )
4
else
5
// Led i soll brennen ( 1 ausgeben )
6
}
> Das Schieberegister hat doch nur> einen serielen Eingang.
Ja und?
Das hat ja mit dem Led Array nur indirekt zu tun.
Wenn da in einem Array Eintrag eine 0 drinnen steht, gibst du eine 0
aus. STeht keine 0 drinnen, gibst du eine 1 aus. Deswegen musst du doch
den Led Eintrag nicht bitweise zerpfriemeln
> Oder meintest du das so:>
mache, dan brauche ich für ein muster 8*32*32 = 8192 Byte... dann ist
mein Atmega8 mit einem Muster schon übervoll... könnte amn das nicht
kleiner als mit uint8_t machen? Gibt es einen Datenyp der nur 1 und 0
ist?
Nils Wiechert schrieb:> mache, dan brauche ich für ein muster 8*32*32 = 8192 Byte...
Wenn ein Muster aus 32 Stufen besteht.
OK. Hast du recht.
Hab ich nicht bedacht.
Machs trotzdem fürs erste. Ich hab dir ein Testprogramm gepostet. Nur um
mal zu sehen, ob deine Hardware überhaupt funktioniert.
Das Umschreiben der Ausgabefunktion ist ja kein Problem
Das Problem ist ja,dass ich die Ics noch nicht habe, ahbe aber alles so
angeschlossen wie es im Tutorial stand, bis auf die Tatsache , dass ich
SCL auf +5V gelegt habe, da du gesagt hast , dass ichs nciht brauche.
Supergroßes danke für deine Riesige Mühe mir zu Helfen,ich haecht keine
Ahnung was ich ohne dich machen würde, doch eigentlich schon
wahrscheinlich heir sitzen und denken "warum geht das nicht, warum geht
das nicht???". Dass du mal eben ein passendes Programm geschrieben hats
istauch supernet, aber wie gesagt ich kanns im Moment leider noch nicht
ausprobieren. Dann heist es wohl erstmal warten -.-
Nils Wiechert schrieb:> Das Problem ist ja,dass ich die Ics noch nicht habe, ahbe aber alles so> angeschlossen wie es im Tutorial stand,
OK.
Ich hab dir im Code #define für die tatsächliche Belegung gemacht. Das
ist also kein Problem an deine tatsächliche Schaltung anzupassen
> bis auf die Tatsache , dass ich> SCL auf +5V gelegt habe,
Das war vernünftig.
Dann kann der Teil in main() mit dem Löschen der SR ersatzlos entfallen.
Nils Wiechert schrieb:> wenn ich das richtig verstanden habe dann Lässt das Programm eine> leuchtende Led einmal durchwandern oder?
Mehr als das.
Das Programm mit dem Array lässt die aktuelle LED-Belegung rundum
wandern. Egal welche und wieviele LED brennen. Du kannst ja einmal
einfach ein paar mehr Einträge auf 1 setzen :-)
Das mit dem uint32_t ist einfacher. Da wird tatsächlich nur 1 LED einmal
rundum geschickt. Mit der Betonung auf einmal. Du kannst noch andere
Bits auf 1 setzten, die wandern genauso bis zum ENde der Leds.
1
intmain()
2
{
3
....
4
uint32_tstep=0b00000000000000000000000000000001;
5
uint8_ttmp;
6
7
while(1){
8
Output(step);
9
10
tmp=step&0x80000000;
11
step<<=1;
12
if(tmp)
13
step|=0x00000001;
14
15
_delay_ms(500);
16
}
17
}
Jetzt wandert auch hier das Muster im Kreis.
Sofern sich da überhaupt etwas tut!
Drumm wäre es wichtig die Funktion der Hardware zu testen, ehe da jetzt
kompliziertere Schemata aufgebaut werden!
Nils Wiechert schrieb:> das nicht???". Dass du mal eben ein passendes Programm geschrieben hats> istauch supernet,
Ist aber die Ausnahme, da du das bis Samstag fertig haben willst (und
ich ab Do nicht mehr im Forum bin). Und da das ganze offenbar ein
Geschenk werden soll, wäre es ganz gut, wenn du rechtzeitig ein paar
Tage vorher etwas grundsätzlich lauffähiges hast.
Hm vielleicht kann ich in der Zeit schonmal die Rückplatte machen (die
wird geschraubt also wenn was falsch dran ist ist das kein Problem)
Soll hinterher mit Batterien betrieben werden 7805 ist auch mti drauf.
Karl heinz Buchegger schrieb:> Ist aber die Ausnahme, da du das bis Samstag fertig haben willst (und> ich ab Do nicht mehr im Forum bin). Und da das ganze offenbar ein> Geschenk werden soll, wäre es ganz gut, wenn du rechtzeitig ein paar> Tage vorher etwas grundsätzlich lauffähiges hast.
Mir ist klar dass es nicht der Normalfall ist, dass man in dieser Art
hilfe bekommt :) deswegen bedanke ich mich ja sosehr. Mir fällt grade
auf, dass ich weniger Schreibfehler mache wenn ich garnicht auf die
Tastatur gucke beim Tippen (gehört hier zwar nicht hin aber mich würde
mal interessieren ob das bei anderen Leuten auch so ist)
Hm dann erstmal zu etwas anderem. ich habe auf dem board auch Taster,
mit denen ich unter andrem den Text auf dem lcd ändern wollte. Im Anhang
ist ersteinmal das Programm das ich hinterher mit einfügen möchte. So
wie ich das sehe, ist es bei nicht gedrücktem völlig unmöglich, dass
sich der Text ändert, und doch tut er es. Woran liegt das? Die Schleife
bei der Tasterabfage sol bewirken, dass bei nicht gedrücktem Taster
sofort aus der Schleife gesprungen wird. wenn der Taster allerdings
gedrückt wird, wird in der while schleife darauf gewartet, dass der
Taster wieder losgelassen wird, was durch die ifabfrage spofort dazu
führt, dass der Text geändert wird... Naja zumindest SOLL es das tun.
Weiß einer wieso NICHT?
Nils Wiechert schrieb:> Hm dann erstmal zu etwas anderem.
Dann solltest Du besser auch nen anderen Thread aufmachen.
Zum Thema Taster haben viele schon Fusseln vorm Mund.
Mein Geheimtip, nimm ne fertige und bewährte Lösung.
Peter
Das sieht auch super aus, aber ich werde erstmal zum probieren die
VErion von karl benutzen. Was amcht den die Zeile
#define F_CPU 1e6
?
Ist die für die CPU Frequenz? denn die definiere ich doch schon in
manchen routinen (unter anderem in den Lcd routinen) und ausserdem ist
die doch im Makefile schon drin.
Nils Wiechert schrieb:> Ist die für die CPU Frequenz? denn die definiere ich doch schon in> manchen routinen (unter anderem in den Lcd routinen) und ausserdem ist> die doch im Makefile schon drin.
Wenn du sie im Makefile hast (was gut ist), dann nimm sie überall anders
raus. Das vermeidet, dass du dir selbst ein Ei damit legst, indem du
vergisst sie an allen Stellen zu ändern, wenn sich die Taktfrequenz
ändert.
Karl heinz Buchegger schrieb:> Das vermeidet, dass du dir selbst ein Ei damit legst, indem du> vergisst sie an allen Stellen zu ändern
Sowas macht man garnicht erst. Man ändert nicht alle Stellen, weil es
immer nur eine Stelle im Projekt gibt.
Da ich kein Make benutze, ist diese eine Stelle bei mir im "Main.h"
(außer das Projekt besteht nur aus einem einzigen File).
Peter
Peter Dannegger schrieb:> Sowas macht man garnicht erst. Man ändert nicht alle Stellen, weil es> immer nur eine Stelle im Projekt gibt.
Manchmal denk ich mir:
Es gibt eine Reihe von 'Unsauberkeiten' (um nicht das Wort 'Fehler' in
den Mund zu nehmen), bei denen muss jeder Programmierer mindestens
einmal, mit anschliessender stundenlanger Fehlersuche, selbst
hineinfallen bis er erkennt, wo das Problem liegt.
Hm Avrstudio macht doch automatisch ein makefile warum sollte ich das
also nciht nutzen^^? Werde die CPU Frequenz dann an den anderen STellen
rausnehmen. Ihc habe immer gedacht dass C ein makefile braucht??? Stimmt
das garnicht?
Nils Wiechert schrieb:> Hm Avrstudio macht doch automatisch ein makefile warum sollte ich das> also nciht nutzen^^?
Ist ja auch ok
> Werde die CPU Frequenz dann an den anderen STellen> rausnehmen.
Darum gehts.
So eine Einstellung macht man immer nur an 1 Stelle
Im Idealfall dort, wo man sie leicht findet. Auch 2 Jahre später.
> Ihc habe immer gedacht dass C ein makefile braucht??? Stimmt> das garnicht?
Nö.
Ein makefile ist nur eine Möglichkeit, wie man sich den Vorgang des
Bauens einer Applikation vereinfachen und automatisieren kann. Aber
nichts und niemand hindert einen daran, den Compiler händisch aus einer
Commandline für jedes C-File aufzurufen und die Einzelteile händisch zum
Programm zusammenzulinken. Und so hat man das auch gemacht, bevor sich
jemand den Mechanismus von 'make' hat einfallen lassen.
Letzten Endes geht es nur darum, dass Änderungen in einem C-File auch
compiliert werden und ein neues Programm entsteht. Ob du das händisch
machst, oder ob das ein Werkzeug namens 'make' aufgrund einer
Beschreibung der Zusammenhänge und Uhrzeitvergleich von Dateien macht
ist letzten Endes egal (letzteres ist komfortabler). Dem Compiler ist es
egal, wer ihn aufruft :-)
Wie arbeitet make, bzw was hat es mit dem Makefile auf sich?
Im Makefile ist einfach nur beschrieben, welche Datei von welchen
anderen Dateien abhängen und mit welchem Kommando man diese Datei
erzeugen kann.
Da steht also drinnen:
Im eine Datei (zb) test.hex zu erzeugen (die du dann auf den Prozessor
brennen kannst), müssen die Einzelteile test.o und (zb) uart.o
vorliegen. Sind die da, dann werden die beiden zusammengelinkt und man
bekommt das hex-File.
Jetzt gehts aber weiter:
test.o hängt von test.c und uart.h ab und man erhält test.o indem man
test.c durch den Compiler schickt
uart.o hängt von uart.c und uart.h ab und man erhält sie, indem man
uart.c durch den Compiler jagt
1
test.hex: test.o uart.o
2
Linker aufrufen um test.hex zu erhalten
3
4
test.o: test.c uart.h
5
Compiler aufrufen um test.o zu erhalten
6
7
uart.o: uart.c uart.h
8
Compiler aufrufen um uart.o zu erhalten
das ist der grundsätzliche Aufbau (in seiner simpelsten Form) eines
Makefiles.
Das Tool make schnappt sich diese Beschreibung und überprüft ganz
einfach die File-Timestamps. Editierst du zb uart.c, dann hat uart.c ein
neueres Datum als uart.o
Daher wird das zugehörige Kommando (Compiler aufrufen um uart.o zu
erhalten) ausgeführt und man bekommt ein neues uart.o.
Dadurch ist jetzt aber auch uart.o neuer als test.hex und folgerichtig
wird auch das dort vermerkte Kommando ausgeführt.
Folge: Du editierst uart.c und make macht alle Schritte die notwendig
sind um daraus ein neues test.hex zu erzeugen. Beachte: test.c hängt
nicht von uart.c ab, daher ist es nicht neu compiliert worden. Hättest
du uart.h editiert, so würde make auch diese Abhängigkeit feststellen,
feststellen dass uart.h neuer ist als test.o und das zugehörige Compiler
Kommando ausführen.
Das ist alles was make macht: Die Zeiteinträge von Dateien vergleichen
und bei Bedarf die zugehörigen Kommandos ausführen.
Aktuelle Makefiles sind ein wenig komplizierter aufgebaut, aber das
Prinzip ist immer noch dasselbe.
Ah danke für die super erklärung. Dann ist das wahrscheinlich auch der
Grund, warum ich nur einmal auf compilieren klicken kann und der beim
zweiten mal nichts mehr macht, wenn ich nichts ändere.
Nils Wiechert schrieb:> Das kann man doch drin lassen oder?
Besser nicht.
Wenn wichtige Eingaben vergessen wurden, sollte der Compiler nen Fehler
ausgeben.
> Weil das doch nur dann die cpu> Frequenz definiert wenn sie noch nicht definiert ist oder?
Und warum soll die dann immer richtig sein?
Besser:
1
#ifndef F_CPU
2
#error Ey Mann, du hast die Frequenz nicht angegeben !!!
Ich ahbe die Ics jetzt bekommen. Aber leider leuchten alle Leds auf
einmal und nicht nur die bei denen in der Variable eine 1 steht. Im
ANhang ist der Code. ICh habe alles nach Plan verlötet. weiß jemand
warum es trotzdem nciht funktioniert?
Liebe Grüße
Nils