mikrocontroller.net

Forum: Compiler & IDEs C, Enums mit preprocessor


Autor: mgiaco82 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

/*!
 \brief Enum for the Slave Select Numbers
 */
typedef enum {
  APP_DAC_SS_NOT_SET = 0, /*!<Slave Select not set */
  APP_DAC_SS_0 = 1, /*!<Slave Select for the 1 DAC8555 Device*/
  APP_DAC_SS_1 = 2, /*!<Slave Select for the 2 DAC8555 Device*/
  APP_DAC_SS_2 = 3, /*!<Slave Select for the 3 DAC8555 Device*/
  APP_DAC_SS_3 = 4  /*!<Slave Select for the 4 DAC8555 Device*/
} ssc_slave_select_number_t;


//i think the fastest solution for slave select handling
#define dac_slave_select(device) \
  if(device==DAC_SS_0) PIN_DAC_CS0 = BIT_CLR \
  if(device==DAC_SS_1) PIN_DAC_CS1 = BIT_CLR \
  if(device==DAC_SS_2) PIN_DAC_CS2 = BIT_CLR \
  if(device==DAC_SS_3) PIN_DAC_CS3 = BIT_CLR \

#define dac_slave_unselect(device) \
  if(device==DAC_SS_0) PIN_DAC_CS0 = BIT_SET \
  if(device==DAC_SS_1) PIN_DAC_CS1 = BIT_SET \
  if(device==DAC_SS_2) PIN_DAC_CS2 = BIT_SET \
  if(device==DAC_SS_3) PIN_DAC_CS3 = BIT_SET \
  

Aufruf:

Es gibt ein dac object. das hat beispielsweise einen member vom typ 
ssc_slave_select_number_t
und so würde ich es gerne aufrufen. Compiler mekert was ist falsch oder 
geht das gar nicht so

dac_slave_select(dac->ss_device_one);

I wollte keine Funktion machen bezüglich Geschwindigkeit.

danke mgiaco

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco82 wrote:

> Es gibt ein dac object. das hat beispielsweise einen member vom typ
> ssc_slave_select_number_t
> und so würde ich es gerne aufrufen. Compiler mekert

Dann solltest du dir die Fehlermeldung des Compilers mal genauer 
ansehen.


> was ist falsch oder

Mach doch einfach mal die Textersetzung, die der Präprozessor auch 
macht.

aus
int main()
{
 dac_slave_select(dac->ss_device_one);
}

wird so:
int main()
{
  if(dac->ss_device_one==DAC_SS_0) PIN_DAC_CS0 = BIT_CLR
  if(dac->ss_device_one==DAC_SS_1) PIN_DAC_CS1 = BIT_CLR
  if(dac->ss_device_one==DAC_SS_2) PIN_DAC_CS2 = BIT_CLR
  if(dac->ss_device_one==DAC_SS_3) PIN_DAC_CS3 = BIT_CLR;
}

Wo sind denn die Strichpunkte?

> I wollte keine Funktion machen bezüglich Geschwindigkeit.

Das Argument zieht nicht. Wenn du gcc benutzt, kannst du ihn zwingen, 
die Funktion zu inlinen und dann hast du genau denselben speed, wie 
durch die Makroexpansion. Nur ist alles wesentlich sicherer.

Das hab ich schon gerne, beim Funktionsaufruf jede Nanosekunde 
rausschinden, dass der Code aber inhärent ineffizient ist, wird komplett 
übersehen. Das dac->ss_device_one wird ja wohl kaum gleichzeitig 
DAC_SS_0 und DAC_SS_1 und  DAC_SS_2 und DAC_SS_3 sein.

->
int main()
{
  if(dac->ss_device_one==DAC_SS_0)
    PIN_DAC_CS0 = BIT_CLR;
  else if(dac->ss_device_one==DAC_SS_1)
    PIN_DAC_CS1 = BIT_CLR;
  else if(dac->ss_device_one==DAC_SS_2)
    PIN_DAC_CS2 = BIT_CLR;
  else if(dac->ss_device_one==DAC_SS_3)
    PIN_DAC_CS3 = BIT_CLR;
}

und schon hast du im Durchschnitt durch den Wegfall der nicht 
notwendigen Vergleiche mehr Zeit eingespart, als dir eine nicht 
stattfindender Funktionsaufruf bringen würde. Noch besser wär 
allerdings:
int main()
{
  switch( dac->ss_device_one )
  {
    case DAC_SS_0;
      PIN_DAC_CS0 = BIT_CLR;
      break;

    case DAC_SS_1:
      PIN_DAC_CS1 = BIT_CLR;
      break;

    case DAC_SS_2:
      PIN_DAC_CS2 = BIT_CLR;
      break;

    case DAC_SS_3:
      PIN_DAC_CS3 = BIT_CLR;
  }
}

