Der Titel sagt eigendlich shcon alles: Ich lese einen 13-Bit (12+Sign) Wert von einem Bipolaren ADC (AD7322) und möchte den Wert nun in ein digitales Filter (16Bit signed Int) schicken. Sind die Werte positiv passt alles, aber bei negativen Werten muss ich ja mit dem MSB des 13Bit Wertes auffüllen. Das Problem ist nur, das es möglichst schnell gehen soll, der arme µc (AT91SAM7s) ist ja schon mit dem Digitalfilter recht ausgelastet. Kennt jemand bitte einen Trick?
Es müsste doch genügen, das Vorzeichenbit zu testen und zu verzweigen. Wenn dieses Bit gesetzt ist mit 0b11100000 oderieren und evtl. vorher noch das Komplement des ganzen Wertes bilden, je nach dem, wie das Ergebnis genau angeliefert wird. Das sind insgesamt so 5 bis 7 Befehle, das wird er wohl noch schaffen nebenbei, der arme µC... Grüße, Peter
^Geht es nicht, das ganze als unsigned short nach links zu schieben sodass das Vorzeichenbit an der richtigen position ist und dann das ganze als signed short wieder zurück zu schieben? Die erste Operation wird aufgrund des unsigneds ein logisches schieben - also alle bits. Die zweite operation schieb nur die unteren 15 bit, weil ja signed - arithmetisches schieben. Kann sein das ich mich irre... man könnte es aber doch mal probieren. Ich meine das so: signed short bla = ((unsigned shiort)(_13BitSignedValue)) << 3; bla >>= 3; ??? MFG
funktioniert meine Variante wäre sie unschlagbar kurz. shl xxx, 3 asr xxx, 3 fertig.
Albi wrote: > funktioniert meine Variante wäre sie unschlagbar kurz. > > shl xxx, 3 > asr xxx, 3 > > fertig. Ja unschlagbar auf einem AVR mit Barrelshifter und 16 bit Architektur... Keine Ahnung ob der SAM sowas hat??? Sonst wird da ja sowas draus:
1 | lsl X_L |
2 | rol X_H |
3 | lsl X_L |
4 | rol X_H |
5 | lsl X_L |
6 | rol X_H |
7 | |
8 | asr X_H |
9 | ror H_L |
10 | asr X_H |
11 | ror H_L |
12 | asr X_H |
13 | ror H_L |
= 12 Takte Aus meiner Variante könnte der Compiler machen:
1 | andi X_H, HIGH(1<<12) |
2 | brne _skip |
3 | ori X_H, HIGH(0xE000); |
4 | skip: |
= 3 Takte Leztendlich ist es aber wohl ne Aufgabe die der µC noch gerade so schaffen sollte ;)
ADC += 0xF000; ADC ^= 0xF000; jetzt mal 16 Bit Arithmetik voraus gesetzt :-)
Nun wirds interessant. Ich denke der SAM hat das :-)
@Läubi: Warum die 12-Takt-Version nicht auf eine 6-Takt-Version schrumpfen, das Schieben der unteren 8 Bit kann man doch sein lassen: rol X_H rol X_H rol X_H asr X_H asr X_H asr X_H = 6 Takte, naja 6 Befehle Deine "compilergenerierte" Version wird allerdings nicht funktionieren, weil ein AND-Befehl, wie ich ihn kenne, zerstörend auf die Nutzdaten wirkt, die hinten wieder gebraucht werden. Da muss also nochmal irgendwie zwischengespeichert werden. Ein Branch-Befehl braucht mehr als einen Takt, ein AND und/oder OR (LOL) mit Konstante auch. Von 3 Takten ist da weit und breit keine Spur zu sehen... :-)
Hast Recht mein Fehler, man könnte aber ein "skip if bit is set" ;) beim AVR dauern aber alle and/or/xor 1 Takt, ein Sprung dauert 1 Takt wenn er nicht genommen wird und 2 wenn nicht. Aber wie gesagt ich kenn mich mit dem SAM+Befehlssatz nicht aus :( Alles in allem aber dauert der Spaß nicht soooooooooo lang das man da optimierungspotenzial hat.
Dem SAM (ARM7) ist es egal, ob ein Byte oder ein 32-Bit-Wort, ob um 1 oder um 19 Bits geshiftet wird. Deswegen ist die von Albi vorgeschlagene Methode, erst an den linken Anschlag und dann wieder zurückzushiften, wahrscheinliche die schnellste.
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.