Forum: Mikrocontroller und Digitale Elektronik fehler im lehrheft


von schüler (Gast)


Lesenswert?

Hallo Zusammen,


ich lerne gerade für meine Microkontroller-Prüfung und bin in meinem 
Lehrheft über etwas seltsames gestoßen. Meiner Meinung nach ist es 
Unsinn aber vielleicht täusch ich mich da.

Beim Setzen von Bits in Registern kommt es immer wieder vor, dass das 
Bit nicht um 1 geschoben wird sondern um 2, 3, ...

Zum Beispiel: Initialisierung eines ADC

ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);

Prescaler soll anscheinend mit "(6<<ADPS0)" auf 64 gestellt werden.
Ergibt das für euch irgendeinen Sinn???

Wäre es ein Einzelfall würd ich sagen Tippfehler, aber das kommt sehr 
oft vor in meinen Unterlagen.

: Gesperrt durch User
von Roland E. (roland0815)


Lesenswert?

Ja, der Code ergibt so Sinn. Im Zweifel mal in die Definitionen schauen, 
um wie viel geschoben wird. Dann siehst du auch, ob du richtig geraten 
hast.

von Wolfgang (Gast)


Lesenswert?

schüler schrieb:
> Beim Setzen von Bits in Registern kommt es immer wieder vor, dass das
> Bit nicht um 1 geschoben wird sondern um 2, 3, ...

Und was stört dich daran. So macht man das.

von Theor (Gast)


Lesenswert?

Genau das Thema hatten wir gestern schonmal.

Beitrag "USART ATmega2561"

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

schüler schrieb:
> Prescaler soll anscheinend mit "(6<<ADPS0)" auf 64 gestellt werden.

Das ist nicht möglich. Das Bitmuster von 64 enthält genau ein gesetztes 
Bit (0b01000000), das von 6 aber enthält zwei gesetzte Bits 
(0b00000110). Mit einer einzelnen Schiebeoperation können diese beiden 
Bitmuster nicht ineinander umgewandelt werden.

von Falk B. (falk)


Lesenswert?

@schüler (Gast)

>ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);

>Prescaler soll anscheinend mit "(6<<ADPS0)" auf 64 gestellt werden.
>Ergibt das für euch irgendeinen Sinn???

Sicher. Schau mal, an welcher Bitposition der Prescaler im Register 
ADCSRA liegt.

>Wäre es ein Einzelfall würd ich sagen Tippfehler, aber das kommt sehr
>oft vor in meinen Unterlagen.

Dann wird es wohl stimmen. Siehe Bitmanipulation.

von S. Landolt (Gast)


Lesenswert?

Ich persönlich ziehe
 ...  (1<<ADPS2)|(1<<ADPS1)
vor, evtl. noch als
 ...  (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
kann aber andererseits verstehen, dass sich der Autor diese 
Schreibarbeit ersparen will.

von S. Landolt (Gast)


Lesenswert?

Ohje, sollte natürlich
 ...  (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
heißen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

S. Landolt schrieb:
> Ohje, sollte natürlich
>  ...  (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
> heißen.

Für ein Lehrheft würde ich immer diese Variante vorziehen. Die Sache mit 
(6<<ADPS0) ist nur unnötig verwirrend, zumal ADPS0 zufällig selber auch 
noch 0 ist.
Damit könnte man noch kryptischer einfach
1
... | 6;
schreiben :-P

von sonmist (Gast)


Lesenswert?

S. Landolt schrieb:
> Ich persönlich ziehe
>  ...  (1<<ADPS2)|(1<<ADPS1)
> vor, evtl. noch als
>  ...  (1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
(habe Euren Folgepost mal eingearbeitet)

Warum? Damit ADPS0 evtl. auf 0 ist?

von S. Landolt (Gast)


Lesenswert?

> Warum? Damit ADPS0 evtl. auf 0 ist?
Nein, eher weil es besser dem Bild im Datenblatt entspricht, und ein 
wenig, weil man beim Austesten die Werte schneller ändern kann.

von schüler (Gast)


Lesenswert?

Ok danke, also doch kein Tippfehler. Aber defenitiv verwirrend wenn man 
es so vorher nie gesehen hat und in den unterlagen auch nicht erklärt 
wird. Aber danke euch.

von Wilhelm M. (wimalopaan)


Lesenswert?

schüler schrieb:

> Zum Beispiel: Initialisierung eines ADC
>
> ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);

In meine Augen ist das falsch, bestenfalls verwirrend!

Warum macht man das mit den cpp-Macros?

1) Lesbarkeit
2) Um unabhängig von der tatsächlichen Position der Bits zu sein

Bei (6<<ADPS0) muss man wissen, dass die Bits ADSP1 und ADPS2 links von 
ADPS0 liegen. Genau dieses Wissen bzw. Nachschauen-Müssen will man ja 
vermeiden.

Ausserdem könnten die Bits bei einem anderen uC (derselben Familie) an 
anderer Stelle liegen.

Dann würde der Code zwar compilieren, wäre aber falsch.

Für mich ist das ein DONT.

von Paul B. (paul_baumann)


Lesenswert?

Ich bin so froh, daß es z.B. in BASCOM den Befehl BITS gibt. Da trage 
ich nacheinander einfach alle Bits ein, die gesetzt werden sollen -ohne 
Schieberei, ohne Maskierung -einfach einfach.

Warum quält man Leute so, wie es oben geschieht?

SCNR
Paul

von Falk B. (falk)


Lesenswert?

@Wilhelm M. (wimalopaan)

>> Zum Beispiel: Initialisierung eines ADC
>>
>> ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);