Da deine DAC_SS_x Werte schön aufsteigend sind, kann hier der Compiler 
mal so richtig zeigen was er kann und eine Sprungtabelle aufbauen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also DIE Fehlermeldung kenne ich noch nicht: "was ist falsch oder geht 
das gar nicht so"

Ansonsten: Wenn dac kein Zeiger ist, dann vielleicht . statt -> nehmen?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco82 wrote:
> C, Enums mit preprocessor
> [...]
> Es gibt ein dac object. das hat beispielsweise einen member vom typ
> ssc_slave_select_number_t
In C gibt es weder Objekte, noch Member. Bitte erzähl mal, was Du 
wirklich willst!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und dann könnte man auch mal untersuchen ob nicht.
volatile uint8_t* DacPin[] = { &PIN_DAC_CS0,
                               &PIN_DAC_CS1,
                               &PIN_DAC_CS2,
                               &PIN_DAC_CS3 }

int main()
{
  ...
  *DacPin[ dac->ss_device_one ] = BIT_CLR;
}

nicht alle anderen Varianten locker abhängt.

Fazit: Wieder mal auf Mikrooptimierung durch Makros geschaut und die 
algorithmischen Möglichkeiten völlig ausser acht gelassen. Dabei hätte 
man durch algorithmische Änderungen viel mehr rausholen können, als 
durch solche Mikrooptimierungen.

Nicht umsonst lautet die erste Regel der Optimierung: Don't do it
Die zweite lautet: Don't do it - yet.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karlheinz,

Danke alles klar. Das dynamisch und wegoptimieren passt nicht zusammen. 
Habe es gerade selber gesehen. Ich mach ne gute alte switch case Lösung.

Hallo Johannes,

Und da bist du dir wirklich sicher? Hast du mal drüber nachgedacht das 
man in C alles machen kann und wie ist C entstanden ober Objective C.

Ich habe nicht gesagt das es in C Objekte gibt, aber man kann in C 
Objektorientiert Programmieren. Und dann kann man die Dinger die dann 
Member haben als Objekte bezeichnen wenn man gerne möchte.

Hier mal ein Beitrag wie ich das so mache, das hab ich mir von Quantum 
Leaps abgeschaut. siehe mein Beitrag
Beitrag "Kapselung in C"

Also bitte mal ganz sachlich bleiben.

Vielen Dank noch mal
mgiaco

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger du bist ech super drauf das ist ja wild. Du weist 
ja glaube ich alles.

danke :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco wrote:

> Ich habe nicht gesagt das es in C Objekte gibt, aber man kann in C
> Objektorientiert Programmieren. Und dann kann man die Dinger die dann
> Member haben als Objekte bezeichnen wenn man gerne möchte.
>

Klar kann man das. Man kann auch in Assembler objektorientiert 
programmieren.

Entscheidend ist aber, welche Unterstützung dir die Sprache von sich aus 
dafür gibt und welchen Anteil an der Objektorientierung du nur duch 
konsequente Disziplin erreichen kannst.

Aber an dieser Stelle ist der Einwand, dass es in C keine Objekte und 
keine Member gibt wirklich nicht berechtigt.

Man kann mit Fug und Recht eine Instanz einer Struktur oder einer Union 
als ein Objekt ansehen. Und ein Element einer Struktur als Member. Ist 
im engl. Sprachgebrauch gang und gäbe, das so zu tun, auch wenn der 
Begriff Objekt im Zusammenhang mit objektorientierter Programmierung 
noch etwas weiter gefasst wird.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Aber an dieser Stelle ist der Einwand, dass es in C keine Objekte und
> keine Member gibt wirklich nicht berechtigt.
Wenn Du das sagst, dann gebe ich mich geschlagen...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco wrote:
> @Karl heinz Buchegger du bist ech super drauf das ist ja wild. Du weist
> ja glaube ich alles.

Nicht wirklich.
Meine Grenzen liegen bei C++ Templates. Da steig ich bei so manchen 
wilden Konstruktionen aus. Ist für mich aber nicht so wichtig als dass 
ich mir da Sorgen machen würde.

