PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie: Mehrere Bits in Register setzen



Mitch64
03.12.2009, 18:29
Hallo und kurze Frage.

Wie kann ich in einem Register mehrere Bits auf einmal setzen?
Irgendwo habe ich mal etwas gelesen, wie man das macht, aber ich kriegs nicht hin.

Der Syntax war etwa so:

Register=(2^Bitname)+(2^Bitname)+(2^Bitname)[+(2^Bitname) ...]

Aber mein Bascom 1.11.9.5 meckert beim Compilieren.

Hier ein Beispiel:

TCCR2A=(2^COM2B1) + (2^COM2A1)

gesetzt werden soll Bit 7 und Bit 5 im Register TCCR2A.

Die Version mit:
TCCR2A=&b10100000

möchte ich nach Möglichkeit vermeiden wegen der schlechten Lesbarkeit.

Kann mir jemand den genauen Syntax nennen, ohne daß der Compiler meckert? Ich finde leider die Seite im Netz nicht mehr.

Der Syntax ähnelt auch etwas an C.

Gruß Mitch.

peterfido
03.12.2009, 18:43
dim B as byte
b=0
set b.5
set b.7
tccr2a=b

Die Routine ist aber langsamer als b=&b10100000.

Mitch64
03.12.2009, 18:51
Diese Variante kenne ich auch. Es geht aber darum, die Bits auf einmal zu setzten und zwar mit den Bitnamen wie oben gezeigt.

screwdriver
03.12.2009, 20:02
Sieh dir mal die Befehle BITS und NBITS in der BASCOM-Hilfe an.

Für mega16 z.B.


Gicr = Gicr And Nbits(int1) -> Löscht Bit7 im Register GICR

Bascom macht daraus:
IN R16,0x3B In from I/O location
PUSH R16 Push register on stack
LDI R24,0x7F Load immediate
MOV R20,R24 Copy register
POP R16 Pop register from stack
AND R16,R20 Logical AND
OUT 0x3B,R16 Out to I/O location



Gicr = Gicr Or Bits(int1) -> Setzt Bit7 in Register GICR

Bascom macht daraus:
IN R16,0x3B In from I/O location
PUSH R16 Push register on stack
LDI R24,0x80 Load immediate
MOV R20,R24 Copy register
POP R16 Pop register from stack
OR R16,R20 Logical OR
OUT 0x3B,R16 Out to I/O location


Edit: Du kannst natürlich mehrere Bits auf einmal Setzen bzw. Löschen - sonst wärs ja witzlos. Also z.B.

GICR= GICR OR BITS(Int1, Int2, Int0)

Mitch64
03.12.2009, 20:15
ist eine interessante Alternative. Leider funktioniert das nur mit Bascom. Wenn ich aber Inline-Assembler nehmen möchte, kann ich das so nicht machen.

Besonders dann nicht, wenn man mal eine Lib draus machen will.

Es gibt aber einen Syntax, den der Compiler kapiert. Ich hatte es nämlich schon mal ausprobiert. Aber der Code war so logisch und simpel, dass ich mir keine Notitz gemacht habe.

Jetzt wollte ich das mal anwenden und merke, ich kriegs nicht mehr zusammen.

Es war irgendwie so:

TCCR2A=(2^COM2B1) + (2^COM2A1)

Das war mit beliebigen Register machbar. Auch um einen Timer zu setzen (Prescaler etc.)

Wenn ich das so schreibe:
TCCR2A=2^COM2B1

funktioniert es. aber mit einem weiteren Bit nicht. Irgendwie war da ein Trick mit den Klammern.

Mitch.

Mitch64
03.12.2009, 21:10
Hallo nochmal an alle,

ich hab die Lösung gefunden.

So muss es lauten:


$regfile = "m168def.dat"

$ASM

!.def temp = r16

ldi temp,2^COM2B1 + 2^COM2A1
OUT TCCR2A , temp

$END ASMDas schluck der Compiler und setzt auch die richtigen bits.
Mein Fehler war, dass ich vergessen hatte, dass das nur mit reinem Assembler so funktioniert.

In Bascom ist die Variante Bits() und NBits() perfekt.

Den Link, wo das steht hab ich wieder gefunden:
http://www.rn-wissen.de/index.php/Bascom

Es steht dort fast ganz unten.

Trotzdem danke an alle, die geholfen haben.

Gruß Mitch.

screwdriver
04.12.2009, 16:11
In Bascom ist die Variante Bits() und NBits() perfekt.

Leider Nein!

Da ich die Bits- und Nbits-Befehle eher selten anwende, war ich selbst ein wenig über die Umständlichkeit des generierten Maschinencodes erstaunt. Also habe ich noch gestern abend die Codezeilen an den BASCOM-Support gemailt und bekam heute morgen Antwort:


hi

something is not right. while the code will work, it is not generated properly.
i will fix it for the 1.119.7 release.


Best regards,

Mark Alberts