>In meine Augen ist das falsch, bestenfalls verwirrend!

Dann mach sie mal auf, die Augen.

>Warum macht man das mit den cpp-Macros?

Das ist werder (cooles) CPP noch Macros, es sind prophane symbolische 
konstanten, aka #define (s).

>1) Lesbarkeit
>2) Um unabhängig von der tatsächlichen Position der Bits zu sein

>Bei (6<<ADPS0) muss man wissen, dass die Bits ADSP1 und ADPS2 links von
>ADPS0 liegen. Genau dieses Wissen bzw. Nachschauen-Müssen will man ja
>vermeiden.

Das ist trivial, denn die Nummer gibt die Bitwertigkeit der einzelnen 
Bit für diese Bitgruppe an.

>Ausserdem könnten die Bits bei einem anderen uC (derselben Familie) an
>anderer Stelle liegen.

Nö, dann hätten die Jungs bei Atmel maximal gepfuscht.

von Falk B. (falk)


Lesenswert?

@ Paul Baumann (paul_baumann)

>Ich bin so froh, daß es z.B. in BASCOM den Befehl BITS gibt. Da trage
>ich nacheinander einfach alle Bits ein, die gesetzt werden sollen -ohne
>Schieberei, ohne Maskierung -einfach einfach.

Das kann C auch, wenn man die Headerfiles passend aufbaut.

>Warum quält man Leute so, wie es oben geschieht?

Naja, eine historische (Fehl)entscheidung, die man bis heute beim avr 
gcc nicht korrigiert hat. Siehe

Beitrag "Re: XC8 compiler - Register schreiben wie bei Atmel"

von Michael U. (amiga)


Lesenswert?

Hallo,

@Paul Baumann: Beispiel?
Ernsthaftee Frage, finde nichtmal den Befehl BITS dort auf die Schnelle.

Gruß aus Berlin
Michael

von Wilhelm M. (wimalopaan)


Lesenswert?

Falk B. schrieb:
> @Wilhelm M. (wimalopaan)
>
>>> Zum Beispiel: Initialisierung eines ADC
>>>
>>> ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);
>
>>In meine Augen ist das falsch, bestenfalls verwirrend!
>
> Dann mach sie mal auf, die Augen.
>
>>Warum macht man das mit den cpp-Macros?
>
> Das ist werder (cooles) CPP noch Macros, es sind prophane symbolische
> konstanten, aka #define (s).


Natürlich ist das ist ein Macro: an object-like macro:

Schau hier:
https://gcc.gnu.org/onlinedocs/cpp/Macros.html

von Wilhelm M. (wimalopaan)


Lesenswert?

Falk B. schrieb:

> Nö, dann hätten die Jungs bei Atmel maximal gepfuscht.

Auch hier nein: genau deswegen hat man ja diese Cpp-Macros eingeführt, 
damit man von der tatsächlich BitNummer unabhängig ist. Und wie schon 
sagte: auch wegen der Lesbarkeit. Die Lesbarkeit ist aber wieder weg, 
von ich (6 << ADPS0) schreibe statt ((1 << ADPS2) | (1 << ADPS1)).

von Paul B. (paul_baumann)


Angehängte Dateien:

Lesenswert?

O.T.

Michael U. schrieb:
> Hallo,
>
> @Paul Baumann: Beispiel?
> Ernsthaftee Frage, finde nichtmal den Befehl BITS dort auf die Schnelle.

In der Bascom Hilfe ist auch der Befehl BITS zu finden. (Siehe Anhang)
Genau so gut kann man dort die Namen der Bits in dem jeweiligen 
Steuerregister eingeben Bits (ADCSRA.ADEN, ADCSRA.ADFR) Das würde z.B. 
bei einem Mega8 die Bits7 und 5 im Regsiter ADCSRA setzen und allen 
Anderen in Ruhe lassen.

