Forum: Mikrocontroller und Digitale Elektronik Kleines C-Prog geht nicht


von HH (Gast)


Lesenswert?

Guten Morgen,
brauche mal eure Hilfe bei einem kleinen Syntax-Fehler. Hier mal der 
Code:

int main(void)
{
   DDRA = 0x0F;
   while(1)
  {
    PORTA = 3;
    _delay_ms(500);
    PORTA &= (0<<PA0);
    _delay_ms(500);
  }
}

LED an Port A.0 blinkt ordnungsgemäß wie erwartet nur die LED A.1 blinkt 
gleichzeitig mit. Sie dürfte eigentlich mit der LED an A.0 an gehen und 
dann nicht mehr ausgehen.
Verwende gerade das Studio 6.2 mit dem internen C-Compiler. Warum wird 
überhaupt ein Schiebebefehl verwendet um Ports zu schalten? Bei BASCOM 
ist es doch so einfach. Habe aber gerade eine zeitkritische Anwendung.
Danke HH

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HH schrieb:
> PORTA &= (0<<PA0);
Was willst du damit bezwecken? Erkläre es mal Schritt für Schritt....

von A. (Gast)


Lesenswert?

1
int main(void)
2
{
3
   DDRA = 0x0F;
4
   while(1)
5
  {
6
    PORTA |= 3;
7
    _delay_ms(500);
8
    PORTA &= ~3;
9
    _delay_ms(500);
10
  }
11
}

Finde die Unterschiede und versuche sie selbststständig zu verstehen!

von Dr. Sommer (Gast)


Lesenswert?

HH schrieb:
> brauche mal eure Hilfe bei einem kleinen Syntax-Fehler

Da es kompiliert ist es offensichtlich kein Syntax-Fehler... Überleg 
doch mal genau was (0 << PA0) für einen Wert hat.

von Ähhmm Ja (Gast)


Lesenswert?

HH schrieb:
> Habe aber gerade eine zeitkritische Anwendung.

HH schrieb:
> _delay_ms(500);

von HH (Gast)


Lesenswert?

Ja mit

PORTA &= ~(1<<PA0); funktioniert es und mit
PORTA = ~(1<<PA0); blinken die LEDs 0 und 2,3,4,5,6,7 abwechselnd. 3 
bleibt ein!
Trinke erst mal einen Kräuter!
Danke

von Curby23523 N. (Gast)


Lesenswert?

ICh weiß ja nicht welchen Controller du verwendest. Eigentlich sollte
1
    PORTA = 3;
2
    _delay_ms(500);
3
    PORTA &= (0<<PA0);
4
    _delay_ms(500);

funktionieren. Möglicherweise liegt so etwas vorkonfiguriertes wie JTAG 
auf dem Pin?

von Einer K. (Gast)


Lesenswert?

1
int main(void)
2
{
3
   DDRA  |= (1<<PA1)|(1<<PA0);
4
   PORTA |= (1<<PA1)|(1<<PA0);
5
6
   while(1)
7
   {
8
    PINA = (1<<PA0);
9
    _delay_ms(500);
10
   }
11
}


Funktioniert mit allen etwas moderneren AVR.
z.B. ATTiny85 ATMega328p

von HH (Gast)


Lesenswert?

Hallo Curby,
dachte auch dass PORTA &= (0<<PA0); funktioniert und nur A.0 
ausschaltet.
Aber eben nur der Befehl PORTA &= ~(1<<PA0); funktioniert. Dann mache 
ich es eben so. ;-(
Habe einen Tiny461A dran.

von Einer K. (Gast)


Lesenswert?

HH schrieb:
> dachte auch dass PORTA &= (0<<PA0); funktioniert und nur A.0
> ausschaltet.

Wieso?

irgendwas & null, ist null

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HH schrieb:
> Dann mache ich es eben so.
Ich hatte den Tipp mit dem Nachdenken über den < Operator gegeben. Du 
solltest ihn befolgen, denn solche Bitoperationen werden dir laufend 
begegnen.

Ein Tipp dazu: PA0 ist in einem  Headerfile definiert als 0

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

HH schrieb:
> Habe einen Tiny461A dran.
Der ist modern genug!
Toggeln mit "PINA = (1<<PA0);" also möglich.

von MaWin (Gast)


Lesenswert?

Curby23523 N. schrieb:
> Eigentlich sollte    PORTA = 3;
>     _delay_ms(500);
>     PORTA &= (0<<PA0);
>     _delay_ms(500);
>
> funktionieren.

Aha.

Schon HH schrieb, dass es nicht funktioniert. Das gibt dir nicht zu 
Denken ?

von M. K. (sylaina)


Lesenswert?

Curby23523 N. schrieb:
> ICh weiß ja nicht welchen Controller du verwendest. Eigentlich sollte
>
1
>     PORTA = 3;
2
>     _delay_ms(500);
3
>     PORTA &= (0<<PA0);
4
>     _delay_ms(500);
5
>
>
> funktionieren. Möglicherweise liegt so etwas vorkonfiguriertes wie JTAG
> auf dem Pin?

Klar funktioniert das, deshalb Compiliert das auch ohne Fehler. Aber 
auch für dich, überlege mal was
1
PORTA &= (0<<PA0)

Bewirken wird. Grade ein Anfänger wird das falsch interpretieren ;)

