Hallo, ich habe eine kleine Anfängerfrage. Da ich Lust hatte zu Basteln, habe ich mir eine 2D LED-Matrix zusammen gebaut. Diese werden im Multiplexverfahren durch einen Prozessor gesteuert. Jetzt habe ich mir eine sehr spärliche GUI mit QT zusammengeklickt und kam auf die Idee die Daten direkt an den Prozessor zu übertragen. D.h. ich will Daten vom PC aus an den µC senden. Billigen China USB-TLL Wandler und eine Comport Lib aus dem Internet habe ich bereits am Laufen. Leider werden doch recht viele Daten geschickt und irgendwie klappt das nicht so recht. Wie ich es gemacht habe: 8Bit werden übertragen: Code wird gesendet mit 1xxx xxxx um anzukündigen das ein Befehl kommt. Daten fangen immer mit 0 an. Dann habe ich die ca. 150 LEDs in 7 Bit Blöcke zerlegt (d.h. 7 Leds auf einmal) und übertrage die hintereinander. Fertig. Funktioniert leider aber nicht so richtig. Wenn zu schnell zweimal gesendet wird, gibts Murks. Manchaml gibts einfach so Murks. Mit 200 Delays gehts, aber schnarch langsam. Wie macht man so was einigermaßen ordentlich (ohne Hardware Handshake). Oder soll man sich jedes Datenpaket, per Rückmeldung bestätigen lassen, sowas wie ein eigenes Protokoll??? Danke von einem der das noch nie gemacht hat :-)
@ Jetta (Gast) >zusammengeklickt und kam auf die Idee die Daten direkt an den Prozessor >zu übertragen. Dann tu das doch ;-) >8Bit werden übertragen: Code wird gesendet mit 1xxx xxxx um anzukündigen >das ein Befehl kommt. Daten fangen immer mit 0 an. Kann man machen. >Dann habe ich die ca. 150 LEDs in 7 Bit Blöcke zerlegt (d.h. 7 Leds auf >einmal) und übertrage die hintereinander. Fertig. Funktioniert leider >aber nicht so richtig. Wenn zu schnell zweimal gesendet wird, gibts >Murks. Manchaml gibts einfach so Murks. Mit 200 Delays gehts, aber >schnarch langsam. >Wie macht man so was einigermaßen ordentlich (ohne Hardware Handshake). Einfach schnell, sinnvollerweise mit einem UART-Interrupt. Geh erstmal mit der Baudrate runter, sagen wir auf 9k6 oder so. >Oder soll man sich jedes Datenpaket, per Rückmeldung bestätigen lassen, Kann man machen, muss man aber nicht. >sowas wie ein eigenes Protokoll??? Hast du doch schon.
Jetta schrieb: > Wie ich es gemacht habe: > 8Bit werden übertragen: Code wird gesendet mit 1xxx xxxx um anzukündigen > das ein Befehl kommt. Daten fangen immer mit 0 an. Also wie bei MIDI. > Dann habe ich die ca. 150 LEDs in 7 Bit Blöcke zerlegt (d.h. 7 Leds auf > einmal) und übertrage die hintereinander. Fertig. Funktioniert leider > aber nicht so richtig. Wenn zu schnell zweimal gesendet wird, gibts > Murks. Manchaml gibts einfach so Murks. Mit 200 Delays gehts, aber > schnarch langsam. Welche Bitrate ist denn eingestellt, und was ist das für ein µC?
Aha also quasi MIDI für Arme? :D
Find ich gut.
>Geh erstmal mit der Baudrate runter, sagen wir auf 9k6 oder so.
Wo steht wie schnell er gerade unterwegs ist?
Gruß Jonas
Kann es sein, dass das Timing in deinem Controller auf Delays basiert?
Sorry, war gestern unterwegs und muss auch heute Arbeiten. Deswegen in kürze: Controller LPC1766 Baudrate ist 115200 (also viell. ein bisschen flott) Uartinterrupt wollte ich mir sparen, da ich dachte das ist nicht zeitkritisch und frage es einfach in der main ab. Der LPC hat wohl einen Hardwarebuffer... Code poste ich nachher.
Jetta schrieb: > Controller LPC1766 > Baudrate ist 115200 (also viell. ein bisschen flott) LOL. Ich habe hier LPC1768 mit 1,8 MBaud (RS485) zu laufen, und zwar beim minimalen CCLK von 29,49 MHz. Da geht nicht ein Bit verloren. > Uartinterrupt wollte ich mir sparen Dann sollte man aber genau wissen, wie lange die Hauptschleife warten darf. Hint: Nicht allzu lange. Ein Delay() ist dann ziemlich ungeeignet. > Der LPC hat wohl einen Hardwarebuffer... Den man übrigens erst über ein Register einschalten muss. Der 16 Byte FIFO ist dann durchaus nützlich - Deine Hauptschleife muss ihn aber auch schnell genug leeren können.
> Wenn zu schnell zweimal gesendet wird, gibts Murks.
Kommt mir komisch vor.
Was hat denn der µC sonst noch so zu tun?
Das Mutiplexing kanns nicht wirklich sein. Wenn man das nach den Regeln
der Kunst macht (in einem Timer-Interrupt), dann verbraucht das fast
keine Rechenzeit. Auf jeden Fall nicht so viel Rechenzeit, dass man
damit Probleme mit einer UART kriegt, weil man diverse Hardaware-Buffer
nicht rechtzeitig entleeren kann.
Ich denke mal, dein eigentliches Problem besteht darin, dass dein
Multiplexing Murks ist. Die Probleme mit der UART sind nur Symptome, die
ihre Ursache im Multiplexing-Murks haben.
Jim Meba schrieb: > Jetta schrieb: >> Controller LPC1766 >> Baudrate ist 115200 (also viell. ein bisschen flott) > > LOL. Ich habe hier LPC1768 mit 1,8 MBaud (RS485) zu laufen, und zwar > beim minimalen CCLK von 29,49 MHz. Da geht nicht ein Bit verloren. > RS485 != RS232 http://de.wikipedia.org/wiki/RS-232#Leitungsl.C3.A4nge_und_.C3.9Cbertragungsrate Bei 115200 darf das Kabel nicht allzu lang sein und auch die Steckverbindungen sollten was taugen. Ansonsten wird das bei der Geschwindigkeit (rein hardwaremässig) nichts.
@ Daniel V. (danvet) >RS485 != RS232 Ach ne? >Bei 115200 darf das Kabel nicht allzu lang sein und auch die >Steckverbindungen sollten was taugen. Ansonsten wird das bei der >Geschwindigkeit (rein hardwaremässig) nichts. C'mon! 115k2 geht über den rostigsten Klingeldraht, den du dir vorstellen kannst. Das hat mit HF nichts zu tun. Auch an die Stecker werden keine nennenswerten Anforderungen gestellt. Wenn es sein muss, läuft das über einen Schukostecker ;-)
@ Karl Heinz (kbuchegg) (Moderator) >Was hat denn der µC sonst noch so zu tun? >Das Mutiplexing kanns nicht wirklich sein. Wenn man das nach den Regeln >der Kunst macht (in einem Timer-Interrupt), dann verbraucht das fast >keine Rechenzeit. So lange im Forum unterwegs und immer noch so optimistisch? Beeindruckend! >Auf jeden Fall nicht so viel Rechenzeit, dass man >damit Probleme mit einer UART kriegt, weil man diverse Hardaware-Buffer >nicht rechtzeitig entleeren kann. Nicht wenige Kandidaten haben hier schon mit einer blinkenden LED einen 32 Bit Kern in die Knie gezwungen ;-)
Falk Brunner schrieb: > @ Karl Heinz (kbuchegg) (Moderator) > >>Was hat denn der µC sonst noch so zu tun? >>Das Mutiplexing kanns nicht wirklich sein. Wenn man das nach den Regeln >>der Kunst macht (in einem Timer-Interrupt), dann verbraucht das fast >>keine Rechenzeit. > > So lange im Forum unterwegs und immer noch so optimistisch? > Beeindruckend! Ich wollte höflich sein und nicht gleich mit der Tür ins Haus fallen :-)
Soooo... ich habe alles bis auf die Multiplexinggeschichte ausgestellt... daran kanns nicht liegen.. Meine Interruptroutine ist nicht die kürzeste, aber auch nicht sooooo schlecht. Danke für die vielen Antworten, ich denke ich weiß woran es liegt. Es ist wirklich das Problem, dass der Empfang von Daten nicht über einen Interrupt abgearbeitet wird. Die main macht noch andre Sachen und die Daten, welche in der Zwischenzeit gesendet werden, gehen verloren. Warum es dann unsynchron ist weiß ich noch nicht genau (eigentlich müsste ja der nächste SendAll Befehl abgewartet werden. Ich poste trotzdem mal den Code, vielleicht fällt einem ja noch was auf ...
1 | void video_controller(void) |
2 | {
|
3 | static uint8_t row = 0; |
4 | |
5 | const uint8_t row_pins[row_max] = {ROW00, ROW01, ROW02, ROW03, ROW04, ROW05, ROW06}; |
6 | |
7 | //static uint8_t col = 0;
|
8 | |
9 | // DIMMEN?
|
10 | |
11 | if (row < row_max-1) |
12 | row++; |
13 | else
|
14 | row = 0; |
15 | |
16 | // alle Reihen deaktivieren
|
17 | ROW_PORT->FIOPIN &= ~((1 << ROW00)|(1 << ROW01)|(1 << ROW02)|(1 << ROW03)|(1 << ROW04)|(1 << ROW05)|(1 << ROW06)); |
18 | // Masken aktivieren
|
19 | //COL1_PORT->FIOMASK = ~(0x00);
|
20 | LPC_GPIO1->FIOMASK = COL1_PORT_MASK; |
21 | COL2_PORT->FIOMASK = COL2_PORT_MASK; |
22 | // Daten anlegen
|
23 | COL1_PORT->FIOPIN = P_videoRam_read[row] << (COL11-7);// & 0x0007FF80; |
24 | COL2_PORT->FIOPIN = P_videoRam_read[row] << COL18;// & 0x0000007F; |
25 | // Masken deaktivieren
|
26 | COL1_PORT -> FIOMASK = 0x0000; |
27 | COL2_PORT -> FIOMASK = 0x0000; |
28 | |
29 | // aktuelle Reihe aktivieren
|
30 | ROW_PORT->FIOPIN |= (1 << row_pins[row]); |
31 | |
32 | |
33 | }
|
Das Dekativieren sollte man wohl mal in eine Konstante schreiben, eventuell erkennt das der Compiler aber auch .... Hauptteil der Main auf dem Prozessor
1 | if (received_data == SEND_ALL) |
2 | {
|
3 | // Empfange Datenblöcke
|
4 | // zuerst wird ROW0 COL0 - COL6 übertragen (7 Bit) // Rest muss Null sein
|
5 | // dann ROW0 COL7 - COL13 (7 Bit) // Rest muss Null sein
|
6 | // dann ROW0 COL14 - COL18 (5 Bit) // Rest muss Null sein
|
7 | clear_memory(); |
8 | uint32_t row_buffer = 0; |
9 | uint8_t ii = 0; |
10 | //write_row
|
11 | for (ii = 0; ii < 7; ii++) |
12 | {
|
13 | row_buffer = 0; |
14 | // Empfange erstes Datenpaket
|
15 | row_buffer |= uart_get_char_block() << 12; |
16 | row_buffer |= uart_get_char_block() << 5; |
17 | row_buffer |= uart_get_char_block() << 0; |
18 | write_row(ii, row_buffer); |
19 | }
|
20 | |
21 | swap_memory_pointer(); |
22 | }
|
Das ist ein Teil aus meinem C Programm was auf dem PC läuft.
1 | void MyWidget::SendDataRS232() |
2 | {
|
3 | ArrayToVideoRam(); |
4 | ComWrite(COM,0x80); // Send all Befehl |
5 | for (int i = 0; i < rowCount; i++){ |
6 | RS232Write(COM,P_videoRam_write[i]>> (7+5)); |
7 | RS232Write(COM,(P_videoRam_write[i]>> (5)) & 0xFF); |
8 | RS232Write(COM,P_videoRam_write[i]>> (0) & 0x1F); |
9 | }
|
10 | }
|
Falk Brunner schrieb: > @ Daniel V. (danvet) > >>RS485 != RS232 > > Ach ne? > >>Bei 115200 darf das Kabel nicht allzu lang sein und auch die >>Steckverbindungen sollten was taugen. Ansonsten wird das bei der >>Geschwindigkeit (rein hardwaremässig) nichts. > > C'mon! 115k2 geht über den rostigsten Klingeldraht, den du dir > vorstellen kannst. Das hat mit HF nichts zu tun. Auch an die Stecker > werden keine nennenswerten Anforderungen gestellt. Wenn es sein muss, > läuft das über einen Schukostecker ;-) Ich habe nicht behauptet, dass 115k2 Hz HF sei. Natürlich kannst du das über einen rostigen Nagel übertragen. Oder über deinen Klingedraht vom Keller zum Dach schicken. Die Frage ist, was damit passieren soll. Und wenn das eine RS232 sein soll (PC->µC), dann geht das bei 115k2 eben nicht mehr ganz so einfach: http://de.wikipedia.org/wiki/RS-232#Leitungsl.C3.A4nge_und_.C3.9Cbertragungsrate Nach 2m ist Ende Gelände. Aber das scheint ja nicht des TO Problem zu sein.
@ Daniel V. (danvet) >>>Bei 115200 darf das Kabel nicht allzu lang sein und auch die >>>Steckverbindungen sollten was taugen. Ansonsten wird das bei der >>>Geschwindigkeit (rein hardwaremässig) nichts. >Ich habe nicht behauptet, dass 115k2 Hz HF sei. Doch, hast du. > Natürlich kannst du das >über einen rostigen Nagel übertragen. Oder über deinen Klingedraht vom >Keller zum Dach schicken. Auf einmal? Klang im 1. Beitrag noch ganz anders! >Die Frage ist, was damit passieren soll. Ja was wohl? Daten empfangen, wenn's geht fehlerfrei? > Und wenn das eine RS232 sein >soll (PC->µC), dann geht das bei 115k2 eben nicht mehr ganz so einfach: >http://de.wikipedia.org/wiki/RS-232#Leitungsl.C3.A... >Nach 2m ist Ende Gelände. Dummes Gelaber. Schon mal real sowas aufgebaut? Zumal der OP einen USB-TTL Wandler hat, da kann allein das USB-Kabel mal problemlos 5m lang sein. Auch TTL schafft mit 115k2 deutlich mehr als 2m. RS232 mit +/-12V auch, auch wenn es OFFIZIELL nicht so spezifiziert ist.
Falk Brunner schrieb: > Dummes Gelaber. Schon mal real sowas aufgebaut? Zumal der OP einen > USB-TTL Wandler hat, da kann allein das USB-Kabel mal problemlos 5m lang > sein. Auch TTL schafft mit 115k2 deutlich mehr als 2m. RS232 mit +/-12V > auch, auch wenn es OFFIZIELL nicht so spezifiziert ist. Du wirst sicherlich Recht haben.
Jetta schrieb: > Danke für die vielen Antworten, ich denke ich weiß woran es liegt. Es > ist wirklich das Problem, dass der Empfang von Daten nicht über einen > Interrupt abgearbeitet wird. Die main macht noch andre Sachen Dann muss man sich die ansehen. Was sind diese 'anderen Sachen'? Wieviel Zeit geht da drauf. > und die > Daten, welche in der Zwischenzeit gesendet werden, gehen verloren. Warum > es dann unsynchron ist weiß ich noch nicht genau (eigentlich müsste ja > der nächste SendAll Befehl abgewartet werden. > > Ich poste trotzdem mal den Code, vielleicht fällt einem ja noch was auf > ... Multiplexing ist, soweit ich das sehen kann, in Ordnung. > Das Dekativieren sollte man wohl mal in eine Konstante schreiben, > eventuell erkennt das der Compiler aber auch .... Kann man machen. Das ist aber nicht dein Zeitproblem. Dein µC wird ja nicht mit ein paar kHz getaktet sein. > swap_memory_pointer(); Du betreibst double Buffering? Das kann natürlich je nach Anforderung sinnvoll sein. Wenn aber der PC sowieso immer ein komplettes Bild schickt, könnte man auch mal in die Richtung überlegen, ob man das überhaupt braucht. Kein Mensch kann das sehen, wenn in einem Bild für ein paar µs die Pixel im oberen Teil nicht mit den Pixel vom unteren Teil zum selben Bild gehören. Ist ja beim Fernsehen auch nicht anders. Da ist ein Bild auch immer eine prozentual wechselnde Mischung aus 2 Bildern. Es wird schon so sein, wie du das vermutest: Dein 'restlicher' Teil in der Hauptschleife braucht zu lange. Daher bist du mit dem Polling der UART zu langsam und verpasst ein paar Bytes. Irgendwo weiter oben hat mal wer gepostet, dass dein µC eine eingebaute FIFO hat, die man nur aktivieren braucht. Hast du das gemacht?
@ Karl Heinz (kbuchegg) (Moderator) >Du betreibst double Buffering? >Das kann natürlich je nach Anforderung sinnvoll sein. Wenn aber der PC >sowieso immer ein komplettes Bild schickt, könnte man auch mal in die >Richtung überlegen, ob man das überhaupt braucht. Kein Mensch kann das >sehen, wenn in einem Bild für ein paar µs die Pixel im oberen Teil nicht >mit den Pixel vom unteren Teil zum selben Bild gehören. Das würde ich nicht so einfach sagen, gerade bei schnelleren Bildwechseln (aka Animation) kommte dann ggf. zu komischen Interferenzen. Ein sauberes Double Buffering ist da nicht verkehr und bringt keine Nachteile, vom doppelten Speicherbedarf mal abgesehen. > Ist ja beim >Fernsehen auch nicht anders. Da ist ein Bild auch immer eine prozentual >wechselnde Mischung aus 2 Bildern. Das "alte" Fernsehen hat auch ausreichend geflimmert ;-) >s wird schon so sein, wie du das vermutest: Dein 'restlicher' Teil in >der Hauptschleife braucht zu lange. Daher bist du mit dem Polling der >UART zu langsam und verpasst ein paar Bytes. Aus den Codefragmenten wird doch keiner schlau!
Ich denk mal du wirst keine Zertifizierung deines Projektes anstreben (Manche Certs. wollen ein deterministisches Proggi, Ints machen das schwer/unmöglich), dann gibt es keinen Grund nicht jeden Interrupt zu benutzen.
Karl Heinz schrieb: > Multiplexing ist, soweit ich das sehen kann, in Ordnung. Ich würd da gerne ein bischen zurückrudern. Die Funktion video_controller wird doch aus einem Timer-Interrupt heraus aufgerufen. Oder? Wenn nicht, dann ist das nicht in Ordnung. @Falk >> s wird schon so sein, wie du das vermutest: Dein 'restlicher' Teil in >> der Hauptschleife braucht zu lange. Daher bist du mit dem Polling der >> UART zu langsam und verpasst ein paar Bytes. > > Aus den Codefragmenten wird doch keiner schlau! Da hast du grundsätzlich recht. Aus den Codefetzen kann man höchstens schliessen, dass das Problem wahrscheinlich nicht da drinnen zu finden ist. Drum hab ich mich auch recht unverbindlich ausgedrückt. Das einzige, wozu ich mich hinreissen lassen würde, ist das hier
1 | if (received_data == SEND_ALL) |
2 | {
|
3 | // Empfange Datenblöcke
|
4 | // zuerst wird ROW0 COL0 - COL6 übertragen (7 Bit) // Rest muss Null sein
|
5 | // dann ROW0 COL7 - COL13 (7 Bit) // Rest muss Null sein
|
6 | // dann ROW0 COL14 - COL18 (5 Bit) // Rest muss Null sein
|
7 | clear_memory(); |
8 | uint32_t row_buffer = 0; |
9 | uint8_t ii = 0; |
10 | //write_row
|
11 | for (ii = 0; ii < 7; ii++) |
12 | {
|
13 | row_buffer = 0; |
14 | // Empfange erstes Datenpaket
|
15 | row_buffer |= uart_get_char_block() << 12; |
16 | row_buffer |= uart_get_char_block() << 5; |
17 | row_buffer |= uart_get_char_block() << 0; |
18 | write_row(ii, row_buffer); |
19 | }
|
20 | |
21 | swap_memory_pointer(); |
22 | }
|
das sieht ein wenig seltsam aus. Wenn da Double Buffering am Werk ist, wozu dann noch mal eine UMkopieraktion von einem (offenbar) UART-Buffer in den 'Video-Ram'. Man kann doch auch gleich die Bytes von der UART direkt in den Video Ram schieben, durch das Double BUffering sieht man das ja nicht. (Immer unter der Voraussetzung, das ich den Rest des Systemaufbaus so ungefähr richtig erraten habe)
Hallo Falk, Danke für die vielen Antworten. Lerne gerne etwas hinzu. Falk Brunner schrieb: > Aus den Codefragmenten wird doch keiner schlau! Ist aber fast alles was relevant ist. Ich habe in die Main jetzt extra eine kleine Verzögerung eingebaut, sonst ist da nur der UART quatsch drin. Ich will nicht davon ausgehen, dass die immer leerbleibt. Zur Erklärung: Das UART Polling ist der relevante Teil der main. Der video controller wird per timer interrupt regelmäßig aufgerufen. Der doppelte Speicher macht Sinn, da Fragmente sichtbar waren besonderst, wenn der komplette Speicher geleert wurde. Der Rest sind andere Spielreien, welche deaktviert sind (RTC, DCF, Tetris...) clear_memory löscht den speicher write_row schreibte eine Zeile in den Schreibspeicher swap_memory tauscht Schreib und lesespeicher durch Pointertausch. Ich dachte so wäre es übersichtlicher.
Hallo Karl Heinz Karl Heinz schrieb: > Dann muss man sich die ansehen. Was sind diese 'anderen Sachen'? Wieviel > Zeit geht da drauf. > Im Moment eine Warteschleife. Ich mache es jedoch jetzt lieber mit Interrupt, soll ja auch in Zukunft noch funktionieren. >> swap_memory_pointer(); > > Du betreibst double Buffering? Meiner Meinung nach Sinnvoll. Wird für andere Betriebsmodi gebraucht.... Siehe oben. Karl Heinz schrieb: > Ich würd da gerne ein bischen zurückrudern. > Die Funktion video_controller wird doch aus einem Timer-Interrupt heraus > aufgerufen. Oder? > Wenn nicht, dann ist das nicht in Ordnung. Das würde mich dann besonders Interessieren. Was ist dann nicht in Ordnung? Ich finde das per Timerinterrupt am saubersten. Immerhin ist dies die wichtigste Aufgabe, möchte schon die Specs der LEDs einhalten, sonst Rauch. Die sind eh am Limit. Da hätte ich gleich noch eine Frage. Wie könnte man das Hardwareseitig absichern, das bei Ausfall des Multiplexbetriebs Rauch aufsteigt. Würde mich schon ärgern :-) Habe schon an flinke Minisicherungen gedacht, die knapp am Multiplexstrom ausgelegt sind. Dann würde das die LEDs schon wenn alle an sind schützen. Bin aber noch nicht so davon überzeugt :-) Wenn ich z.B. dern Programmer anschließe, schaltet der gerne mal alle Ausgänge auf High, bevor es los geht. Genauso ist es wenn ich den Debuggerstarte und er wartet bis ich den Code ablaufen lasse. Im Moment habe ich noch 2 Watt Widerstände in jeder Zeile, die habe ich auch schon öfters gebraucht.
Karl Heinz schrieb: > das sieht ein wenig seltsam aus. Wenn da Double Buffering am Werk ist, > wozu dann noch mal eine UMkopieraktion von einem (offenbar) UART-Buffer > in den 'Video-Ram'. Man kann doch auch gleich die Bytes von der UART > direkt in den Video Ram schieben, durch das Double BUffering sieht man > das ja nicht. Ja das kann man machen. Der Videobuffer ist aber nicht global. Und ich hatte schon eine Funktion, welche eine ganze Zeile schreibt. Deswegen habe ich die genommen und eine Zeile, d.h. eine 32bit Variable wird jetzt doppelt gebuffert. Finde noch vertretbar, kann ich aber mal durch eine neue Funktion austauschen...
@ was zum lachen (Gast) >> Aus den Codefragmenten wird doch keiner schlau! >Ist aber fast alles was relevant ist. Oft wiederholter Irrtum. Poste vollständige Quelldateien als Anhang. >Ich dachte so wäre es übersichtlicher. Siehe oben.
@ was zum lachen (Gast) >absichern, das bei Ausfall des Multiplexbetriebs Rauch aufsteigt. Würde >mich schon ärgern :-) Duch einen Hardware-Watchdog in Form eines Monoflops, welche nach nur wenig mehr als einer Multiplexzeit die Treiber abschaltet, wenn es nicht per CPU aktiv neu getriggert wird. >Habe schon an flinke Minisicherungen gedacht, die >knapp am Multiplexstrom ausgelegt sind. Vergiss es, die LEDs werden schneller geschädigt als dein Sicherung reagieren kann. >Wenn ich z.B. dern Programmer anschließe, schaltet der gerne mal alle >Ausgänge auf High, bevor es los geht. Nö, er schalltet sie auf Eingang. Damit dein Treiber nicht wild schalten, braucht man passende Pull down Widerstände. >habe ich noch 2 Watt Widerstände in jeder Zeile, die habe ich auch schon >öfters gebraucht. Für die Entwicklung sinnvoll. Siehe http://www.mikrocontroller.net/articles/LED-Matrix#Ansteuerung
Falk Brunner schrieb: > Oft wiederholter Irrtum. Poste vollständige Quelldateien als Anhang. Alles klar. Ist ja gut ;-) Wenn ich mal Zeit habe werde ich den Interrupt einfügen und dann noch mal komplett posten. Falk Brunner schrieb: > Duch einen Hardware-Watchdog in Form eines Monoflops, welche nach > nur wenig mehr als einer Multiplexzeit die Treiber abschaltet, wenn es > nicht per CPU aktiv neu getriggert wird. Das ist ja ne geile Idee. Da wäre ich nicht drauf gekommen. Mal sehn ob ich so einen Kollege in der Bastelkiste finde. Wollte eh noch einen Mosfet als Verpolschutz spendieren, viell. kann man das kombinieren, dass das Monoflop gleich alles ausschaltet. Falk Brunner schrieb: > Nö, er schalltet sie auf Eingang. Damit dein Treiber nicht wild > schalten, braucht man passende Pull down Widerstände. Wild zwar nicht, aber die sind immer an. Das habe ich nicht bedacht, obwohl mir das schonmal passiert ist. Ich dachte bei einem FPGA reichen die internen Pulldowns, bis mir meine Halbbrücke entgegenkam. Vielen Dank Falk! Jetzt will nur noch wissen was an meiner Routine so schlecht sein soll ;-) Karl Heinz wo bist du ? :-D
@ was zum lachen (Gast) >Wenn ich mal Zeit habe werde ich den Interrupt einfügen und dann noch >mal komplett posten. Nein, poste den aktuellen Stand, auch wenn er Fehler hat. >Jetzt will nur noch wissen was an meiner Routine so schlecht sein soll Genau DARUM sollst du das tun, damit du was lernen kannst.
Hallo Falk, Danke für deine Antwort. Kann schon sein, das der Fehler dort steckt, wo man ihn nicht vermutet. Und wahrscheinlich hast du Recht das es Sinn macht ein Minimalbeispiel zu Posten. Bin jetzt erstmal glücklich und eventuell schlauer, werden den Code aber gegen Ende der Woche mal posten (wenn ich wieder zu Hause bin). Vielen Dank für deine Tips! was zum lachen schrieb: > Jetzt will nur noch wissen was an meiner Routine so schlecht sein soll > ;-) > Karl Heinz wo bist du ? :-D Karl Heinz schrieb: > Ich würd da gerne ein bischen zurückrudern. > Die Funktion video_controller wird doch aus einem Timer-Interrupt heraus > aufgerufen. Oder? > Wenn nicht, dann ist das nicht in Ordnung. Das habe ich leider falsch verstanden. Wer lesen kann ich klar im Vorteil, aber für eine doppelte Negierung hat mein Hirnprozi nicht gereicht. -> Wird mit 1kHz aus Timerinterrupt aufgerufen, also in Ordnung (in der main steht die Fkt. nicht). Danke auch dir!
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.