MfG Paul
------------------------------------------------------------------------ 
--
Bitte Beitrag mal nicht sofort wieder löschen, damit ihn Michael 
wenigstens
kurz überfleigen kann.

Danke.

: Bearbeitet durch User
von posti (Gast)


Lesenswert?

Falk B. schrieb:
> @Wilhelm M. (wimalopaan)
> ....
>>Bei (6<<ADPS0) muss man wissen, dass die Bits ADSP1 und ADPS2 links von
>>ADPS0 liegen. Genau dieses Wissen bzw. Nachschauen-Müssen will man ja
>>vermeiden.
>
> Das ist trivial, denn die Nummer gibt die Bitwertigkeit der einzelnen
> Bit für diese Bitgruppe an.
>
>>Ausserdem könnten die Bits bei einem anderen uC (derselben Familie) an
>>anderer Stelle liegen.
>
> Nö, dann hätten die Jungs bei Atmel maximal gepfuscht.

Hi

Beispiel?
ATtiny45
Register WDTCR (0x21)
Enthaltene Bits
WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0

Watchdog Prescaler WDP3 WDP2 WDP1 WDP0

Bei diese Bits hat Atmel wohl - wie meinten zu sagen? 'Gepfuscht' ?

Zumindest gehört zu der Bitschieberei mit der 6 eine Erklärung, was 
diese 6 darin zu suchen hat und warum man Das so macht.

Und eben, daß man vorher sicher stellen muß, daß die Bits auch in der 
gewünschten Reihenfolge in das Byte geschrieben gehören.
Klar kann man in diesem Beispiel das Bit WDP3 auch durch 32 in die 
Rechnung einbeziehen, aber da ich bei 'WDP0' (=0) ebenfalls nicht 
verschiebe, wäre das reine Eintragen des Byte in das Register 
sinnvoller, als die zusammengeschusterte Summe der Einzelbits um 0 Bits 
zu verschieben.

Anderes Beispiel:
TCCR0A, als unterste Bits WGM01 WGM00
und als Schmankerl dazu im
TCCR0B, als 4.tes Bit WGM02

Wenn's ein Atmel-Chip gibt, Der die Bits WGM00-02 in einem Byte vereint, 
wäre der Code hierzu nicht kompatibel.

Also: Verstehen, was gemeint ist und beim Einsetzen entscheiden, ob's 
Sinn macht oder man sich damit nicht das nächste Wochenende versaut :)

MfG

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
>> Prescaler soll anscheinend mit "(6<<ADPS0)" auf 64 gestellt werden.
>
> Das ist nicht möglich. Das Bitmuster von 64 enthält genau ein gesetztes
> Bit (0b01000000), das von 6 aber enthält zwei gesetzte Bits
> (0b00000110).

Rufus, das war ein Eigentor deinerseits. Ich will jetzt nicht auf die 
AVR's eingehen, aber Konstrukte wie

(zahl<<position)

sind recht üblich. Oft genug ist sowas die Position des auszuwählenden 
Teiler-FF, die da angegeben wird. Hier mit 2^6-->64, das scheint mir 
stimmig zu sein.

Ob allerdings sowas

ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);

wirklich guter Schreibstil ist, wage ich zu bezweifeln. Um das 
betreffende Register richtig aufzusetzen, muß man ohnehin ins Manual 
schauen und da kann man dann auch konkrete Bitnummern angeben. Man 
braucht zu sowas nicht zusätzliche Bezeichner zu kreieren - das macht 
alles nur unnötig aufgeblasen. Hier mal ein Gegenbeispiel:
1
 ADCBLABLA = (5<<0) |  // Kanal 5
2
             (1<<3) |  // ADC einschalten
3
             (1<<4) |  // Ergebnis rechtsbündig
4
             (1<<5) |  // Enable Interrupts
5
             (6<<9);   // Systemtakt:64
(alle Zahlen nur als Beispiel).

W.S.

von avr (Gast)


Lesenswert?

Paul B. schrieb:
> In der Bascom Hilfe ist auch der Befehl BITS zu finden.

Auch wenn man dich wohl nie überzeugen könnte. In diesem Fall ist das 
Verhalten der Bits-Funktion sogar in C abbildbar. Mit C++ hat man ein 
noch mächtigeres Werkzeug - hier reichen Makros mit variadischen 
Funktionen. Mit einem gescheiten Compiler wird das ganze während des 
Kompilierens berechnet.
1
#include <stdarg.h>
2
static int Bits2 (int value, ...)
3
{
4
  int ret = 0;
5
  va_list args;
6
7
  va_start (args, value);
8
    
9
  while(value != -1)
10
  {
11
    ret |= 1 << value;
12
    value = va_arg(args, int);
13
  }
14
15
  va_end (args);
16
  return ret;
17
}
18
19
#define Bits(...) Bits2(__VA_ARGS__, -1)

