Forum: Compiler & IDEs cbi / sbi und #define Problem


von Sebastian (Gast)


Lesenswert?

Warum geht das so nicht??

#define glcd_cs0_pin  (glcd_ctrl_port,4)
//mit nem "." hab ich es auch schon probiert
cbi (glcd_cs0_pin);

von Alex (Gast)


Lesenswert?

Deine Schreibweise ist veraltet. Wo und wie hast du glcd_ctrl_port
definiert?

Ansonsten:

glcd_ctrl_port &= ~_BV(4);

Bsp.: PORTB &= ~_BV(PB4);  //setzt PB4 in PORTB auf '0'

von OldBug (Gast)


Lesenswert?

Hi!

Nach Alex' Beispiel müsste Dein #define dann so aussehen:

#define glcd_cs0_pin (glcd_ctrl_port &= ~_BV(4))

_BV(X) steht für "BitValue" und kann durch (1 << X) ersetzt werden.

Gruß,
Patrick...

P.S.: Deprecated-List der avr-libc:
http://www.nongnu.org/avr-libc/user-manual/deprecated.html

von Sebastian (Gast)


Lesenswert?

hmmm ok
werd das mal testen. den port hatte weiter oben definiert.
Schon schade das jeder compiler irgendwie ne andere syntax hat, selbst
wenn es eigentlich die gleiche sprache ist

von OldBug (Gast)


Lesenswert?

sbi/cbi sind meines Wissens nach kein Standard-C.

Um den Aufruf dieses Makros etwas C-Konformer zu machen, würde ich das
#define noch etwas abändern (hab da eben gar nicht drüber
nachgedacht):

#define glcd_cs0_pin() (glcd_ctrl_port &= ~_BV(4))

Aufruf dann so:

[..]
  /* call CS0-Makro: */
  glcd_cs0_pin();
[..]

von Sebastian (Gast)


Lesenswert?

also nochmal nur damit ich das jetzt richtig verstehe...

#define glcd_ctrl_ddr  DDRA
#define glcd_ctrl_port  PORTA
#define glcd_cs0_pin  (_BV(PB4))
#define glcd_cs1_pin  (_BV(PB5))


glcd_ctrl_port  &= glcd_cs0_pin;    //PORTBIT Setzen??
glcd_ctrl_port  &= ~glcd_cs1_pin;   //PORTBIT Löschen??

hoffe ich das mit pinX... einzelnes Portbit lesen dann auch auf die
reihe kriege

von OldBug (Gast)


Lesenswert?

Hm, ja, so gehts natürlich auch ;)
Allerdings ist das Makro für's Setzen noch falsch:

glcd_ctrl_port  |= glcd_cs0_pin;

von OldBug (Gast)


Lesenswert?

Korrekterweise solltest Du natürlich

#define glcd_cs0_pin  (_BV(PA4))
#define glcd_cs1_pin  (_BV(PA5))

benutzen...

von Sebastian (Gast)


Lesenswert?

ja... doch. jetzt wo du es sagst. das wäre dann auch wieder so ein
fehler gewesen wo man sich fragt... warum geht das nicht??

dankschön.

Kannst du mir noch ein kleines beispiel geben... für ein einelnes
Portbit lesen?

Hab bis jetzt immer mit Codevision Demo getestet, aber da ist man dann
doch relativ schnell am demolimit.

von OldBug (Gast)


Lesenswert?

Das schlimme ist: es hätte ja funktioniert! Aber man liest dann Fehler
aus dem Sourcecode, was bei der Suche nach denselben nicht gerade
behilflich ist ;-)
In den ioxxx.h-Files sind beispielsweise PA0 und PB0 einfach nur "0"
zugewiesen (weil es jeweils das erste Bit ist).

Einlesen kann man die Bits nicht einzeln, wenn man liest, dann immer
das gesamte Byte. Genau wie beim Schreiben. Wenn Du wissen willst, ob
PA3 gesetzt ist, dann kannst Du das so machen:

  if((PORTA & _BV(PA3)))
    /* Bit is set */
  else
    /* Bit is not set */

von Sebastian (Gast)


Lesenswert?

irgendwie will es nicht so wie ich es will.
vielleicht sollte ich mich doch mehr um asm bemühen.

aus irgendeinem grund ist gcc verdammt umständlich...
bei den anderen compilern kann man z.B. folgendes machen

while (PINB.7)
{
  ...
}

oder PORTX.X = 0

sowas vermisse ich wirklich.
sehr sehr ärgerlich wenn man so viel beachten muß um eigentlich was
ganz banales wie "sbic pinb.7" zu machen

