Hallo Leute,
sowohl die Foren- als auch die Googlesuche haben keinen gewünschten
Erfolg gebracht, daher nun folgende Frage.
Bei den C-Compilern von Microchip gibt es für jeden Prozessor ein
Headerfile. In diesem .h file sind unter anderem alle
Special-Funktion-Register als unions hinterlegt (Bitweise oder byteweise
Lesen und schreiben).
Bei den WinAvr Bibliotheken habe ich so etwas nicht finden können.
Einzelne Bits kann man ja folgendermaßen setzen:
Registername ^= (1<<Registerbit);
Registername &=~(1<<Registerbit);
allerdings bin ich nicht in der lage folgende Konstruktionen mit WinAvr
hin zu bekommen:
LATAbits.LATA1 = PORTBbits.PORTB1; // dafür finde ich keinen
gleichwertigen ersatz
Kann mir vielleicht jemand verraten ob ich nur unfähig bin die WinAvr
Hilfe richtig zu lesen, oder müsste ich mir eine Solche zuweisung selber
zusammen basteln??
Grüße Tarkan
Was ich mich grad frage, was willst du damit eigentlich machen ein Bit
durch ein anderes setzen?
Aber die Schreibweise von dir ist mir unbekannt. Denke da musst du dir
selbst was basteln wenn du es so schreiben willst.
edit
war wohl zu langsam
Frederik Krämer schrieb:> Was ich mich grad frage, was willst du damit eigentlich machen ein Bit> durch ein anderes setzen?>> Aber die Schreibweise von dir ist mir unbekannt. Denke da musst du dir> selbst was basteln wenn du es so schreiben willst.
Die Schreibweise ist standardmäßig bei Microchip Compilern machbar. Ich
komme aus der Ecke und darf/muss mich jetzt mit Atmels beschäftigen.
Geist schrieb:> Such mal nach "struct" gehört und "bitfield".
Auf Port-Ebene? Viel Spass...
BTW:
Lasst doch mal die ganze Bitpfriemelei auf einem uC aussen vor. Das ist
für den unglaublich umständlich zu berechnen. In meinen Programmen
bekommt (solange genug Speicher da ist) jeder Zustand ein eigenes Byte:
1
uint8_tschalter,taster,licht;
2
3
schalter=PORTB&(1<<PORTB1);
4
taster=PORTC&(1<<PORTC2);
5
6
if(schalter)licht=1;
7
if(taster)licht=0;
8
:
Jetzt könnte ein Hacker drauf kommen und alles zusammen in ein Bitfeld
hacken, das dann natürlich statt 3 Bytes nur noch 1 Byte braucht. Aber
sieh sich mal einer hinterher das Listing an...
uwie schon erwähnt lauten die zauberworte union, bitfield und zusätzlich
struct und packed struct - wenn du die begriffe an gurgel verfütterst,
solltest du eigentlich recht leicht auf die lösung kommen...
z.b. so schrieb:> uwie schon erwähnt lauten die zauberworte union, bitfield und zusätzlich> struct und packed struct - wenn du die begriffe an gurgel verfütterst,> solltest du eigentlich recht leicht auf die lösung kommen...
ich weiß, dass es sowas gibt. Wenn man meine Frage richtig gelesen
hätte, dann wüsste man, dass ich gefragt habe ob der WinAvr C-Compiler
sowas in seinen Headerfiles bereit stellt. Dass man soetwas selber
erstellen kann und wie das geht weiß ich selber
Nur für jedes einzelne SFR mir meine eigene Union zu schreiben fände ich
etwas aufwändig.
Tarkan D. schrieb:> müsste ich mir eine Solche zuweisung selber> zusammen basteln??
Ja, es geht unter WINAVR, aber Du mußt es selber machen.
Ich sehe darin allerdings keinen richtigen Sinn, Du ersetzt eine
Schreibweise durch eine andere, genauso wenig aussagende.
Mich interessiert bei meinen Programmen aber nicht der konkrete Pin,
sondern die Funktion, die er hat.
Ich mache mir daher Definitionen mit aussagekräftigen Namen, z.B.:
Kann mir kurz jemand erklären was man mit SBIT() macht?Odre wo kann ich
das nachlesen? Weder AVRStudio hilfe noch WINAVR hilfe noch google geben
mir eine antwort
möglicherweise ist das der "heilige Gral" nach dem ich gesucht habe!!
Lothar Miller schrieb:> Jetzt könnte ein Hacker drauf kommen und alles zusammen in ein Bitfeld> hacken, das dann natürlich statt 3 Bytes nur noch 1 Byte braucht. Aber> sieh sich mal einer hinterher das Listing an...
Wozu erst extra Variablen, nimm doch gleich die Pins.
Dann sieht das Listing auch vernünftig aus:
Peter Dannegger schrieb:> Wozu erst extra Variablen, nimm doch gleich die Pins.
Ich habe mir angewöhnt, für Prozessabläufe bewusst nicht die Pins
(zumindest nicht die Eingangspins) zu verwenden, sondern wie bei SPSen
üblich erst mal ein Eingangssbbild einzulesen, mit dem dann ein
Ausgangsabbild zu berechnen und das dann auf die Ports abzubilden.
Und warum? Damit gibt es keine solchen Grenzfälle mehr, wo ein
Taster/Schalter/Sensor im Programm mehrfach abgefragt wird, aber erst in
der 2. Programmhälfte aktiv wird...
Aber für die Low-Level IO-Manipulation muß ich mir das mit den
Bitfeldern offenbar noch mal genauer ansehen. Die Compiler scheinen
besser geworden zu sein... ;-)
Tarkan D. schrieb:> Warum bekomme ich bei folgendem Code
Weil Du den wichtigen Teil weggelassen hast.
Um auf "struct bits" zu zeigen, muß der Compiler ja wissen, was das
überhaupt ist.
Ich dachte, Du hast schonmal Bitfelder benutzt?
Peter
Tarkan D. schrieb:> Mit Bitfeldern hatte ich im Prinzip nur folgende Spielereien> veranstaltet:>>>
1
>
2
>
3
>uniongruetze
4
>{
5
>struct
6
>{
7
>unsignedcharbit0:1;
8
>unsignedcharbit1:1;
9
>unsignedcharbit2:1;
10
>unsignedcharbit3:1;
11
>unsignedcharbit4:1;
12
>unsignedcharbit5:1;
13
>unsignedcharbit6:1;
14
>unsignedcharbit7:1;
15
>};unsignedchargruetz_byte;
16
>};
17
>
18
>
19
>
20
>
>> und dann bitweise schreiebn und auslesen
Ja.
Und weiter?
Jetzt musst du nur noch den nächsten Schritt machen.
Du hast ein Register. Das wird dir vom Compiler wie eine Variable
präsentiert. Nimmst du also die Adresse dieser Variablen her, dann
kannst du dem Compiler durch Umcasten dieser Adresse in einen anderen
Datentyp weismachen, dass an genau dieser Stelle im Speicher nicht
einfach nur ein Byte sitzt, sondern dass sich dort an dieser Adresse im
Speicher genau so ein Bitfeld befindet.
Und voila. Schon kannst du über ein Bitfeld auf die Einzelbits
zugreifen.
Einfach nur 2 und 2 zusammenzählen und 2 Techniken miteinander
kombinieren.
Peter S. schrieb:> @peda> Und wieso verschachtelst Du das in zwei #defines?
Das (die genaue Funktionsweise von ##) ist eines der großen Mysterien
des C-Präprozessor. Nimm einfach hin, dass wenn es richtig funktionieren
soll, man das immer 2-stufig machen muss. Ansonsten werden Argumente an
dieses Makro, welche seinerseits Makros sind, nicht richtig ausgewertet.
Okey, dann nehme ich das einfach mals als "Mysterium" hin! ;o)
Ich hatte mich mich nämlich gefragt, ob ich da was offensichtliches bzw.
triviales übersehe...
Und schon wird das bit 0x35.b0 angesprochen.
Und damit wird auch klar, warum das 2. Macro.
Wenn man nämlich "b##PC0" zusammenkleben würde, kommt nicht "b0" raus,
sondern "bPC0" und das ist kein Element von "struct bits".
Das Macro "PC0" muß erst noch zu "0" expandiert werden.
Peter
Peter Dannegger schrieb:> Und damit wird auch klar, warum das 2. Macro.> Wenn man nämlich "b##PC0" zusammenkleben würde, kommt nicht "b0" raus,> sondern "bPC0" und das ist kein Element von "struct bits".> Das Macro "PC0" muß erst noch zu "0" expandiert werden.
Ganz so einfach ist es nicht, denn dann dürfte
#define LED_BIT PC0
#define LED SBIT( PORTC, LED_BIT )
nicht compilieren :-)
Die Reihenfolgen in der Makros selbst bzw. Makroargumente expandiert
werden ist in manchen Fällen auf den ersten Blick etwas dubios.
##, genauso wie #, verhält sich hier einfach anders. Beide expandieren
ihre möglichen Makroargumente selbst nicht. Zumindest nicht so, wie es
an anderen Stellen der Makrobearbeitung passiert.