von Michael U. (amiga)


Lesenswert?

Hallo,

man kann natürlich (fast) alles abbilden, muß man es auch immer?

Um auf den Ursprung zurückzukommen:
ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);
würde bei mir immer
ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2);
geschrieben werden.

Im Datenblatt sehe ich die zu setzenden Bits und ihren Namen.
Warum sollte ich jetzt erst ADPS2,ADPS1,ADPS0 in den zugehörigen 
Dezimalwert umdenken und nach der Position von ADPS0 schauen, die ich 
garnicht brauche?

PS: Ob ich jetzt das so in C schreibe oder
Bits(ADEN,ADATE,ADIE,ADPS1,ADPS2)
in Bascom (Danke Paul) ist für mich kein wirklicher Unterschied,
Copy & Paste geht auch in C und den Binamen muß ich ohnehin suchen und 
schreiben.

Gruß aus Berlin
Michael

von Wolfgang (Gast)


Lesenswert?

Michael U. schrieb:
> Warum sollte ich jetzt erst ADPS2,ADPS1,ADPS0 in den zugehörigen
> Dezimalwert umdenken

Wer kommt schon bei Bitmustern auf einen Dezimalwert?

Hex oder Binär ist dem Problem deutlich angemessener und bei 
zusammenhängenden Bits ist es natürlich sinnvoll, sich für die 
Verschiebung des Bitmusters auf das unterste Bit zu beziehen.

Die wenigsten Register werden wohl die Bitreihenfolge spiegeln ;-)

von Falk B. (falk)


Lesenswert?

@Michael U. (amiga)

>ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(6<<ADPS0);
>würde bei mir immer
>ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2);
>geschrieben werden.

Naja, wie bereits gesagt, das ist ein historisch gewachsenes Relikt. 
Nicht optimal aber man kann damit arbeiten. Wenn es wirklich sicher und 
bequem sein soll, muss man die Register mit Bitfeldern definieren, etwa 
so, die Definition ist unvollständig, man muss sie noch als IO-Register 
definieren, da weiß ich aber nicht wie das geht.
1
union ADCSRA {
2
  unit8_t ADEN:1;
3
  unit8_t ADSC:1;
4
  unit8_t ADFR:1;
5
  unit8_t ADIF:1;
6
  unit8_t ADIE:1;
7
  unit8_t ADPS:3;
8
}
9
10
//
11
12
ADCSRA.ADEN = 1;
13
ADCSRA.ADPS = 6;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Wenn es wirklich sicher und bequem sein soll, muss man die Register mit
> Bitfeldern definieren,

Das ist nicht immer praktisch; es gibt Peripherie mit Registern, die in 
einem Rutsch beschrieben werden müssen, und die sich merkwürdig 
verhalten, wenn die Bits nacheinander hineintröpfeln.

Eine andere Konvention zur Notation von Bit-Werten (die nicht auf die 
Assemblereigenschaften von AVRs achtet) ist die, den Wert des Bits und 
nicht dessen Nummer als Konstante zu definieren.

Dann sähe das hier
1
ADCSRA=(1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2);

so aus:
1
ADCSRA = ADEN | ADATE | ADIE | ADPS1 | ADPS2;

So findet man das recht häufig außerhalb der AVR-Welt.

Solange nicht der C-Compiler auf spezielle Bitoperationen des 
Controllers zugreifen kann/muss, gibt es wenig Gründe, die für die 
Bitschiebenotation stehen (außer vielleicht der Handel mit 
Ersatztastenkappen für "<"-Tasten).

Und ich bezweifle sehr stark, daß bei obigen Codebeispiel der Compiler 
etwas anderes erzeugt als Code, der einen konstanten Wert in ein 
Register schreibt.

von W.S. (Gast)


Lesenswert?

Wolfgang schrieb:
> Wer kommt schon bei Bitmustern auf einen Dezimalwert?
>
> Hex oder Binär ist dem Problem deutlich angemessener..

Nö. Deine Aussage gilt nur zur Hälfte. Nicht immer, aber oftmals ist ein 
Dezimalwert wesentlich angemessener. Hier mal ein Beispiel (aus dem 
RM0365):

Bits 7:5 PLS[2:0]: PVD level selection.
These bits are written by software to select the voltage threshold 
detected by the Power Voltage Detector.
000: 2.2V
001: 2.3V
010: 2.4V
011: 2.5V
100: 2.6V
101: 2.7V
110: 2.8V
111: 2.9V