von Jörg Wunsch (Gast)


Lesenswert?

Ich hab's schon paarmal geschrieben:

Wenn mir jemand zeigt, nach welchem Schema etwas wie

PORTB.7

gültiges C wäre, würde ich mich an die Implementierung für den GCC
machen.

Solange das aber gegen jeglichen Sprachstandard für C verstößt (und
damit auch keine Chance hat, als ,,Spracherweiterung'' durchzugehen
wie vielleicht die 0b Konstanten), ist es sinnlos, darüber zu
diskutieren.

Was ich nicht so recht verstehe: Programmierer von Betriebssystemen
programmieren seit Jahrzehnten mit Bitmanipulation (aus der
Betriebssystemecke stammt C schließlich) ohne die leisesten Probleme,
und von denen ist noch nie der Ruf nach besonderen Pseudo-Operationen
für sowas laut geworden...  Warum können nicht Microcontroller-
Programmierer auch ganz einfach mit normalem Standard-C arbeiten?

Der Vorteil ist, daß es auf jedem C-Compiler einfach funktionieren
sollte. ;-)

Wie Patrick schon schrieb: falls Du irgendwas sehr häufig brauchst,
ist es ja kein Problem, einen eigenen Präprozessormakro dafür zu
schreiben.  Andererseits lohnt das oft in der von Dir gewünschten
Allgemeinheit eigentlich gar nicht -- manche der Bits muß man
wahrscheinlich nur während der Initialisierung setzen, dann setzt man
lieber gleich das ganze Steuerregister auf einmal, statt x-mal ein SBI
haben zu wollen.

von Sebastian (Gast)


Lesenswert?

das mit PORTB.7 wäre für mich schon gültig... in c und in vielen anderen
sprachen auch. sogesehen ist jeder Port für mich ein Bitarray mit 8
Elementen auf die man mit dem ".-operator" zugreift.

GCC ist der 1. Compiler den ich bis jetzt gesehen habe wo das so nicht
implementiert ist. Codevision, Imagecraft, Bascom,... und eigentlich
alle anderen auch machen das so. Es ist schwer sich daran zu gewöhnen
das das hier nicht so geht

von Sebastian (Gast)


Lesenswert?

aber du hast ja irgendwo recht.
Das ist ja der größte nachteil an C... bis man C wirklich beherrscht
ist man mehr damit beschäftig sich mit der syntax rumzuquälen als sich
mit dem eigentlichen Problem zu beschäfitigen.

von OldBug (Gast)


Lesenswert?

Jörg schrieb irgendwann:

>PORTX.0 = 1;
>
>Dabei ist mir aber die C-syntaktische Auflösung des Knotens unklar.
>Nach einem Punkt müßte ein struct tag folgen, aber eine Zahl oder
>Ziffer ist kein gültiger struct tag.

Und genau da liegt das Problem. Versuch mal, ein Bitfeld anzulegen, auf
das Du mit X.0; X.1; ... zugreifen kannst.
X.BIT0; X.BIT1; ... wird möglich sein.

von Jörg Wunsch (Gast)


Lesenswert?

> das mit PORTB.7 wäre für mich schon gültig...

Für Dich vielleicht, nicht aber für die C-Syntax.

> sogesehen ist jeder Port für mich ein Bitarray mit 8 Elementen auf
> die man mit dem ".-operator" zugreift.

Kannst Du ja machen wollen, aber Feldnamen dürfen nicht mit einer
Ziffer beginnen.

Der GCC ist halt in erster Linie ein C-Compiler, der Parser ist völlig
generisch.  Erst in zweiter Linie besitzt er ein Backend, das Code für
den AVR generieren kann.  Genauso wie für drei Dutzend weiterer
Prozessoren (und das unterscheidet ihn eben von Codevision,
Imagecraft etc.).

> bis man C wirklich beherrscht ist man mehr damit beschäftig sich mit
> der syntax rumzuquälen

Was aber an den Bitmanipulationen mit | und & so schwierig zu
verstehen ist, kannst Du dennoch nicht so recht beschreiben.

von Matthias (Gast)


Lesenswert?

Hi

ich mach mir für jedes Bit das ich an den Ausgängen ändern muß drei
Makros:

#define LED_SIM_TOG    PORTB^=(1<<3)
#define LED_SIM_ON    PORTB|=(1<<3)
#define LED_SIM_OFF    PORTB&=(unsigned char)(~(1<<3))

dann kann ich im Sourcecode schreiben:
LED_SIM_ON;
und der Pin geht auf High. Fertig.

Matthias

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.