: Bearbeitet durch User
von HH (Gast)


Lesenswert?

Irgendwie bewirkt der Befehl:
PORTA &= (0<<PA0);
dass der gesamte PORTA mit Null überschrieben wird und nicht nur PA.0!
Mache mal Pause ......
Danke für die Hinweise!

von M.K. B. (mkbit)


Lesenswert?

Ich gehe mal davon aus, dass du als Anfänger etwas auf dem Schlauch 
stehst.
Hier mal die Hausaufgabe fürs Wochenende:
1
PORTA &= (0<<PA0)

Überleg mal was die Einzelschritte im folgenden ergeben. Ob die 
Datentypen stimmen, kann ich nicht sagen, aber es geht ums Prinzip:
1
uint x = (0<<PA0);
2
PORTA = PORTA & x;

Ich denke es hilft dir viel, wenn du deinen Denkfehler selber erkennst.
Mir hat zum Einstieg das gcc Tutorial hier gut geholfen (Verändern von 
Registerinhalten).
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ver.C3.A4ndern_von_Registerinhalten

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bitmanipulation ist hier Pflichtlektüre.

von Joachim B. (jar)


Lesenswert?

HH schrieb:
> Irgendwie bewirkt der Befehl:
> PORTA &= (0<<PA0);
> dass der gesamte PORTA mit Null überschrieben wird und nicht nur PA.0!

schreibe dir es doch einfach auf:

PA0 ist Bit 0

also setzt du die 8 Portsbits auf 0000 0000
Es ist Bit 0 auf 0 gesetzt richtig aber auch Bit 1 bis 7

und nun undierst du alle Bits auf Port A mit 0
was soll da rauskommen ausser 8x NULL?
Maske 0000 0000
PortA 1010 xxxx
---------------
gibt 0000 0000

weswegen wird es wohl richtig mit
PORTA &= ~(1<<PA0)
Maske 0000 0001
negiert 1111 1110
PortA 1010 xxxx
---------------
gibt 1010 xxx0

gemacht?

alle bleiben wie sie sind ausser BIT 0 das wird auf 0 gesetzt gelöscht

von Curby23523 N. (Gast)


Lesenswert?

HH schrieb:
> LED an Port A.0 blinkt ordnungsgemäß wie erwartet nur die LED A.1 blinkt
> gleichzeitig mit. Sie dürfte eigentlich mit der LED an A.0 an gehen und
> dann nicht mehr ausgehen.

MaWin schrieb:
> Schon HH schrieb, dass es nicht funktioniert. Das gibt dir nicht zu
> Denken ?

Ja, wieder zu schnell gelesen, er möchte, dass der PORT nicht angeht. 
Dann bitte in C-Lektüre nachschauen, wie man Bits manipuliert.

von c-hater (Gast)


Lesenswert?

HH schrieb:

> Trinke erst mal einen Kräuter!

Entweder Programmieren oder Saufen. Beides gleichzeitig funktioniert 
eher nicht, da wirst du nur das Saufziel erreichen...

Geringe Mengen Alkohol können allerdings wirklich auch die Kreativität 
beim Programmieren erhöhen, so meine Beobachtung. Sie lösen etwas die 
Verhaftung in eingefahrene Bahnen.