Wenn man sowas mit (zahl<<5) inschreibt, dann ist das wesentlich 
lesbarer und auch sicherer gegen Schreibfehler, als wenn man
(PLS2<<7)|(PLS1<<6)|(PLS0<<5)
hinschreiben wollte.

W.S.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Wenn man sowas mit (zahl<<5) inschreibt, dann ist das wesentlich
> lesbarer und auch sicherer gegen Schreibfehler

Und noch besser ist hier die Verwendung von sprechenden symbolischen 
Konstanten, also nicht

2

sondern

PVDLEVEL_2_4

(oder was hübscher geschriebenes)

Das mir unterstellte "Eigentor" (wir erinnern uns: 6 soll für 64 stehen) 
wäre mit vernünftigen Konstanten auch nicht geschehen. Weil auch in 
diesem Fall der eigentliche numerische Wert 6 völlig irrelevant und 
irreführend ist.

von Falk B. (falk)


Lesenswert?

@ Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite

>> Wenn es wirklich sicher und bequem sein soll, muss man die Register mit
>> Bitfeldern definieren,

>Das ist nicht immer praktisch; es gibt Peripherie mit Registern, die in
>einem Rutsch beschrieben werden müssen, und die sich merkwürdig
>verhalten, wenn die Bits nacheinander hineintröpfeln.

Ja die gibt es, vor allem beim C2000 ;-)
Aber das kann man das dadurch verhindern, indem man nur für DIESE eben 
keine Bits definiert bzw. parallel dazu in einer Union einen 32 Bit 
zugriff ermöglicht, so wie es TI macht. Die allermeisten Register 
vertragen Einzelbitzugriffe.

von Falk B. (falk)


Lesenswert?

@Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite

>Und noch besser ist hier die Verwendung von sprechenden symbolischen
>Konstanten, also nicht

>2

>sondern

>PVDLEVEL_2_4

>(oder was hübscher geschriebenes)

Wenn schon, dann

PVDLEVEL_2V4

;-)

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> (wir erinnern uns: 6 soll für 64 stehen)

Richtig! die 6 ist ein Code, dessen Bedeutung man nur aus dem Refman 
erfahren kann und die 64 ist das, was durch diesen Code bewirkt wird. 
Siehe "Feuerzangenbowle" mit Rühmann: Der Code "BALDRIAN" hat nur per 
vorheriger Vereinbarung mit dem darauf Folgenden zu tun und Prof. 
Schnauz kann es sich nicht durch Logik erklären. Das ist dr 
Knackpunkt.

Ich darf dich an deine eigenen Worte erinnern: "Das ist nicht möglich. 
Das Bitmuster von 64 enthält genau ein gesetztes Bit.., das von 6 aber 
enthält zwei gesetzte Bits... Mit einer einzelnen Schiebeoperation 
können diese beiden Bitmuster nicht ineinander umgewandelt werden."

Es ist eben DOCH möglich, aber eben nicht mit einer logischen Operation, 
sondern per Blick ins Manual.

Ganz genau so verhält es sich ja auch mit dem von mir geposteten Stück 
Refman. Durch logisches Nachdenken kann man unmöglich drauf kommen, 
daß eine 5 zu einer Schwelle von 2.7V führt. Sowas muß man nachlesen.

W.S.

von Holla (Gast)


Lesenswert?

W.S. schrieb:
> Mit einer einzelnen Schiebeoperation
> können diese beiden Bitmuster nicht ineinander umgewandelt werden."
>
> Es ist eben DOCH möglich

Wie? Zeig mal bitte!

von Falk B. (falk)


Lesenswert?

@ Holla (Gast)

>> Mit einer einzelnen Schiebeoperation
>> können diese beiden Bitmuster nicht ineinander umgewandelt werden."
>
>> Es ist eben DOCH möglich

>Wie? Zeig mal bitte!

Mit der Tabelle aus dem Datenblatt.

von Holla (Gast)


Lesenswert?

Falk B. schrieb:
> @ Holla (Gast)
>
>>> Mit einer einzelnen Schiebeoperation
>>> können diese beiden Bitmuster nicht ineinander umgewandelt werden."
>>
>>> Es ist eben DOCH möglich
>
>>Wie? Zeig mal bitte!
>
> Mit der Tabelle aus dem Datenblatt.

Zeig doch bitte, wie du mittels einer einzelnen Schiebeoperation aus 6 
(zwei Bits) eine 64 (ein Bit) machst!

von Volker S. (vloki)


Lesenswert?

