Am Port klappern

Gast #1674007
Lesenswert?

Hallo,
ich fummel mit dem ATtiny25 rum, um in die Materie rein zu kommen.
Bisher habe ich wenn ich einen Port setzen / löschen wollte das so 
gemacht:
1
#define LED_rot_an   {PORTB &= ~(1 << DDB4);}
2
#define LED_rot_aus   {PORTB |=  (1 << DDB4);}

Jetzt bin ich in der Instruction Set Summary auf die Befehle
SBI P,b Set Bit in I/O Register und
CBI P,b Clear Bit in I/O Register
gestossen.
Wie kann ich den Compiler (GCC = AVRWIN) überreden diese befehle zu 
benutzen?
1
#define LED_rot_an {asm volatile("CBI   PORTB,4");}
gibt leider Fehlermeldung.
Wie geht die richtige Schreibweise?
Gast #1674034
Lesenswert?

>ich fummel mit dem ATtiny25 rum, um in die Materie rein zu kommen.
imho würde ich empfehlen um in die materie reinzukommen mit assembler 
die ersten gehversuche zu machen.

zu deinem problem, google man nach gcc inline-assembler.
#1674041
Lesenswert?

Oliver schrieb:
> Timmo H. schrieb:
>> Den Rest erledigt dein Compiler.
>
> wenn du den auch optimieren lässt.

Du hast natürlich recht.
Allerdings gehe ich schon davon aus, dass man sein Programm durch den 
Optimizer jagt. Schliesslich haben eine Menge Leute eine Menge 
Gehirnschmalz da rein gesteckt, so dass ich mich auf das Problem 
konzentrieren kann anstatt auf die vielen kleinen Details und der 
Compiler sorgst dafür, dass meine Programmidee so gut wie möglich auf 
der Assembler-Ebene umgesetzt wird.
#1674044
Lesenswert?

... ... schrieb:
> Karl heinz Buchegger schrieb:
>>> Wie geht die richtige Schreibweise?
>> #define LED_rot_an    do {PORTB &= ~(1 << PB4);} while( 0 )
>> #define LED_rot_aus   do {PORTB |=  (1 << PB4);} while( 0 )
>
> Was soll das do..while da?

Lass es weg und schreib mal
1
   if( i == j )
2
     LED_rot_an;
3
   else
4
     LED_rot_aus;

und erfreu dich an der Fehlermeldung, dass ein else existiert, für das 
es kein if gibt.
Oder noch fieser
1
   if( k == 0 )
2
     if( i == j )
3
       LED_rot_an;
4
     else
5
       LED_rot_aus;

das else gehört zum if( k == 0 ).
Nicht ganz das, was du dir vorgestellt hast, oder?

Warum das so ist?
Mach die Textersetzung und sieh selber.
Gast #1674047
Lesenswert?

grr..

Karl heinz Buchegger schrieb:
> Den Rest erledigt dein Compiler.

Die Zitatfunktion hier im Forum ist nicht idiotensicher ...

syn_error schrieb:
> imho würde ich empfehlen um in die materie reinzukommen mit assembler
> die ersten gehversuche zu machen.

Ich nicht. Ich würde, um in die Materie reinzukommen, erst einmal völlig 
die Finger von Assembler lassen. Planloses vermischen von C und 
Assembler bringt, wie dieses Beispiel hier ja auch wieder zeigt, gar 
nichts.

Oliver
#1674071
Lesenswert?

... ... schrieb:
> Karl heinz Buchegger schrieb:
>> Nicht ganz das, was du dir vorgestellt hast, oder?
>
>
1
> #define LED_rot_an   PORTB &= ~(1 << DDB4)
2
> #define LED_rot_aus   PORTB |=  (1 << DDB4)
3
>
>
> so finde ich die defines auch besser, oder ist das auch doof/ungünstig?

Nein.
In dem Fall ist das ok und völlig identisch zu der Version mit den { } 
rundum. Aber wenn man schon { } macht (weil man zb mehrere Anweisungen 
durch das Makro einbringen möchte) dann muss man das auch richtig machen 
:-)

Entscheidend ist, dass ich bei der Makro-Verwendung noch einen ; hinten 
drann machen kann, ohne dass sich die Semantik ändert
Gast #1674226
Lesenswert?

Oktoberfestbesucher schrieb:
> habe dieses probiert,#define LCD_Data_0  asm volatile("cbi _SFR_IO_ADDR 
>PORTB),4");
>
> geht überhaupt nicht.

Natürlich geht das nicht. cbi_SFR_IO_ADDR ist eine C-Funktion (bzw. ein 
makro) aus der avrlibc.

Lass doch den Assembler Assembler sein, und schreib dein Programm in C. 
Der C-Compiler kennt wirklich alle erforderlichen Assemblerbefehle, und 
weiß die auch zu nutzen. Auch sbi und cbi.

Schau dir mal im .lss-File an, was der Compiler aus der Zeile
1
PORTB &= ~(1 << DDB4);

mit eingeschalteter Optimierung macht.

Oliver
Gast #1674246
Lesenswert?

Oliver schrieb:
> Schau dir mal im .lss-File an, was der Compiler aus der Zeile
> PORTB &= ~(1 << DDB4);
> mit eingeschalteter Optimierung macht.
>
> Oliver

1
 c0:  c4 98         cbi  0x18, 4  ; 24


Sehr guter Tip,
ich staune Bauklötze, woher weis der Compiler so schlau, was ich will?
#1674259
Lesenswert?

Oktoberfestbesucher schrieb:
> Oliver schrieb:
>> Schau dir mal im .lss-File an, was der Compiler aus der Zeile
>> PORTB &= ~(1 << DDB4);
>> mit eingeschalteter Optimierung macht.
>>
>> Oliver
>
>
>
1
>  c0:  c4 98         cbi  0x18, 4  ; 24
2
>
>
>
> Sehr guter Tip,
> ich staune Bauklötze, woher weis der Compiler so schlau, was ich will?

Du willst mit

    PORTB &= ~(1 << 4);

Das Bit 4 am PortB auf 0 setzen. Das hier ist die C-Schreibweise dafür. 
Irgendein kluger Mensch hat sich mal überlegt, dass wenn man das plain 
Vanilla übersetzt, da immer diese Sequenz rauskommt

     IN      r_irgendwas, PORTB
     ANDI    r_irgendwas, ~(1<<wert)
     OUT     PORTB, r_irgendwas

und dass man diese Sequenz gefahrlos gegen

     cbi     PORTB, wert

ersetzen kann. Macht dasselbe, ist aber kürzer (und versaut keine Flags 
bei der Ausführung). Alles was er tun muss, ist während der 
Optimierungsphase nach solchen Sequenzen zu suchen und die Ersetzung 
vorzunehmen, ehe dann das endgültige Programm in Maschinensprahce 
erzeugt  wird.

Das sagen wir doch schon die ganze Zeit: Compilerbauer sind keine 
Volltrottel. Die haben noch ganz andere Optimierungstricks auf Lager.

(Compilerbauer mögen mir verzeihen, wenn ich das jetzt absichtlich 'ein 
klein wenig vereinfacht' darstelle.)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren