Ist es möglich diesen Code noch zu optimieren ? Die SPI Ausgabe ist einfach zu langsam ich komme aber nicht weiter, letterptr ist der Anfang in einer lookup Tabelle, a stellt dann den index innerhalb der Tabelle dar. Das ganze aus dem Ram statt Flash zu machen scheint keinen Geschwindigkeitsvorteil zu bringen. Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit Assembler noch ein paar Takte rauszuholen ? a = *textptr++; nextbyte = pgm_read_byte(letterptr+a); while (*textptr != 0) { a = *textptr++; SPDR = nextbyte; nextbyte = pgm_read_byte(letterptr+a); while(!(SPSR & (1<<SPIF))); } SPDR = nextbyte; while(!(SPSR & (1<<SPIF)));
@ Christian Ulrich (z0m3ie) >Ist es möglich diesen Code noch zu optimieren ? Sicher. >Die SPI Ausgabe ist einfach zu langsam ich komme aber nicht weiter, >letterptr ist der Anfang in einer lookup Tabelle, a stellt dann den >index innerhalb der Tabelle dar. Das ganze aus dem Ram statt Flash zu >machen scheint keinen Geschwindigkeitsvorteil zu bringen. Tut es auch nicht. Siehe hier. AVR-Tutorial: Schieberegister >Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit >Assembler noch ein paar Takte rauszuholen ? Nicht wirklich. C wird schon brauchbar übersetzt, wenn man es richtig hinschreibt. Etwa so.
1 | a = *textptr++; |
2 | nextbyte = pgm_read_byte(letterptr+a); |
3 | while (a != 0) |
4 | {
|
5 | while(!(SPSR & (1<<SPIF))); |
6 | SPDR = nextbyte; |
7 | a = *textptr++; |
8 | nextbyte = pgm_read_byte(letterptr+a); |
9 | }
|
10 | while(!(SPSR & (1<<SPIF))); |
11 | SPDR = nextbyte; |
12 | while(!(SPSR & (1<<SPIF))); |
Der Trick dabei ist, während die Übertragung läuft das nächste Byte zu holen und danach erst zu prüfen, ob sie zu Ende ist. In deinem Beispiel verplemperst du Zeit um auf das Ende der Übertragung zu warten und DANACH erst das nächste Byte zu holen. MFG Falk
> Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit > Assembler noch ein paar Takte rauszuholen ? Dazu müßte man sich den ASM-Code, den der Compiler erzeugt, mal näher ansehen und überlegen, was man besser machen kann. Dem C-Code sieht man das nicht an.
Hallo Falk, in der Zwischenzeit hatte ich das selbst schon gesehn und meinen Code so geändert: a = *textptr++; nextbyte = pgm_read_byte(letterptr+a); while (*textptr != 0) { SPDR = nextbyte; a = *textptr++; nextbyte = pgm_read_byte(letterptr+a); while(!(SPSR & (1<<SPIF))); } SPDR = nextbyte; while(!(SPSR & (1<<SPIF))); Damit sollte das ja wenn ich das richtig seh keinen unterschied mehr zu deinem code machen. Jedoch hat das nicht genug gebracht. ich hab immer noch lücken in der ausgabe die so groß sind wie die ausgabezeit selbst. Ich hab auch schon mit dem Assemblercode geschaut und das vorher schon etwas optimiert nur programmiere ich nie in assembler und kann so schlecht einschätzen ob man das nicht inline optimaler lösen könnte. ich poste montag mal den erzeugten code.
Hi, probiers doch mal mit Interrupt. Dann musst das Programm nicht warten, bis die Übertragung fertig ist, sondern bekommst das per Interrupt mitgeteilt. Gruß, Alex
Ich fürchte das wird eher schlimmer da ich ja irgendwann die neuen daten holen muss. Das mach ich jetzt wärend der Ausgabe, dann kann ich das aber nicht mehr machen.
@ Alexander Heß (ill_son) >probiers doch mal mit Interrupt. Dann musst das Programm nicht warten, >bis die Übertragung fertig ist, sondern bekommst das per Interrupt >mitgeteilt. Und? Wird es dann schneller? NEIN! Für maximale SPI Geschwindigkeit muss man pollen. @ Christian Ulrich (z0m3ie) >in der Zwischenzeit hatte ich das selbst schon gesehn und meinen Code so >geändert: Warum fragst du zweimal *textptr ab? Da muss der Compiler, wenn er es nicht erkennt, zweimal den Pointer defererenzieren, obwohl a den gleichen Inhalt hat. >a = *textptr++; >nextbyte = pgm_read_byte(letterptr+a); >while (*textptr != 0) > { > SPDR = nextbyte; > a = *textptr++; > nextbyte = pgm_read_byte(letterptr+a); > while(!(SPSR & (1<<SPIF))); > } >SPDR = nextbyte; >while(!(SPSR & (1<<SPIF))); Pssst soweit. Besser kann man es wahrscheinlich nicht machen. Und man muss sehen, dass da immerhin zwei Pointer dereferenziert werden müssen. > a = *textptr++; Das ist recht einfach, daraus wird eine ld rx,z+ > nextbyte = pgm_read_byte(letterptr+a); Hier muss jedes mal letterptr geladen werden und der Offset a als 16 Bit Offset addiert werden, dann kommt lpm. Das dauert schon ein paar Takte. >deinem code machen. Jedoch hat das nicht genug gebracht. ich hab immer >noch lücken in der ausgabe die so groß sind wie die ausgabezeit selbst. Naja, rechne mal. Bei SPI-Takt = CLK/2 bleiben gerade mal 16 Takte pro Byte. Das wird knapp mit den zwei Pointeroperationen. >ich poste montag mal den erzeugten code. OK. MfG Falk
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.