Holla schrieb:
> Zeig doch bitte, wie du mittels einer einzelnen Schiebeoperation aus 6
> (zwei Bits) eine 64 (ein Bit) machst!

Ohne jetzt in das Datenblatt zu schauen würde ich vermuten, dass hier 
die bitfolge 110 (6) an einer bestimmten Stelle im Register irgendwas 
auf 64 stellt.... (64 ==2^6,  das hat man schon öfter so gesehen)

von Mugl (Gast)


Lesenswert?

Zeig doch bitte, wie du mittels einer einzelnen Schiebeoperation aus 6
(zwei Bits) eine 64 (ein Bit) machst!

6 = 110 b

geschoben wird um ? ADPS0

wie sieht das Bitfeld aus?
wenn die Bedeutung zB genau an der Grenze von 1 zu 1 sich ändert warum 
dann nicht?

zB:

110 < 5


....000000011000000
 x          | Y  | Z

Y = 64

von Holla (Gast)


Lesenswert?

Volker S. schrieb:
> an einer bestimmten Stelle im Register irgendwas
Könntest du das mal genauer ausführen, wie mit einer einzigen 
Schiebeoperation aus der 6 eine 64 wird?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Sowas muß man nachlesen.

Eben. Und damit man nicht jedesmal nachschlagen muss, verwendet man 
statt nichtssagender Zahlen sinnvoll definierte Symbole.