> Warum wird
> überhaupt ein Schiebebefehl verwendet um Ports zu schalten? Bei BASCOM
> ist es doch so einfach.

Zum Beispiel solche Veklemmungen... Nein, hier wird kein Schiebebefehl 
verwendet. Geschoben wird hier nur zur Compile-Zeit, letztlich ergeben 
die Ausdrücke zur Laufzeit eine konstante Zahl.

Du solltest dich mit dem grundsätzlichen Unterschied zwischen 
Kompilezeit und Laufzeit auseinandersetzen. Wenn du den begriffen hast, 
wird das klarer.

von HH (Gast)


Lesenswert?

Oh c-hater. Auch schon getrunken?

Mir ist jetzt schon klar, wie es funktioniert. Werde aber wohl nicht 
erfahren, warum Mann einen schlüssigen Befehl, um ein Bit zusetzen (also 
mit Oder maskiert - mit oder ohne senkrechten Strich) nicht eine 
ähnliche Syntax verwendet, um ein Bit zu löschen. In Bascom und in 
Pascal für PICs geht es doch. Aber hier wird erst das Einer-Komplement 
mit der Tilde gebildet.
Oder seht euch mal CodeVision an.
Aber die Variante von A (Gast) ganz oben gefällt mir ganz gut.

Danke und schönen Sonntag noch.

von Karl M. (Gast)


Lesenswert?

Hallo,

kennst Du schon die Funktionalität von sbit.h (peda - Peter Dannegger)?

Hier die Includedatei:
https://www.mikrocontroller.net/attachment/58294/SBIT.H

Beispiel:
1
#include "sbit.h"
2
#define LED0 SBIT(PORTA,PA0)
3
4
// schreibt man einfach:
5
LED = 0;
6
LED = 1;

von HH (Gast)


Lesenswert?

Ja. Der Typ ist gut und sachlich.
In den anderen Sprachen verwende ich auch ganz gern alias-Namen.

Sitze Im Biergarten und der Akku .....

Danke.

von Einer K. (Gast)


Lesenswert?

HH schrieb:
> Mir ist jetzt schon klar, wie es funktioniert. Werde aber wohl nicht
> erfahren, warum Mann einen schlüssigen Befehl, um ein Bit zusetzen (also
> mit Oder maskiert - mit oder ohne senkrechten Strich) nicht eine
> ähnliche Syntax verwendet, um ein Bit zu löschen. In Bascom und in
> Pascal für PICs geht es doch. Aber hier wird erst das Einer-Komplement
> mit der Tilde gebildet.
> Oder seht euch mal CodeVision an.


Ich bin mir nicht sicher, ob du mit dieser Einstellung in der C und C++ 
Welt gut aufgehoben bist.

Denn da wird nicht alles mundgerecht vorgekaut, wie es deiner Meinung 
nach sein sollte. Hier muss man die die Dinge selber machen.

HH schrieb:
> Aber die Variante von A (Gast) ganz oben gefällt mir ganz gut.
Passt ins Bild.

von NaJa (Gast)


Lesenswert?

Es ist fast wie immer. Einige sachliche Antworten und viele am Kern 
vobei.
Anfängern oder besser hier > Umsteigern < wird unterstellt, dass sie es 
besser lassen sollten.

Ja, Arduino F, vielleicht bist Du in diesem Forum falsch mit Deiner 
Einstellung. Deine Beiträge an anderer Stelle "passen ins Bild"!

Also weiter so .....

von Sven K. (quotschmacher)


Lesenswert?

Arduino F. schrieb:
>
1
> int main(void)
2
> {
3
>    DDRA  |= (1<<PA1)|(1<<PA0);
4
>    PORTA |= (1<<PA1)|(1<<PA0);
5
> 
6
>    while(1)
7
>    {
8
>     PINA = (1<<PA0);
9
>     _delay_ms(500);
10
>    }
11
> }
12
>

was spricht denn dagegen? das steht sogar im datenblatt der controller, 
bei denen es möglich ist, das man so den pin toggled.

von Rolf M. (rmagnus)


Lesenswert?

HH schrieb:
> Oh c-hater. Auch schon getrunken?
>
> Mir ist jetzt schon klar, wie es funktioniert.

Das glaube ich nicht.

