Hallo! ich habe folgendes Problemchen. Ich möchte mit meinem Atmega (in c++) ca 300 LEDs ansteuern. Das ganze über 30 Pins die mit Vorwiderstand an den Anoden von je 10 LEDs hängen und dann eben noch 10 Pins die im Wechsel einen FET schalten um einen Abschnitt der LEDs zu aktivieren. Das ganze klappt auch soweit. Ich erzeuge Effekte in der Main Funktion und eine ISR kümmert sich darum dass immer einer meiner FETs angesteuert wird. Nun kommen im Programm so einige rand()%x Aufrufe vor und ich habe beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10 Zufallsberechnungen im Pfad stehen bleibt. Es sind aber nach dem compilieren gerade mal 1% Speicher belegt. Frisst die rand() zur Laufzeit derartig viele Ressourcen dass der uC so schnell an seine Grenzen kommt? Wie überprüft man sowas am besten?
Ralf Eden schrieb: > Hallo! > > ich habe folgendes Problemchen. Ich möchte mit meinem Atmega (in c++) ca > 300 LEDs ansteuern. Das ganze über 30 Pins die mit Vorwiderstand an den > Anoden von je 10 LEDs hängen und dann eben noch 10 Pins die im Wechsel > einen FET schalten um einen Abschnitt der LEDs zu aktivieren. Das nennt man eine LED-Matrix. > Das ganze klappt auch soweit. Ich erzeuge Effekte in der Main Funktion > und eine ISR kümmert sich darum dass immer einer meiner FETs angesteuert > wird. Klingt gut. > Nun kommen im Programm so einige rand()%x Aufrufe vor und ich habe > beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10 > Zufallsberechnungen im Pfad stehen bleibt. Programmierfehler. > Es sind aber nach dem > compilieren gerade mal 1% Speicher belegt. Frisst die rand() zur > Laufzeit derartig viele Ressourcen dass der uC so schnell an seine > Grenzen kommt? Nö. > Wie überprüft man sowas am besten? Mit einer systematischen Fehlersuche.
Ralf Eden schrieb: > eine ISR kümmert sich darum Wie sieht denn diese ISR aus? Sind da drin Schleifen? Oder sogar irgendwelche Warteschleifen? > Wie überprüft man sowas am besten? Such mal nach "float" und/oder nach "double" in deinem Programm. Wenn da sowas vorkommt, dann findest du Zeitfresser recht schnell. Ein recht guter Ansatz ist auch die Suche nach delay() und/oder seine Derivate... > Wie überprüft man sowas am besten? Man misst/berechnet die Zykluszeit der Hauptschleife. Messen geht z.B. über eine LED, die pro Durchlauf getoggelt wird. Mit einem Oszi kann man dann recht leicht feststellen, wie lang die dann braucht. Das selbe kann man mit einer LED in der ISR machen: am Anfang setzen, am Ende zurücksetzen, Oszi dran und ein paar Minuten laufen lassen, um auch Ausreißer zu erfassen.
Per Timerinterrupt 10 mal jeweils 4 Byte auszugeben, sollte keine nennenswerte CPU-Last erzeugen. Dein Fehler muß also woanders liegen. Ohne Code kann man dazu nichts weiter sagen.
Aber was bringt es mir, die Zykluszeit der Hauptschleife zu messen? Die sollte ja unkritisch sein, nachdem die Ansteuerung der LEDs von der ISR übernommen wird. Die ISR ist unterdessen tatsächlich nicht gerade die feine englische Art, da in einer Schleife die Bits entsprechend der Pinbelegung angeordnet werden müssen. Aber sie läuft immer gleich lang ab und bis zum nächsten Interrupt vergehen sicher 50*256 Taktzyklen.
Ralf Eden schrieb: > Die ISR ist unterdessen tatsächlich nicht gerade die feine englische > Art, da in einer Schleife die Bits entsprechend der Pinbelegung > angeordnet werden müssen. Da die Multiplexrate deutlich höher sein wird, als die Änderungsrate, könnte man die Bitreihenfolge besser vor Speicherung in den Bild-RAM umändern. Das spart deutlich CPU-Last. Man könnte natürlich auch gleich die LED-Matrix in der optimalen Reihenfolge an den AVR anschließen.
Peter D. schrieb: > Ralf Eden schrieb: > Die ISR ist unterdessen tatsächlich nicht gerade die feine englische > Art, da in einer Schleife die Bits entsprechend der Pinbelegung > angeordnet werden müssen. > > Da die Multiplexrate deutlich höher sein wird, als die Änderungsrate, > könnte man die Bitreihenfolge besser vor Speicherung in den Bild-RAM > umändern. Das spart deutlich CPU-Last. > Man könnte natürlich auch gleich die LED-Matrix in der optimalen > Reihenfolge an den AVR anschließen. Ja stimmt, das steht auch auf der Todo-Liste. Aber die Ursache kann das ja eigentlich kaum sein denke ich.
Ralf Eden schrieb: > Ja stimmt, das steht auch auf der Todo-Liste. Aber die Ursache kann das > ja eigentlich kaum sein denke ich. 1. Fehler! Niemals etwas ausschließen, was man nicht wasserdicht geprüft hat! Siehe Fehlersuche.
Ralf Eden schrieb: > Die ISR ist unterdessen tatsächlich nicht gerade die feine englische > Art, da in einer Schleife die Bits entsprechend der Pinbelegung > angeordnet werden müssen. jetzt nicht direkt zum Thema: __builtin_avr_insert_bits ist bekannt? https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html damit gehen so Bit-Umsortierereien recht komfortabel und flott. Natürlich nur, wenn die Pinbelegung zur Compilezeit schon bekannt ist.
Ralf Eden schrieb: > Aber was bringt es mir, die Zykluszeit der Hauptschleife zu messen? Die > sollte ja unkritisch sein, nachdem die Ansteuerung der LEDs von der ISR > übernommen wird. Wenn die Hauptschleife "normalerweise" 500 mal pro Sekunde durchlaufen wurde, nach einer "kleinen" Codeänderung an ganz anderer Stelle, z.B. in der Interruptroutine(!) aber auf einmal nur noch 200 mal, dann war die Änderung doch nicht so "klein" wie vermutet. Ralf Eden schrieb: > beobachtet, dass meine Anzeige ab einer kritischen Menge von ca 10 > Zufallsberechnungen im Pfad stehen bleibt. Definiere "stehen bleiben", wie stellst du das fest?
Was soll rand() als Random Generator ? Nimm ein LFSR, siehe XApp210.pdf, XApp211.pdf, XApp217.pdf, XApp220.pdf von Xilinx. Mit der Laenge kannst du dir die Repetierhaeufigkeit einstellen. Ich denke oberhalb von 20 bit, entsprechend 1:1'000'000 bist du gut aufgestellt. Ich wuerd's mit 32 bit probieren, mit Longint rechnen. Das waere dann eine wiederholung alle 4 Milliarden bit.
Name H. schrieb: > Was soll rand() als Random Generator ? Weil das schon funktioniert? > Nimm ein LFSR, siehe XApp210.pdf, XApp211.pdf, XApp217.pdf, XApp220.pdf > von Xilinx. Was glaubst du, was in rand() drin steckt? Eine Blattlaus die würfelt?
So hier ist mal der Code soweit. In der Main ist die Änderung auskommentiert, die zum Freeze führt. Wenn ich an anderer Stelle die Anzahl an rand()-Aufrufen reduziere, funktioniert die Änderung.
Lothar M. schrieb: > Definiere "stehen bleiben", wie stellst du das fest? Das Hauptprogramm bleibt bei der aktuellen Anzeige Hängen. Die ISRs scheinen aber weiterzulaufen. Meine Testmöglichkeiten sind bzgl Oszi dummer Weise eingeschränkt, denn ich habe keins. :(
Beitrag #5794535 wurde von einem Moderator gelöscht.
Beitrag #5794542 wurde von einem Moderator gelöscht.
Beitrag #5794543 wurde von einem Moderator gelöscht.
Beitrag #5794547 wurde von einem Moderator gelöscht.
Beitrag #5794551 wurde von einem Moderator gelöscht.
Also bis auf die beiden Punkte die du selbst mit Todo angemerkt hast fällt mir auch nichts auf
Ralf Eden schrieb: > So hier ist mal der Code soweit. In der Main ist die Änderung > auskommentiert, die zum Freeze führt. Wenn ich an anderer Stelle die > Anzahl an rand()-Aufrufen reduziere, funktioniert die Änderung. Deine Formatierung ist ungünstig. Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster spinnt. Das reine Multiplexen sieht erstmal OK aus.
Ralf Eden schrieb: > So hier ist mal der Code soweit. Mit C++ kenne ich mich nicht so aus. Irgendwann habe ich den Faden verloren, wer wen aufruft. Vielleicht sollte man die Codehäppchen etwas größer machen und nicht alles bis zu Einzeilern zerteilen. Es sieht so aus, daß fast alles im Interrupt läuft, also ne richtig große Menge Holz. Daneben soll aber der Interrupt noch die Helligkeit ändern, d.h. ne PWM machen (je LED?). Wenn der Interrupt dicht ist, dann läuft Main auf Sparflamme, d.h. zwischen den Interrupts wird nur noch ein Befehl des Main ausgeführt. Das kann so wirken, als ob das Main steht. Ein Aufräumen wäre also dringeng angeraten. Man sollte auch vermeiden, für jedes Bit ein Byte zu verbraten. Bitmasken (ein Byte je 8 Bit) machen das ganze nochmal schneller.
Falk B. schrieb: > > Deine Formatierung ist ungünstig. > > Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich > nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster > spinnt. Das reine Multiplexen sieht erstmal OK aus. Kannst du das präzisieren? Was würdest du genau anders machen? Das seltsame ist ja, dass die Probleme erst auftreten, sobald ich zu viele Parameter per Zufall erzeuge. Solange ich in diesem Fall die beiden Directions fest übergebe klappt alles. Ich kann auch die Directions per Zufall bestimmen und dafür die Axen fest übergeben. Dann läuft es auch. Mein Eindruck ist, dass einzig und allein die Anzahl der rand() Aufrufe den Unterschied macht.
Peter D. schrieb: > Ralf Eden schrieb: > So hier ist mal der Code soweit. > > Mit C++ kenne ich mich nicht so aus. Irgendwann habe ich den Faden > verloren, wer wen aufruft. Vielleicht sollte man die Codehäppchen etwas > größer machen und nicht alles bis zu Einzeilern zerteilen. > > Es sieht so aus, daß fast alles im Interrupt läuft, also ne richtig > große Menge Holz. Daneben soll aber der Interrupt noch die Helligkeit > ändern, d.h. ne PWM machen (je LED?). > Wenn der Interrupt dicht ist, dann läuft Main auf.. Nein im Interrupt wird nur umsortiert u die Portzuweisung gemacht. Wobei die sortierung wirklich noch raus kann aber das kann es kaum sein. Da sind noch ca 50*256 Taktzyklen Zeit. Helligkeit wird nicht im Interrupt behandelt.
Ich werfe mal die Stichworte "atomic" und "volatile" in den Ring. Beim Datenaustausch Main<->Interrupt können die Wunder bewirken.
Oder anders herum gefragt. Wann kann ein überladener Interrupt denn für ein Freeze sorgen? Das passiert doch eigentlich nur wenn er so groß wird dass das Programm kaum noch außerhalb der ISR läuft. Oder übersehe ich hier was?
Peter D. schrieb: > Ich werfe mal die Stichworte "atomic" und "volatile" in den Ring. > Beim Datenaustausch Main<->Interrupt können die Wunder bewirken. Die habe ich doppelt und dreifach überprüft. Hast du eine bestimmte Stelle im Auge?
Ralf Eden schrieb: > Die habe ich doppelt und dreifach überprüft. Hast du eine bestimmte > Stelle im Auge? Volatile habe ich grad gefunden. Ist eben schwer, sich in einem fremden Code zurecht zu finden. Atomic braucht man, wenn mehrere Datenbytes konsistent sein müssen. Wo das in Deinem Code nötig wäre, kann ich noch nicht sagen.
Ralf Eden schrieb: >> Auf den ersten Blick sehe ich keinen massiven Fehler. Aber es würde mich >> nicht wundern, wenn dein Funktion zum Erzeugen neuer Anzeigemuster >> spinnt. Das reine Multiplexen sieht erstmal OK aus. > > Kannst du das präzisieren? Was würdest du genau anders machen? Einfach mal eine EINFACHE Funktion schreiben, die einfach ein paar Zahlen hochzählt und anzeigt. > Das seltsame ist ja, dass die Probleme erst auftreten, sobald ich zu > viele Parameter per Zufall erzeuge. Wo denn? In deiner Hauptschleife wählst du zufällig eine von 5 Funktionen aus. In den einzelnen Funktion stecken auch wieder lange delays. Aber das ist nebensächlich. Denn das Multiplexing ist davon unberührt. Bestenfall wenn die CPU-Last im Multiplexing zu hoch wird (sehr nahe 100%), kommt das Hauptprogramm gar nicht mehr merklich vorwärts. Das kann man aber messen, auch ohne Oszi. Schalte in JEDEM Interrut zu Beginn ein IO-Pin auf HIGH und am Ende wieder auf LOW. Damit kann man die CPU-Last der ISRs messen. Mit dem Oszi ist es komfortabel, es reicht aber auch ein Multimeter! Denn das mißt den Mittelwert des Signals. Wenn du dort >90% von VCC mißt, hast du ein Problem. > Solange ich in diesem Fall die > beiden Directions fest übergebe klappt alles. Wo denn? Mit welcher Funktion? Ich kann auch die > Directions per Zufall bestimmen und dafür die Axen fest übergeben. Dann > läuft es auch. Mein Eindruck ist, dass einzig und allein die Anzahl der > rand() Aufrufe den Unterschied macht. Sicher nicht, denn die sind relativ kurz, ein paar Dutzend Takte. Man kann den Spies auch mal rumdrehen. Lass die ISRs AUS! Kein sei() vor der Hauptschleife! Und dann lass deine Datengenerierungsfunktionen mal laufen und schalte vor jedem Aufruf/Durchlauf eine Status-LED an und nach dem Aufruf aus. Dann siehst du, ob da was langsamer wird oder stehen bleibt, wenn du deine Aufrufparameter veränderst.
Falk B. schrieb: > Wo denn? > Siehst du in der Main. Dort sind zwei Funktionsaufrufe auskommentiert. So wie der Code JETZT ist, funktioniert er tadellos. Erst wenn durch diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt finden fangen die Probleme an. Ich kann aber dann an anderer Stelle im Pfad rand Aufrufe weg nehmen und es klappt wieder.
Falk B. schrieb: > In > den einzelnen Funktion stecken auch wieder lange delays. Das kann die Ursache sein. _delay_ms(1); geht davon aus, daß es 16000 Zyklen verbraten soll. Wenn es aber nur jede 1ms (1/960Hz) für einen Zyklus dran kommt, ist es 16000-fach langsamer (16s statt 1ms).
Peter D. schrieb: > Falk B. schrieb: > In > den einzelnen Funktion stecken auch wieder lange delays. > > Das kann die Ursache sein. _delay_ms(1); geht davon aus, daß es 16000 > Zyklen verbraten soll. Wenn es aber nur jede 1ms (1/960Hz) für einen > Zyklus dran kommt, ist es 16000-fach langsamer (16s statt 1ms). Guter Punkt, aber nochmal. So wie das Programm jetzt ist läuft es wie gewünscht. Dann würde es ja gar nicht laufen.
Beitrag #5794641 wurde vom Autor gelöscht.
Ralf Eden schrieb: > Erst wenn durch > diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt > finden fangen die Probleme an. Dann füg doch einfach mal in die Mainloop eine Schleife mit rand-Aufrufen ein, z.B. 10, 100 oder 1000. Ich denke mal, nicht die rands sind das Problem, sondern was mit deren Werten gemacht wird.
Ralf Eden schrieb: > Falk B. schrieb: >> Wo denn? >> > > Siehst du in der Main. Dort sind zwei Funktionsaufrufe auskommentiert. > So wie der Code JETZT ist, funktioniert er tadellos. Erst wenn durch > diese beiden veränderten Funktionsaufrufe weitere rand Aufrufe statt > finden fangen die Probleme an. Ich kann aber dann an anderer Stelle im > Pfad rand Aufrufe weg nehmen und es klappt wieder. OK. Hmmm, merkwürdig. Denn das sind einfache, aufeinanderfolgende Funktionsaufrufe. Deine Funktion void var_delay_ms(double ms) { while(0 < ms) { _delay_ms(1); --ms; } } funktioniert zwar, der Parameter MS ist aber mit double nonsense. Die Funktion kann nur ganzzahlige Millisekunden warten, also reicht ein Paramter vom Typ integer oder Long. aber das ist nicht das Problem.
Der Quelltext ist wiedermal das allerbeste Beispiel warum C++ und andere Objektorientierte Sprachen auf kleineren Mikrocontrollern kontraproduktiv sind, du verlierst einfach absolut die Übersicht. Oder anders gefragt, wieviele Takte brauchen deine ISR?
Ralf Eden schrieb: > Erst wenn durch diese beiden veränderten Funktionsaufrufe weitere rand > Aufrufe statt finden Was passiert denn, wenn du die Funktion mal so oder mal so aufrufst:
1 | // mal so
|
2 | CFbelt(randAxis(), ((rand()%20)+25), DIR_ASC); |
3 | // un beim zweiten Test so
|
4 | CFbelt(randAxis(), ((rand()%20)+25), DIR_DESC); |
Denn das hier scheint mir sehr eigenartig: 2 Möglichkeiten, aber modulo 3...
1 | Direction randDirection(void) |
2 | {
|
3 | switch(rand()%3) // stimmt das wirklich? |
4 | {
|
5 | case 0: |
6 | default:
|
7 | return DIR_ASC; |
8 | break; |
9 | case 1: |
10 | return DIR_DESC; |
11 | break; |
12 | }
|
13 | }
|
Ich hätte das so gemacht:
1 | Direction randDirection(void) |
2 | {
|
3 | if(rand()&1) return DIR_ASC; |
4 | |
5 | return DIR_DESC; |
6 | }
|
:
Bearbeitet durch Moderator
Falk B. schrieb: > OK. Hmmm, merkwürdig. Denn das sind einfache, aufeinanderfolgende > Funktionsaufrufe. > > Deine Funktion > > void var_delay_ms(double ms) > { > while(0 < ms) > { > _delay_ms(1); > --ms; > } > } > > funktioniert zwar, der Parameter MS ist aber mit double nonsense. Die > Funktion kann nur ganzzahlige Millisekunden warten, also reicht ein > Paramter vom Typ integer oder Long. aber das ist nicht das Problem. Ich habe Double genommen, weil _delay_ms auch einen Double Wert erwartet, wenn ich nicht irre. Aber stimmt ein uint16 sollte ausreichen. Gut also werde ich mir wenn ich Zuhause bin die ISR nochmal genauer anschauen. Wenn die Last hier tatsächlich das Problem sein sollte, müsste es ja mit einem größeren Prescaler laufen. Trotzdem seltsam aber schauen wir mal.
Andreas M. schrieb: > ist so was nicht eine Endlosschleife?for(uint8_t i=6; i>=0; i--) Ääh! Naja genau genommen sollte es überlaufen und dann trzd stoppen. Aber gut gesehen dass ist natürlich falsch!
Andreas M. schrieb: > ist so was nicht eine Endlosschleife? > for(uint8_t i=6; i>=0; i--) Mich würde auch die Meinung des Compilers dazu interessieren...
Ralf Eden schrieb: > Ääh! Naja genau genommen sollte es überlaufen und dann trzd stoppen. Es kann nicht stoppen, denn wegen unsigned ist die Bedingung immer true ;)
Den Code habe ich mir nicht angesehen. Typisch für ein Hängenbleiben eines Programmes ist, wenn der Stack überläuft. Hast Du genug Platz für den Stack vorgesehen oder kann C++ an anderen Stellen zu einem Überlauf führen?
var_delay_ms sieht für mich äußerst verdächtig aus. stell das mal um, dass es ein Int als Argument nimmt und mit ints rechnet.
Kleiner Tipp. Die Verdrehung der IO-Bits kann man einfach und DEUTLICH schneller mit einer Tabelle machen. Dann sieht das so aus.
1 | uint8_t bit_mix[256] = {.....}; |
2 | |
3 | *_ptrList[colInd] = bit_mix[localDataByte]; |
Da deine Pinzuordnung konstant ist, kann man die Tabelle auch als Konstante in den Flash legen, das spart 256 Bytes RAM. Dann muss man sie aber vorher per Script, Excel oder zu Fuß erstellen 8-0. Im RAM kann man sie per Funktion erstellen.
Lothar M. schrieb: > CFbelt(randAxis(), ((rand()%20)+25), DIR_ASC); > // un beim zweiten Test so > CFbelt(randAxis(), ((rand()%20)+25), DIR_DESC); > ... > switch(rand()%3) // stimmt das wirklich? Oh je. Also rand()%3 spuckt mir Zahlen von 0 bis 2 aus. Das ist eins Zuviel, stimmt. Sollte der Default: zwar auffangen, aber falsch ist es allemal. Wird geändert. Und ich Idiot habe DIR_DESC gar nicht einzeln getestet. Und da kommen wir zu Andreas M. schrieb: > ist so was nicht eine Endlosschleife? > for(uint8_t i=6; i>=0; i--) Andreas M. schrieb: > Es kann nicht stoppen, denn wegen unsigned ist die Bedingung immer true > ;) Das sieht doch stark nach dem Übeltäter aus.
Vlad T. schrieb: > var_delay_ms sieht für mich äußerst verdächtig aus. > > stell das mal um, dass es ein Int als Argument nimmt und mit ints > rechnet. Jupp wird gemacht. Danke! Falk B. schrieb: > Kleiner Tipp. Die Verdrehung der IO-Bits kann man einfach und > DEUTLICH > schneller mit einer Tabelle machen. Dann sieht das so aus. > uint8_t bit_mix[256] = {.....}; > > *_ptrList[colInd] = bit_mix[localDataByte]; > > Da deine Pinzuordnung konstant ist, kann man die Tabelle auch als > Konstante in den Flash legen, das spart 256 Bytes RAM. Dann muss man sie > aber vorher per Script, Excel oder zu Fuß erstellen 8-0. Im RAM kann man > sie per Funktion erstellen. Ja stimmt wohl. Danke für den Hinweis!
Ralf Eden schrieb: > Das sieht doch stark nach dem Übeltäter aus. Mich würde nach wie vor interessieren, was der Compiler dazu meint. Lässt der das tatsächlich unkommentiert durch?
Lothar M. schrieb: > Andreas M. schrieb: >> ist so was nicht eine Endlosschleife? >> for(uint8_t i=6; i>=0; i--) > Mich würde auch die Meinung des Compilers dazu interessieren... Keine Warnung, kein Fehler.. Ich benutze den AVR/GNU C++ in den Standardeinstellungen des Atmel Studio. Außer Unterschiede und Einflüsse unterschiedlicher Optimierungsflags hab ich mich damit auch noch nicht wirklich beschäftigt.
Lothar M. schrieb: > Ralf Eden schrieb: >> Das sieht doch stark nach dem Übeltäter aus. > Mich würde nach wie vor interessieren, was der Compiler dazu meint. > Lässt der das tatsächlich unkommentiert durch? Ja, keine Warnung, keinen Fehler, produziert nur ne 1A Endlosschleife.
:
Bearbeitet durch User
Hannes J. schrieb: > Keine Warnung, kein Fehler.. Ok, die Warnung gibts erst ab -Wtype-limits, und das wäre dann drin z.B. in -Wextra (zusammen mit anderen zusätzlichen Warnings für C++): https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html Deshalb schlägt dieses Problem hier immer wieder auf... ;-)
:
Bearbeitet durch Moderator
Beitrag #5794740 wurde vom Autor gelöscht.
Lothar M. schrieb: > Hannes J. schrieb: >> Keine Warnung, kein Fehler.. > Ok, die Warnung gibts erst ab -Wtype-limits, und das wäre dann drin z.B. > in -Wextra (zusammen mit anderen zusätzlichen Warnings für C++): > https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html > > Deshalb schlägt dieses Problem hier immer wieder auf... ;-) Dazu kommt, dass AVR Studio die Option nur im C Compiler anbietet, nicht im C++. Habe sie jetzt manuell eingefügt und jetzt meckert er auch.
Falk B. schrieb: > Was glaubst du, was in rand() drin steckt? Eine Blattlaus die würfelt? Hallo Falk, ist zu lustig, ich hätte auf "Kleine Hufeisennase" getippt. :-)
Hallo, die delays in den Funktionen und in der Hauptschleife stören nicht? Ohne Oszi kannste dennoch eine LED in Hauptschleife blinken lassen. Musste aber ohne delay machen. Überhaupt würde ich delay rauswerfen. Wenn sich die Frequenz optisch verändert sieht man das.
Ralf Eden schrieb: > Meine Testmöglichkeiten sind bzgl Oszi dummer Weise eingeschränkt, denn > ich habe keins. :( Dafür brauchst du kein Oszi. Es reicht ein minimalistischer Logikanalysator im Gegenwert eines Kantinenmittagessens.
Hab da noch zwei Fehler entdeckt. Du rufst CFfullPulsation() und TPflash() mit Parametern auf die größer als 8Bit sein können. Die Funktionen erwarten da aber uint8 ;)
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.