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?
Der Compiler sollte das schon so automatisch aus deinem ersten Ansatz
machen.
Zudem kann man auch über C bereits diese Makros aufrufen ( cbi() und
sbi()) wobei das nicht bei jedem Compiler geht.
Timmo H. schrieb:> Den Rest erledigt dein Compiler.
wenn du den auch optimieren lässt. Sonst produziert der da tatsächlich
sehr länglichen Code.
Oliver
>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.
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?
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.
... ... 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.
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
>> 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
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
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?
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.)