von Huh (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> W.S. schrieb:
>> Sowas muß man nachlesen.
>
> Eben. Und damit man nicht jedesmal nachschlagen muss, verwendet man
> statt nichtssagender Zahlen sinnvoll definierte Symbole.

Seh ich genauso.

von Volker S. (vloki)


Lesenswert?

Holla schrieb:
> Volker S. schrieb:
>> an einer bestimmten Stelle im Register irgendwas
> Könntest du das mal genauer ausführen, wie mit einer einzigen
> Schiebeoperation aus der 6 eine 64 wird?

Darum geht es bei den originalen Problem doch gar nicht. Das Schieben 
hat lediglich den Zweck die 110 an die richtige Stelle zu bringen, was 
dann zur Folge hat dass irgendein Parameter für was auch immer den Wert 
64 bekommt.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Eben. Und damit man nicht jedesmal nachschlagen muss, verwendet man
> statt nichtssagender Zahlen sinnvoll definierte Symbole.

Sowas kann man auf einem ganz kleinen µC machen. Aber schau dir mal an, 
was es für Unmassen an Einstellwerten auf einem mittelprächtigen 
32Bitter so gibt. Deine sinnvoll definierten Symbole helfen da nicht 
weiter, denn da kommt eine Legion zusammen, die man sich nimmer merken 
kann.

Selbst wenn du den Bezeichner unhandlich lang machst, um dort den 
Verwendungsort+Zweck mit unterzubringen, wird es nicht besser. Wie 
handlich ist denn ein

#define UART5_CR1_BITLENG_5_NO_PAR_1_5_STOP_Val  (...)
#define UART5_SR1_BITLENG_5_NO_PAR_1_5_STOP_Mask (...)

nach deiner Meinung? Eben deshalb ist das Kreieren von "sinnvoll 
definierten Symbolen" in 90% aller Fälle ganz einfach Murks. Siehe die 
unsägliche ST-Lib.

Abhilfe schafft nur das Schreiben von sinnvoll definierten 
Lowlevel-Handlern, weil dort das Blickfeld auf den betreffenden 
Peripherie-Core gerichtet ist und man eben deshalb auch ganz bequem mit 
direkten Zahlen arbeiten kann, also (1<<7) und so. Sinnvoll an solcher 
Stelle ist dann ein Kommentar. Den kann man nicht durch einen Bandwurm 
an zusätzlichen Symbolen ersetzen.

Aber das mit den Codes, die sich per Tabelle im Handbuch zu einem Sinn 
übersetzen, hast du ja jetzt erkannt - gelle?

W.S.

von Wilhelm M. (wimalopaan)


Lesenswert?

Ich glaube auch kaum, dass dem "Schüler" mit dieser Diskussion gedient 
ist (meine Meinung dazu steht oben ...).

von Falk B. (falk)


Lesenswert?

@ W.S. (Gast)

>Sowas kann man auf einem ganz kleinen µC machen. Aber schau dir mal an,
>was es für Unmassen an Einstellwerten auf einem mittelprächtigen
>32Bitter so gibt. Deine sinnvoll definierten Symbole helfen da nicht
>weiter, denn da kommt eine Legion zusammen, die man sich nimmer merken
>kann.

Dafür hat der liebe Gott Includefiles erfunden, in die man auch 
reinschauen darf ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Selbst wenn du den Bezeichner unhandlich lang machst, um dort den
> Verwendungsort+Zweck mit unterzubringen, wird es nicht besser. Wie
> handlich ist denn ein
> #define UART5_CR1_BITLENG_5_NO_PAR_1_5_STOP_Val  (...)
> #define UART5_SR1_BITLENG_5_NO_PAR_1_5_STOP_Mask (...)
>
> nach deiner Meinung?

Sinnlos. Aber so müssen solche Bezeichner auch nicht aussehen. In Deinem 
Beispiel werden sich die anderen UARTs identisch verhalten, also ist es 
komplett überflüssig, die Nummer der jeweiligen UART mit im symbolischen 
Namen unterzubringen.

Auch wenn ST grottiges Zeug abgeliefert hat, die Verwendung von 
irgendwelchen Zahlenwerten im Code ist noch viel schlechterer Stil. 
Ich würde solchen Code bei einem Review nicht akzeptieren.

> Aber das mit den Codes, die sich per Tabelle im Handbuch zu einem Sinn
> übersetzen, hast du ja jetzt erkannt - gelle?

Dieser Tonfall ist komplett überflüssig. Gelle?

von W.S. (Gast)


Lesenswert?

Paul B. schrieb im Beitrag #4864303:
> Und während man sich in Villa C noch über die richtige Syntax streitet,
> läuft in Villa Bascom das Programm schon seit Stunden.

Ja.

Aber das hat wie jede Medaille zwei Seiten.
In Villa C ist man nicht auf eine ganz spezielle Zielplattform 
festgenagelt, während man in Villa Bascom dies sehr wohl ist.

Ich vergleiche das mal mit den Tools von Mikroe, zum Beispiel deren 
Mikropascal. Wäre ja ne nette Sache, geht aber nicht, weil die Leute von 
Mikroe genau denselben Fehler gemacht haben. Deren Mikropascal ist 
nämlich nicht universell benutzbar, sondern NUR für einige sehr 
ausgewählte µC-Typen - eben weil ein Haufen Chip-Spezifisches in die 
Toolchain eingebaut worden ist. Sowas schränkt derart ein, daß man es 
nicht benutzen will.

W.S.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Dieser Tonfall ist komplett überflüssig. Gelle?

Einverstanden. Du hättest das alles vermeiden können, hättest du nicht 
zwischendurch noch einen draufgesetzt. Zur Erinnerung: "Das mir 
unterstellte "Eigentor" (wir erinnern uns: 6 soll für 64 stehen)".

Es war eines, und hättest du geschrieben "OK, jetzt hab ich's", wäre die 
Welt in Ordnung geblieben. Und die Bandwurm-Bezeichner in meinem 
Beispiel sind eben genau das: Beispiele. Guck mal in die ST-Lib, da 
findet sich solch eine Bandwurm-Bezeichner-Mentalität bis zum Erbrechen. 
Mag ja sein, daß es dir eher liegt, Zahlen mit endlosen #define's zuerst 
in derart längliche Namen umzuwandeln, damit in deinen C-Quellen die 
Zahlen nicht mehr vorkommen, aber das ist keine Verbesserung, sondern 
nur Obfuscation. Man darf dann eben etwas länger suchen, bis man den Bug 
gefunden hat.

W.S.

von Volker S. (vloki)


Lesenswert?

Paul B. schrieb im Beitrag #4864303:
> Und während man sich in Villa C noch über die richtige Syntax streitet,
> läuft in Villa Bascom das Programm schon seit Stunden.
> :))
> Großes Kino!
>
> MfG Paul

Unsinn, C kann das doch auch ;-)
Kleines Beispiel -> OSCCONbits.IRCF = IRCF_16MHZ;