> Werde aber wohl nicht erfahren, warum Mann einen schlüssigen Befehl, um
> ein Bit zusetzen (also mit Oder maskiert - mit oder ohne senkrechten
> Strich) nicht eine ähnliche Syntax verwendet, um ein Bit zu löschen.

Weil das nicht primär die "Befehle" sind, um ein Bit zu setzen oder zu 
löschen. Sie werden nur unter anderem auch dafür verwendet.

von M. K. (sylaina)


Lesenswert?

Sven A. schrieb:
> was spricht denn dagegen? das steht sogar im datenblatt der controller,
> bei denen es möglich ist, das man so den pin toggled.

Dass du das "^" vergessen hast vor dem "=" ;)

von Rolf M. (rmagnus)


Lesenswert?

M. K. schrieb:
> Dass du das "^" vergessen hast vor dem "=" ;)

Nein, hat er nicht. Bei halbwegs aktuellen AVRs kann man ein Bit in 
einem PORT-Register toggeln, indem man eine 1 in das entsprechende Bit 
des dazugehörigen PIN-Registers schreibt.

Sven A. schrieb:
> was spricht denn dagegen?

Mir würde nur einfallen, dass es bei Portierung auf einen älteren AVR zu 
fiesen, schwer zu findenden Fehlern kommen könnte.

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

M. K. schrieb:
> Dass du das "^" vergessen hast vor dem "=" ;)

Sorry, die Anweisung an PINx! ist schon ok, man findet diese Eigenschaft 
zum Toggeln eines Bits bei "neueren" Amtel µC nur versteckt im 
Datenblatt.
1
PINx = (1<<Pn0);

von Wilhelm M. (wimalopaan)


Lesenswert?

Arduino F. schrieb:
> HH schrieb:
>> Mir ist jetzt schon klar, wie es funktioniert. Werde aber wohl nicht
>> erfahren, warum Mann einen schlüssigen Befehl, um ein Bit zusetzen (also
>> mit Oder maskiert - mit oder ohne senkrechten Strich) nicht eine
>> ähnliche Syntax verwendet, um ein Bit zu löschen. In Bascom und in
>> Pascal für PICs geht es doch. Aber hier wird erst das Einer-Komplement
>> mit der Tilde gebildet.
>> Oder seht euch mal CodeVision an.
>
>
> Ich bin mir nicht sicher, ob du mit dieser Einstellung in der C und C++
> Welt gut aufgehoben bist.

Die eigentliche Frage ist doch (und die finde ich berechtigt):

Warum benötige ich zur Manipulation einzelner Bits einen Datentyp 
uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?

Was er möchte ist ein Datentyp, der einfach nur eine Ansammlung von Bits 
darstellt, und der dann Operationen zum Setzen / Löschen einzelner Bits 
anbietet.

Und da ist er doch in der C++-Welt sehr gut aufgehoben ;-) Damit könnte 
man auch die Problematik des RMW lösen ...

von Anderer Frank (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?
> Was er möchte ist ein Datentyp, der einfach nur eine Ansammlung von Bits
> darstellt, und der dann Operationen zum Setzen / Löschen einzelner Bits
> anbietet.
> Und da ist er doch in der C++-Welt sehr gut aufgehoben ;-) Damit könnte
> man auch die Problematik des RMW lösen ...

Dir steht es natürlich frei eine Bitstruct darüber zu legen. Der 
Compiler muss trotzdem einen Zugriff auf das Register machen, das bei 
diesem Controller funktioniert. Das wird hier eben 8 Bit sein.
Wobei es bei manchen uC auch Bereiche gibt die Bit adressiert sind.

von Karl M. (Gast)


Lesenswert?

Hallo Wilhelm M. schrieb:
> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?

Die Frage ist doch schnell beantwortet, da ein Port eines AVR µC 8 Bit 
Breit ist.
Das "soll" ist doch eher ein "ist".
Und wenn in "C" programmiert wird, dann kann man sich seine eigenen 
Zugriffe auf Pins basierend auf einem Port programmieren, so dass einem 
die Syntax zusagt.

Hier geht es wirklich nur um das Aussehen, um mehr nicht.
Also warum der ganze Stress?

von Wilhelm M. (wimalopaan)


Lesenswert?