(Und die Neuerungen in C99 sind auch ein wenig an mir vorbei gegangen. 
Bin aber dabei, mein Gedächtnis auf diese Neuerungen umzukonditionieren. 
Ist halt nicht einfach, umzuschalten, wenn man ein bestimmtes Problem 20 
Jahre lang nach einem gut funktionierenden Muster gelöst hat und 
plötzlich eröffnet sich mit einer Sprachänderung eine elegantere 
Möglichkeit. Das muss erst mal ins Hirn hinein, sodass der schnelle 
Gedächtnis-Abruf das neue Muster benutzt und nicht weiterhin mit den 
alten Kamellen hochkommt.)

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm das wäre ja super aber, Problem:

hinter PIN_DAC_CS0 steht sbit usw. Keil Compiler.

Gibts da auch noch einen Trick ?

volatile uint8_t* DacPin[] = { &PIN_DAC_CS0,
                               &PIN_DAC_CS1,
                               &PIN_DAC_CS2,
                               &PIN_DAC_CS3 }

danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco wrote:
> Hm das wäre ja super aber, Problem:
>
> hinter PIN_DAC_CS0 steht sbit usw. Keil Compiler.

OK. Das wusste ich so nicht.
Zeig mal die Makros.

>
> Gibts da auch noch einen Trick ?

Wie sagte schon Monaco-Franze:
"A bissl wos geht imma!"

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define PIN_DAC_CS0 P3_P2 /*!<CS0 pin of external D/A converter*/

und P3_2 ist dann ==> sbit P3_P2 = P3^2;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und P3_2 ist dann ==> sbit P3_P2 = P3^2;

Der Schritt ist mir noch nicht klar. Vor allem wie da jetzt das sbit ins 
Spiel kommt.

Kannst du mal den #define für P3_P2 in seiner vollen Pracht zeigen?

Wie ist sbit definiert? Ist das selbst wieder ein Makro?


   PIN_DAC_CS0 = BIT_CLR;
würde dann ja zu

   P3^2 = BIT_CLR;

Das ist aber kein gültiges Standard-C (was nicht heisst, das Keil da was 
erfunden haben könnte).

(BIT_CLR ist das einfach eine 0?)

(Mein Ziel ist es zu verstehen, welcher C-Code letztendlich bei

   PIN_DAC_CS0 = BIT_CLR;

rauskommt, wenn alle Makros aufgelöst wurden. Dort identifizieren wir 
dann, welche Teile variabel sein müssen und arbeiten das dann wieder 
zurück (mglw. mit Makros) auf genehmen, schönen C-Code.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja P3^2 = 0 ist dann das was übrig ist. Was das P3^2 genau macht kann 
weis ich nicht. Der Rest macht der Compiler.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mgiaco wrote:
> ja P3^2 = 0 ist dann das was übrig ist. Was das P3^2 genau macht kann
> weis ich nicht. Der Rest macht der Compiler.

OK. (Da musst du mir jetzt ein wenig helfen, ich hab keinen Keil 
Compiler hier)

P3 dürfte wohl der Port Nummer 3 sein und die 2 stehen für den Pin an 
diesem Port.

Ist es möglich, die 2 variabel zu gestalten?
Also sowas in der Art

   P3^PinNr = 0;

wobei PinNr sagen wir mal ein unsigned char ist
int main()
{
  unsigned char PinNr = 2;

  P3^PinNr = 0;
}

(Wenn das klappt, haben wir schon einen Fuss in der Tür.
 Das gewünschte C-Ergebnis würde dann lauten


   unsigned char PinNr[] = { 2, 3, 4, 5 };    // Pins des DAC

   P3^PinNr[dac->ss_device_one] = BIT_CLR;

Die Frage ist an dieser Stelle nur: Sind an dieser Stelle beim ^ nur 
Konstante erlaubt oder können das auch Variablen bzw. Ausdrücke sein.
Die Pin Nummern im Array könnte man noch hinter ein paar Makros 
verstecken, aber im Grunde wärs das dann

Wenn das nicht geht:
Wie setzt du einen Port komplett auf einen Wert (also alle 8 Bit)
   P3 = 0xFF;

Da könnte man auch noch einen Hebel ansetzen.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö das geht nicht habs probiert. Konstanten kann man da nicht verwenden.

Autor: mgiaco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn das nicht geht:
> Wie setzt du einen Port komplett auf einen Wert (also alle 8 Bit)
> P3 = 0xFF;
> Da könnte man auch noch einen Hebel ansetzen.

Ja so kann ich den Port natürlich auch setzten.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.