Forum: Compiler & IDEs asm Anweisung vereinfachen


von Damien (Gast)


Lesenswert?

Hallo Fachkundige,
ich habe eine asm Anweisung geschrieben die man sicherlich noch 
vereinfachen kann. Die Anweisung stellt eine 8 auf einer 7-Segment 
Anzeige dar, welche mit einem 4511 Decodiert wird. Im Prinzip will ich 
nur wissen wie ich zB. die Pins in DDRD alle auf einmal aktivieren kann 
und nicht alle einzeln. Genauso wie alle Pins in PORT D Low setzten und 
nicht einzeln.

Quellcode:

        asm volatile (
        "sbi %0, %1" "\n\t"             /*Aktiviert den Pin2 (Enable)*/
        "sbi %2, %3" "\n\t"             /*Aktiviert den Pin3 (Input_A)*/
        "sbi %4, %5" "\n\t"             /*Aktiviert den Pin4 (Input B)*/
        "sbi %6, %7" "\n\t"             /*Aktiviert den Pin5 (Input_C)*/
        "sbi %8, %9" "\n\t"             /*Aktiviert den Pin6 (Input_D)*/
        "cbi %10, %11" "\n\t"           /*Setzt Input_A auf Low*/
        "cbi %12, %13" "\n\t"           /*Setzt Input_B auf Low*/
        "cbi %14, %15" "\n\t"           /*Setzt Input_C auf Low*/
        "cbi %16, %17" "\n\t"           /*Setzt Input_D auf Low*/
        "sbi %18, %19" "\n\t"           /*Setzt den Enable Pin auf 
High*/
        "sbi %20, %21" "\n\t"           /*Setzt Input_D auf High*/
        "cbi %22, %23" "\n\t"           /*Setzt den Enable Pin auf Low*/
        :
        : "M" (_SFR_IO_ADDR (DDRD)), "i" (2)
        , "M" (_SFR_IO_ADDR (DDRD)), "i" (3)
        , "M" (_SFR_IO_ADDR (DDRD)), "i" (4)
        , "M" (_SFR_IO_ADDR (DDRD)), "i" (5)
        , "M" (_SFR_IO_ADDR (DDRD)), "i" (6)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (3)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (4)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (5)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (6)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (2)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (6)
        , "M" (_SFR_IO_ADDR (PORTD)), "i" (2)
        );

Danke im Voraus,
Gruß, Damien.

von Peter (Gast)


Lesenswert?

Damien schrieb:
> Im Prinzip will ich
>
> nur wissen wie ich zB. die Pins in DDRD alle auf einmal aktivieren kann
> und nicht alle einzeln.

ldi R16, 255;
out DDRD, R16


warum schreibst du überhaupt ASM wenn du den gcc nutzt?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

1
#define Enable PD2
2
// usw.
3
4
DDRD |= _BV(Enable)|_BV(Input_A)|_BV(Input_B)|_BV(Input_C)|_BV(Input_D);
5
PORTD &= ~(_BV(Input_A)|_BV(Input_B)|_BV(Input_C)|_BV(Input_D));
6
PORTD |= _BV(Enable);  // => sbi (s.u.)
7
PORTD |= _BV(Input_D); // => sbi
8
PORTD &= ~(_BV(Enable)); // => cbi

http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html

Porting programs that use the deprecated sbi/cbi macros

Access to the AVR single bit set and clear instructions are provided via 
the standard C bit manipulation commands. The sbi and cbi macros are no 
longer directly supported. sbi (sfr,bit) can be replaced by sfr |= 
_BV(bit).

i.e.: sbi(PORTB, PB1); is now PORTB |= _BV(PB1);

This actually is more flexible than having sbi directly, as_ _the 
optimizer_ _will_ _use_ _a_ _hardware_ _sbi_ _if_ _appropriate, or a 
read/or/write operation if not appropriate. You do not need to keep 
track of which registers sbi/cbi will operate on.

von Peter D. (peda)


Lesenswert?

Damien schrieb:
> ich habe eine asm Anweisung geschrieben die man sicherlich noch
> vereinfachen kann.

Ja, kann man. Schreibs in C.
Assembler nimmt man nur, wenns in C nicht geht oder deutlich aufwendiger 
ist.


> Die Anweisung stellt eine 8 auf einer 7-Segment
> Anzeige dar, welche mit einem 4511 Decodiert wird.

Schau Dir dochmal andere MC-Projekte an. Du wirst da nie nen 7-Segment 
Dekoder sehen. Das kann die CPU nämlich sehr gut selber machen.


Und man macht auch nicht 10 Ausgaberoutinen für 10 Ziffern.
Ziffern sind ja quasi das, womit die CPU arbeitet, da muß man sich nicht 
umständliche Sachen ausdenken.

Eine Ziffer hat den Wert 0..9, diesen einer Routinen übergeben, die die 
10 7-Segmentmuster aus ner Tabelle liest und auf das gewünschte Digit 
ausgibt. Die Ziffer ist also der Zeiger auf den Tabelleneintrag.


Peter

von Damien (Gast)


Lesenswert?

Hallo,
so hatte ich mir das ungefähr gedacht:

        asm volatile (

        "ldi r16, 0xFF" "\n\t"
        "out [_DDRD], r16" "\n\t"

        "out [_PORTD], 0x00" "\n\t"

        "sbi [_PORTD], 0x04" "\n\t"             /*Setzt den Enable Pin 
auf High*/
        "sbi [_PORTD], 0x40" "\n\t"             /*Setzt Input_D auf 
High*/
        :
        : [_DDRD] "M" (_SFR_IO_ADDR (DDRD))
        , [_PORTD] "M" (_SFR_IO_ADDR (PORTD))

        );

aber das Problem ist das ich den falschen constrain benutze und er nicht 
versucht in "DDRD" sondern in "_DDRD" zu schreiben.. kann mir einer 
helfen?

von Klaus (Gast)


Lesenswert?

Alter! Verabschiede dich von dem Assemblerkrams und lerne C!

von Peter (Gast)


Lesenswert?

und warum schreibs nicht einfach als C

DDRD = 255;

ist das zu einfach?

von Damien (Gast)


Lesenswert?

Ja natürlich ist es das ^^

Ich kann C.. ich will nur ein bisschen mit den asm Befehlen rumspielen 
um ein bisschen das gefühl dafür zu bekommen.. Ich weiss schon das es in 
C einfacher ist aber mich interessiert einfach wie es in assembler läuft 
;)

Wenn mir einer mit dem Problem helfen kann wäre ich sehr dankbar

von Peter (Gast)


Lesenswert?

dann mach auch richtig ASM und nicht C mit ASM. Leg ein neuen Projekt in 
AVRStudion an und schreib es mit ASM.

von Peter D. (peda)


Lesenswert?

Damien schrieb:
> Ich kann C.. ich will nur ein bisschen mit den asm Befehlen rumspielen
> um ein bisschen das gefühl dafür zu bekommen.

Oh, dann habe ich Dich mißverstanden. Ich dachte Du brauchst Hilfe bei 
einem Problem.
Aber es soll ja nur Spiel sein, da will ich Dich nicht weiter dabei 
stören.

GCC Inline Assembler gucke ich mir nicht ohne größte Not an, das ist 
einfach nur gräßlich.


Peter

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.