Für OSCCON gibt es im Prozessorheader folgende Definitionen:
1
// Register: OSCCON
2
extern volatile unsigned char           OSCCON              @ 0xFD3;
3
#ifndef _LIB_BUILD
4
asm("OSCCON equ 0FD3h");
5
#endif
6
// bitfield definitions
7
typedef union {
8
    struct {
9
        unsigned SCS                    :2;
10
        unsigned HFIOFS                 :1;
11
        unsigned OSTS                   :1;
12
        unsigned IRCF                   :3;
13
        unsigned IDLEN                  :1;
14
    };
15
    struct {
16
        unsigned SCS0                   :1;
17
        unsigned SCS1                   :1;
18
        unsigned IOFS                   :1;
19
        unsigned                        :1;
20
        unsigned IRCF0                  :1;
21
        unsigned IRCF1                  :1;
22
        unsigned IRCF2                  :1;
23
    };
24
} OSCCONbits_t;
25
extern volatile OSCCONbits_t OSCCONbits @ 0xFD3;
26
// bitfield macros
27
#define _OSCCON_SCS_POSN                                    0x0
28
#define _OSCCON_SCS_POSITION                                0x0
29
#define _OSCCON_SCS_SIZE                                    0x2
30
#define _OSCCON_SCS_LENGTH                                  0x2
31
#define _OSCCON_SCS_MASK                                    0x3
32
...
33
#define _OSCCON_IRCF2_POSN                                  0x6
34
#define _OSCCON_IRCF2_POSITION                              0x6
35
#define _OSCCON_IRCF2_SIZE                                  0x1
36
#define _OSCCON_IRCF2_LENGTH                                0x1
37
#define _OSCCON_IRCF2_MASK                                  0x40
Dann noch irgendwo definiert:
1
//----------------------------------------------------------internal clock freq.
2
#if defined(__18F25K22) | defined(__18F24K22) | defined(__18F26K22)
3
    #define IRCF_16MHZ  0b111
4
    #define IRCF_8MHZ   0b110
5
    #define IRCF_4MHZ   0b101
6
    #define IRCF_2MHZ   0b100
7
    #define IRCF_1MHZ   0b011
8
    #define IRCF_500KHZ 0b010
9
    #define IRCF_250KHZ 0b001
10
    #define IRCF_31KHZ  0b000
11
#endif
So kann man natürlich auch immer noch mit dem Shiftgeraffel arbeiten.
Ich vermute aber, dass wenn man mal die Bitfelder benutzt hat, wird man 
das nicht mehr so mögen. Zumal ja auch noch in der IDE die 
entsprechenden Vorschläge kommen sobald man den "." setzt ;-)

von F. F. (foldi)


Lesenswert?

W.S. schrieb:
> ADCBLABLA

Zumindest ist das ein wirklich schönes Register. ?
Dein Beispiel ist sehr schön und jeder (man selbst auch und das nach 
Jahren) kann das schnell verstehen.
Ansonsten würde ich immer den Beispielen im Datenblatt folgen oder den 
allgemeinen Empfehlungen der AppNotes.

von F. F. (foldi)


Lesenswert?

Jedes Mal kommt gerade bei den Schreibweisen immer wieder die Frage nach 
der "richtigen" Sprache auf und auch die Kritiker sind nicht weit. 
Nehmen wir als Beispiel Arduino und schon ist Cyblord da und schnappt 
den "Knochen" auf.
Alles was die Benutzung eines Mikrocontrollers vereinfacht, sollte doch 
willkommen sein. Letztlich ist er nur Mittel für einen höheren Zweck, 
nämlich den, eine Idee in ein elektronisches Gerät zu verwandeln.
Ich behaupte hier einfach mal, dass jeder von uns zumindest ein Gerät 
benutzt, dessen Funktion im Inneren dem Benutzer unbekannt, ja sogar 
völlig egal ist.

Deswegen finde ich es so schade, dass fast jedes Mal ein Streit um die 
Sprachen ausbricht.

von Paul B. (paul_baumann)


Lesenswert?

F. F. schrieb:
> Deswegen finde ich es so schade, dass fast jedes Mal ein Streit um die
> Sprachen ausbricht.

Es ist ja in dem Sinne kein Streit, sondern ein sich mit konstanter 
Bosheit hinziehendes Rätselraten, eben WEIL es viele, viele 
unterschiedliche Möglichkeiten gibt etwas z.B. in Registern 
einzustellen. Das wiederum enthält jede Menge Fallstriscke und 
Fehlerquellen, wie man hier jeden Tag lesen kann, wenn ein Kontroller 
etwas Anderes tut, als man ihm (vermeintlich) "gesagt" hat.

MfG Paul

von Volker S. (vloki)


Lesenswert?

Flachwitz schrieb im Beitrag #4864462:
> Weißt du, wie egal den meisten hier deine Ansichten und noch viel mehr
> deine penetranten "Witze" sind?

Den meisten vieleicht meistens schon. Manchmal lässt sich dann aber doch 
der Ein oder Andere zu einem Kommentar hinreissen ;-)



Paul B. schrieb im Beitrag #4864468:
> @All
> Bedankt Euch für das Sprengen der Diskussion bei den Schuldigen.

Dann passiert so was leider automatisch. Kettenreaktion...
(...und die armen Admins können's wieder aufräumen ;-)

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Aufgrund des Unvermögens eines einzelnen wohlbekannten Forenmitgliedes, 
sich mit überflüssigen und unnötigen Kommentaren zurückzuhalten, mache 
ich das hier mal zu, und wische nicht den Dreck weg.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.