Forum: Compiler & IDEs SBIC Befehl in C++


von Andy S. (1632andys)


Lesenswert?

Hi Leute,

weis einer von euch vielleicht wie es möglich ist mit GNU den Assembler 
Code "SBIC" zu implementieren?

Habe folgendes Problem:
Es wird in einer ISR ein Taster abgefragt, welcher entsprechend dem 
Zustand eine Variable incrementiert.

  if (PINB & 1<<PINB0)
  {
    counter1+=100;
  }

Der Assembler Code sieht so aus:

  if (PINB & 1<<PINB0)
00000036  SBIS 0x16,0    Skip if bit in I/O register set
00000037  RJMP PC+0x000B    Relative jump
    counter1+=100;
00000038  LDS R24,0x0062    Load direct from data space
0000003A  LDS R25,0x0063    Load direct from data space
0000003C  SUBI R24,0x9C    Subtract immediate
0000003D  SBCI R25,0xFF    Subtract immediate with carry
0000003E  STS 0x0063,R25    Store direct to data space
00000040  STS 0x0062,R24    Store direct to data space

Bitte versteht mich nicht falsch, das Programm funktioniert. Leider ist 
es so, dass ich die internen Pullups meines ATmega8 verwende möchte, 
welche mit einem Taster auf GND gezogen werden.
Was der µC jetzt macht, ist ständig die Variable zu erhöhen, weil er 
natürlich einen logic 1 Pegel registiert.

Was muss nun in der Bedingung des IF-Befehlts verändert werden, damit er 
anstatt des SIBS ein SBIC im assembler Code erzeugt?

- Andy

von Peter II (Gast)


Lesenswert?

if (!(PINB & 1<<PINB0) )

von Sam P. (Gast)


Lesenswert?

1
if (!(PINB & ~(1<<PINB0))) {
2
    ...
3
}

Der AVR-GCC ist i.A. klug genug, aus der C-Logik die passende 
AVR-Assemblerinstruktion zu bauen, d.h. du musst nur die if-Abfrage 
entsprechend anpassen. Kümmer dich nicht um den Åssemblercode, es sei 
denn du bekommst konkrete Performance/Zeitprobleme.

Der Lesbarkeit und Dokumentation halber würde ich der Konstanten 
~(1<<PINB0) übrigens per #define einen sinnvollen Namen geben, z.B. 
"TasterXY", das macht es übersichtlicher und verständlicher.

von Sam P. (Gast)


Lesenswert?

Argh, vergiss meinen C-Code. Peter II hat natürlich recht. 
Hirnaussetzer. Aber das mit dem #define solltest du dir selbst zuliebe 
trotzdem machen.

von Andy S. (1632andys)


Lesenswert?

Vielen Dank für die schnelle Antwort!

Das mit den #define ist ein guter Tipp danke!
Mir ging es ohnedies nicht um Performance sonder um den Code an sich.

if (!(PINB & 1<<PINB0))

ist übgrigens die richtige Lösung, sollte noch jemand das gleiche 
Problem haben.

  if (!(PINB & 1<<PINB0))
00000036  SBIC 0x16,0    Skip if bit in I/O register cleared
00000037  RJMP PC+0x000B    Relative jump

Mit

if (!(PINB & ~(1<<PINB0))) {
    ...
}

erzeugt der Compiler folgendes:

  if (!(PINB & ~(1<<PINB0)))
00000036  IN R24,0x16    In from I/O location
00000037  ANDI R24,0xFE    Logical AND with immediate
00000038  BRNE PC+0x0B    Branch if not equal

wobei ich nicht sagen kann ob das nur bei der von mir verwendeten 
Version der Fall ist.(gcc Verion 4.5.1)

von Peter D. (peda)


Lesenswert?

Andy S. schrieb:
> Es wird in einer ISR ein Taster abgefragt, welcher entsprechend dem
> Zustand eine Variable incrementiert.

In der Regel macht man das nicht so.

Bei Tasten interessiert oft nicht der Zustand, sondern die 
Zustandsänderung von Losgelassen nach Gedrückt. Das macht man dann 
bequemer Weise in einem Timerinterrupt, der dann die Taste gleich 
entprellt und gleich auch ein Autorepeat machen kann, wenn gewünscht.

Beitrag "Universelle Tastenabfrage"

Und da man oft mehrere Tasten hat, macht die Routine das gleich für den 
ganzen Port (8 Tasten) ohne jeden Mehraufwand.


Peter

von Andy S. (1632andys)


Lesenswert?

Peter Dannegger schrieb:
> Das macht man dann
> bequemer Weise in einem Timerinterrupt, der dann die Taste gleich
> entprellt

Genau das wird ja auch gemacht. Ein timer nimmt mit ca. 450 Hz die 
Tasterabfrage vor.

Ich sollte vielleicht noch erwähnen, dass es sich um ein sehr einfaches 
Programm handelt, welches nur zu testzwecken mal "schnell" geschrieben 
wurde. (Vereinfacht ein Stobolicht, welches mit einem 16 bit Timer der 
vorgeladen wird, in der Frequenz verändert werden kann)

Was ich aber nicht ganz verstehe:

Peter Dannegger schrieb:
> Bei Tasten interessiert oft nicht der Zustand, sondern die
> Zustandsänderung von Losgelassen nach Gedrückt.

Das würe in diesem Fall ja nichts bringen, ich möchte eben gerade, dass 
die Variable mit der Geschwindigkeit von 450 Hz geändert wird.

Oder hab ich da was falsch verstanden?

von Karl H. (kbuchegg)


Lesenswert?

Andy S. schrieb:

> Oder hab ich da was falsch verstanden?

Ich denke, du sprichst von ganz was anderem.

Peter spricht von der Tastenauswertung.

Du drückst die Taste nieder, das Stroboskop geht an.
Du lässt die Taste los, das Stroboskop blinkt weiter.

Du drückst die Taste nochmal, das Stroboskop geht wieder aus.
Du lässt die Taste los, das Stroboskop bleibt aus.


Eben ein ganz normaler Ein/Ausschalter, der eine Funktion durch 
Tastendruck aktiviert bzw. deaktiviert. Bei jedem mal Draufdrücken wird 
eine Aktion ausgelöst. Aber NUR beim Draufdrücken.
Im Gegensatz dazu steht die Funktionalität: Mache was, solange eine 
Taste gedrückt IST. Auch das kann manchmal sinnvoll sein. Wenn du haben 
willst, dass dein Stroboskop dann arbeiten, wenn du mit dem Finger auf 
der Taste einschläfst, dann ist dieser Modus dein Ziel.

von Peter D. (peda)


Lesenswert?

Andy S. schrieb:
> Das würe in diesem Fall ja nichts bringen, ich möchte eben gerade, dass
> die Variable mit der Geschwindigkeit von 450 Hz geändert wird.

Das dürfte weit über dem menschlichen Reaktionsvermögen sein.
Die Variable ist dann fast schon ein Zufallszahlengenerator.

Ich benutze 5Hz (200ms) als Repeatfrequenz.
Aber erst nach 500ms, d.h. man kann auch Einzeldrücke zählen.


Peter

von Marwin (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Andy S. schrieb:
>> Es wird in einer ISR ein Taster abgefragt, welcher entsprechend dem
>> Zustand eine Variable incrementiert.
> In der Regel macht man das nicht so.

Du weisst doch gar nicht, was er machen will.

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
Noch kein Account? Hier anmelden.