Anderer Frank schrieb:
> Wilhelm M. schrieb:
>> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
>> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?
>> Was er möchte ist ein Datentyp, der einfach nur eine Ansammlung von Bits
>> darstellt, und der dann Operationen zum Setzen / Löschen einzelner Bits
>> anbietet.
>> Und da ist er doch in der C++-Welt sehr gut aufgehoben ;-) Damit könnte
>> man auch die Problematik des RMW lösen ...
>
> Dir steht es natürlich frei eine Bitstruct darüber zu legen.

Ja, das mache ich auch schon sehr lange so ... und mittlerweile ist so 
etwas in rudimentärer Form (eine Ansammlung von Bits) auch in der 
libstdc++ enthalten ;-)

von Markus F. (mfro)


Lesenswert?

C hat Bitfelder.

Ja, die sind implementation defined.

Na und?

von Wilhelm M. (wimalopaan)


Lesenswert?

Karl M. schrieb:
> Hallo Wilhelm M. schrieb:
>> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
>> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?
>
> Die Frage ist doch schnell beantwortet, da ein Port eines AVR µC 8 Bit
> Breit ist.

8-Bit als ein Byte zusammengefasst: ja.

Aber diese 8-Bit immer als Ganzzahl interpretieren: klares nein.

> Hier geht es wirklich nur um das Aussehen, um mehr nicht.

Nein. Es geht darum, den Code ausdrücken zu lassen, was er bedeutet. Und 
da ist es eben unsinnig, 8-Bits eines Ports zu einer Ganzzahl zusammen 
zu fassen. Es sind einfach nur 8 (zusammenhanglose) Bits.

> Also warum der ganze Stress?

Welcher Stress?

von Wilhelm M. (wimalopaan)


Lesenswert?

Markus F. schrieb:
> C hat Bitfelder.
>
> Ja, die sind implementation defined.

Ja!
Ich spreche aber gar nicht von Bitfeldern.

von Markus F. (mfro)


Lesenswert?

Wilhelm M. schrieb:
> Ich spreche aber gar nicht von Bitfeldern.

aber ich tu' das ;).

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Karl M. schrieb:
>> Hallo Wilhelm M. schrieb:
>>> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
>>> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?
>>
>> Die Frage ist doch schnell beantwortet, da ein Port eines AVR µC 8 Bit
>> Breit ist.
>
> 8-Bit als ein Byte zusammengefasst: ja.
>
> Aber diese 8-Bit immer als Ganzzahl interpretieren: klares nein.

Tut man ja auch weder bei dem &, noch bei dem <<. Man shiftet ja Bits 
und nicht eine Ganzzahl. Man interpretiert sie in dem Fall lediglich als 
einen zusammengehörigen Block aus 8 Bits, aber nicht als Ganzzahl.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Wilhelm M. schrieb:
>> Karl M. schrieb:
>>> Hallo Wilhelm M. schrieb:
>>>> Warum benötige ich zur Manipulation einzelner Bits einen Datentyp
>>>> uint8_t, der ja vorzeichenlose Ganzzahlen repräsentieren soll?
>>>
>>> Die Frage ist doch schnell beantwortet, da ein Port eines AVR µC 8 Bit
>>> Breit ist.
>>
>> 8-Bit als ein Byte zusammengefasst: ja.
>>
>> Aber diese 8-Bit immer als Ganzzahl interpretieren: klares nein.
>
> Tut man ja auch weder bei dem &, noch bei dem <<. Man shiftet ja Bits
> und nicht eine Ganzzahl. Man interpretiert sie in dem Fall lediglich als
> einen zusammengehörigen Block aus 8 Bits, aber nicht als Ganzzahl.

Dann lies mal genauer:

http://en.cppreference.com/w/c/language/operator_arithmetic

von M. K. (sylaina)


Lesenswert?

Rolf M. schrieb:
> M. K. schrieb:
>> Dass du das "^" vergessen hast vor dem "=" ;)
>
> Nein, hat er nicht. Bei halbwegs aktuellen AVRs kann man ein Bit in
> einem PORT-Register toggeln, indem man eine 1 in das entsprechende Bit
> des dazugehörigen PIN-Registers schreibt.

Achja, stimmt ja. Da war ja noch was mit PINx...wo ist mein Kaffee?

Beitrag #5443421 wurde von einem Moderator gelöscht.
von Einer K. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Ja, das mache ich auch schon sehr lange so ...
Zeigen!
(bitte)

von Wilhelm M. (wimalopaan)


Lesenswert?

Arduino F. schrieb:
> Wilhelm M. schrieb:
>> Ja, das mache ich auch schon sehr lange so ...
> Zeigen!
> (bitte)

Grundsätzlich: primitive Datentypen sind die kleinsten "Bausteine". 
Allerdings, sind sie in vielen Einsatzbereichen sowohl im Wertebereich 
wie auch in der Operationenmenge unpassend. Zudem tragen sie keinerlei 
Semantik. Das ist der Tatsache geschuldet, das wir es mit einer 
general-purpose Sprache zu tun haben (irgendetwas muss die Sprache ja 
bereitstellen). Für seine eigene, projektspezifische Problemdomäne 
sollte man sich eigene Datentypen maßgeschneidert erstellen.

Nun, es geht darum, einen Typ zu erstellen, der ein Byte, d.h. eine 
geordnete Sammlung von 8-Bits darstellt. Da diese 8-Bits zunächst keine 
Semantik haben, macht es keinen Sinn

i) implizite Typkonversionen von/zu arithmetischen DT zu erlauben
ii) arithmetische Rechenoperationen

zuzulassen. Als erlaubte Operationen kommt zunächst mal nur die 
Kopierzuweisung und die Kopierkonstruktion in Betracht.

Also
1
auto x = Byte{42};
2
auto y = x;
3
y = x;
soll möglich sein, aber
1
auto z1 = 2 * x;
2
auto z2 = x + y;
soll nicht möglich sein.

Die erste Möglichkeit, wäre ein Typ
1
struct Byte {
2
       uint8_t value;
3
};
zu schreiben. Eine andere Möglichkeit ist:
1
enum class byte : uint8_t {};

Ich habe die zweite Variante genommen, denn es gab mal einen 
gcc-Optimizer isra-Bug, der mit der ersten manchmal Schwierigkeiten 
hatte. Die scoped-enum Variante benutzt auch libstdc++.

Jetzt kann man anfangen, seine gewünschten Operation hinzuzufügen, etwa:
1
template<typename IType>
2
constexpr byte operator<<(byte b, IType shift) noexcept {
3
   return byte(static_cast<uint8_t>(b) << shift);
4
}
oder
1
constexpr bool any(std::byte b) noexecpt {
2
     return b != std::byte{0};
3
}
und andere.
Wobei man die Operatoren dann besser als SFINAE-enabled templates 
schreibt, falls man auch noch andere Bit-Typen hat, wie etwa Nibble, 
o.ä.


*Achtung*: an dieser Stelle kommt regelmäßig der Einwand:
Was, sooo viel Aufwand. Das mache ich doch mit C und int einfacher.

Dazu ist natürlich zu bedenken:

a) den Aufwand macht man sich für seine N-Projekte genau einmal.
b) für den Klienten ist es eben nicht aufwändiger
c) ich gewinne Sicherheit im Sinne von "ease to use, hard to misuse"
d) der Code wird expressiver

Das war es in Kürze und nur ganz grob.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Sven A. schrieb:
> was spricht denn dagegen? das steht sogar im datenblatt der controller,
> bei denen es möglich ist, das man so den pin toggled.

Dagegen spricht, daß jeder erstmal grübelt, wenn er nicht das Datenblatt 
im Kopf hat. Ich benutze es daher absichtlich nicht. In der Regel ist 
der Einspareffekt unerheblich.

von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Sven A. schrieb:
>> was spricht denn dagegen? das steht sogar im datenblatt der controller,
>> bei denen es möglich ist, das man so den pin toggled.
>
> Dagegen spricht, daß jeder erstmal grübelt, wenn er nicht das Datenblatt
> im Kopf hat. Ich benutze es daher absichtlich nicht. In der Regel ist
> der Einspareffekt unerheblich.

Schaltest Du dann bei einem unechtem RMW auch die Interrupts aus und 
legst die anderen Kerne still?

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
>> Tut man ja auch weder bei dem &, noch bei dem <<. Man shiftet ja Bits
>> und nicht eine Ganzzahl. Man interpretiert sie in dem Fall lediglich als
>> einen zusammengehörigen Block aus 8 Bits, aber nicht als Ganzzahl.
>
> Dann lies mal genauer:
>
> http://en.cppreference.com/w/c/language/operator_arithmetic

Und dann?

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.