PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C und Bit Arrays erstellen... aber wie?!


DraconiX
2010-02-11, 23:29:45
Hiho... ich programmier gerade in C... (MicroC für AVR) jedoch stoße ich nun auf ein kleines Problem. Ich möchte eigentlich nur ein 24Bit Array aus Bits erstellen (01000101100...). Ich mach das gerade über Umwege mit einem Char Array:


char* bitmask[24];
....

for(i=0;i<24;i++){bitmask[i] = wert;}

Jedoch ist mir das zu langsam, zu rechenintensiv und speicherfressend... ein Char Typ sind ja 1Byte = 8Bit - quasi würden ja 3Byte reichen. Ein Array des Datentyps Bit läßt C jedoch nicht zu :/
Wie komme ich nun daran die einzelnen Bit darin zu ändern?!

Jemand ein Tipp?!

Pinoccio
2010-02-11, 23:32:11
Jemand ein Tipp?!Integer und dann mit XOR etc. und shifts drauf arbeiten?
Bzw wenn du nur 24 Bit benötigst dann long.

mfg

Gast
2010-02-12, 00:19:39
Integer und dann mit XOR etc. und shifts drauf arbeiten?
so siehts aus!

Gnafoo
2010-02-12, 00:22:20
In den meisten Fällen sind die booleschen Operationen vermutlich die einfachste Wahl. Sprich "x |= (1 << n)" um das n-te Bit zu setzen, "x &= ~(1 << n)" um es zu löschen und "(x & (1 << n)) != 0" um herauszubekommen, ob es gesetzt ist.

Ansonsten gibt es natürlich noch die freakige Variante mit den Bitfeldern und Union in C:


union word
{
char value;
struct
{
unsigned int bit1 : 1;
unsigned int bit2 : 1;
unsigned int bit3 : 1;
unsigned int bit4 : 1;
unsigned int bit5 : 1;
unsigned int bit6 : 1;
unsigned int bit7 : 1;
unsigned int bit8 : 1;
};
};

int main()
{
union word bitfield[3];
memset(bitfield, 0, sizeof(union word[3]));

bitfield[0].value = 123; // 1111011 = 123
bitfield[1].bit4 = 1; // 1000 = 8
bitfield[2].bit1 = 1;
bitfield[2].bit3 = 1; // 101 = 5

printf("%i\n", bitfield[0].bit1); // 1
printf("%i\n", bitfield[1].value); // 8
printf("%i\n", bitfield[2].value); // 5
return 0;
}


Wobei das vermutlich abhängig von der Endianness der Zielplattform unterschiedliche Ergebnisse ausgeben dürfte. Möglicherweise spielt das Alignment des Compilers auch eine Rolle. Von daher finde ich die Bit-Operationen persönlich schöner (zumal unter der Haube quasi dasselbe passieren dürfte).

Der_Donnervogel
2010-02-12, 00:28:14
Je nachdem was genau der Zweck der Übung sein soll, kann auch ein Bitfield (http://en.wikipedia.org/wiki/Bitfield) die Lösung sein.

edit: Zu spät :usad:

#44
2010-02-12, 01:21:57
Du stehst so oder so vor der Wahl Speicher oder Rechenaufwand zu sparen.

Beides bekommst du nicht, da du nunmal keine Bits adressierst.

Wenn's nicht zwingend nötig ist, lass den Speicher Speicher sein. Der Code wird durch Bitschubserei langsamer, größer und hässlicher.

Zu den Bitfields: Lies die letzten 3 Absätze. (http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html)

Gnafoo
2010-02-12, 01:41:41
Auf der anderen Seite ist der Rechenaufwand eigentlich vernachlässigbar. Bei größeren Bitfeldern könnte ich mir sogar vorstellen, dass man durch die Cache-Effizienz und den Umstand, dass mehr Werte in den Registern bleiben können schneller ist. Ist ja immerhin ein Verhältnis des Speicheraufwandes von 1:8.

Recht hast du natürlich insofern, als dass das hier vermutlich sowieso keine Rolle spielt und damit teilweise unter das Motto unsinnige Optimierung fällt. Auf der anderen Seite ist das so schwer nun auch nicht umzusetzen und hässlich wird es meiner Meinung nach auch nicht, wenn man die ganze Bitfuchtelei mit einer netten wiederverwendbaren Datenstruktur und hinter ein paar Zugriffsmethoden kapselt.

Für einen Anfänger in C ist das imho eine schöne Übung. Wenn es einfach nur funktionieren soll sind die Arrays höchstwahrscheinlich auch okay.

Gast
2010-02-12, 08:47:21
Auf AVR8 gibt's keinen Cache und auch keine nennenswerte Anzahl an Registern ;)
Am sinnvollsten sind imho die schon vorgeschlagenen Bitoperationen. Den Speicher kannst du entweder mit einer (u)int32_t aus avr/stdint.h (entspricht einer long, ist aber schöner ;) ) oder mit (u)int8_t[3] allozieren. Bei ersterem verschwendest du ein Bit, dafür ist die Adressierung leichter.

Gast
2010-02-12, 08:50:14
du solltest dir Macros für die Bitoperationen schreiben.
SETBIT(var, n)
RESETBIT(var, n)
GETBIT(var, n)
wirst du spätestens nach dem dritten Zugriff auf ein Bit lieben.

Gast#44
2010-02-12, 09:25:21
Auf der anderen Seite ist der Rechenaufwand eigentlich vernachlässigbar.

Der TS schrieb das (ihm) die bisherige Lösung zu langsam und zu rechenintensiv ist, darum habe ich darauf aufmerksam gemacht. Letztendlich muss er ja abwägen, was genau er jetzt sparen will.

hässlich wird es meiner Meinung nach auch nicht, wenn man die ganze Bitfuchtelei mit einer netten wiederverwendbaren Datenstruktur und hinter ein paar Zugriffsmethoden kapselt. Auch wieder wahr. :) Dann sollte man darauf achten, die Methoden nicht Inline zu deklariren um Sprünge zu vermeiden. Das Codesegment zu vergrößern um im Datensegment etwas zu sparen kann hier zum gegenteiligen Effekt führen. 21 Byte hätte man in diesem Fall schnell beisammen.

DraconiX
2010-02-12, 19:54:31
In den meisten Fällen sind die booleschen Operationen vermutlich die einfachste Wahl. Sprich "x |= (1 << n)" um das n-te Bit zu setzen, "x &= ~(1 << n)" um es zu löschen und "(x & (1 << n)) != 0" um herauszubekommen, ob es gesetzt ist....


Das sieht schonmal super aus... Dank dir!

du solltest dir Macros für die Bitoperationen schreiben.
SETBIT(var, n)
RESETBIT(var, n)
GETBIT(var, n)
wirst du spätestens nach dem dritten Zugriff auf ein Bit lieben.

Werde ich machen, wird am effektivsten sein, somit kann ich es auch einfacher in andere Programme übertragen.

Auf AVR8 gibt's keinen Cache und auch keine nennenswerte Anzahl an Registern
Am sinnvollsten sind imho die schon vorgeschlagenen Bitoperationen. Den Speicher kannst du entweder mit einer (u)int32_t aus avr/stdint.h (entspricht einer long, ist aber schöner ) oder mit (u)int8_t[3] allozieren. Bei ersterem verschwendest du ein Bit, dafür ist die Adressierung leichter.

Jep, compiliere aber mit MicroC da gibts nur int, long, char, etc... werde wohl long nehmen, ein Array wird zu schnell zu unübersichtlich. Und auf ein Bit kommt es nicht mehr drauf an. Jedoch verhunzt mein Atmega leider das Char Array bei einem Overflow Interrupt wenn er gerade am schreiben ist, deswegen der Umstieg auf die Bitoperationen...

noid
2010-02-12, 20:15:45
Ich würde mal tippen bei dem Speicherüberschuss, den du hast sollte der char-array aber auch ok sein.

Und das mit dem kaputtmachen... overflow interrupt? woher kommt der denn? Sowas immer zuerst abstellen.

DraconiX
2010-02-12, 20:20:04
Ich würde mal tippen bei dem Speicherüberschuss, den du hast sollte der char-array aber auch ok sein.

Und das mit dem kaputtmachen... overflow interrupt? woher kommt der denn? Sowas immer zuerst abstellen.

Der Overflow Interrupt ist gewollt ;) Besser gesagt heißt er ja Timer Overflow Interrupt - sprich ist ein Wert bei einem Timer (16Bit Timer auf AVR8 AT32) erreicht wird der Interrupt ausgeführt - egal was gerade gemacht wird.

for(i=0;i<20;i++)
{
test |= (1 << i);
//test &= ~(1 << i);
}

for(i=0;i<24;i++)
{
if ((test & (1 << i)) != 1) UART1_Write_text("1"); else UART1_Write_text("0");
}

Bin nun soweit, jedoch schreibt er mir immer nur den ersten Bit um... blick da net durch :frown:

pest
2010-02-12, 20:29:59
if ((test >> i) & 1 == 1) do something

Der_Donnervogel
2010-02-12, 20:32:12
for(i=0;i<20;i++)
{
test |= (1 << i);
//test &= ~(1 << i);
}

for(i=0;i<24;i++)
{
if ((test & (1 << i)) != 1) UART1_Write_text("1"); else UART1_Write_text("0");
}

Bin nun soweit, jedoch schreibt er mir immer nur den ersten Bit um... blick da net durch :frown:Der Grund dafür liegt darin dass der Test nicht korrekt ausgewertet wird:

(test & (1 << i)) != 1

ist falsch

es müsste

(test & (1 << i)) >= 1

sein. Der Grund liegt darin, dass die Operation (test & (1 << i)) kein Test ist ob dort eine 1 sitzt, sondern alle Bits außer dem Bit an Stelle i auf 0 gesetzt werden*. Aber je nach Stelle von einem gesetzten Bit in einem int ändert sich der Wert der Zahl. Das Resultat ist je nach Stelle die entsprechende Zweierpotenz, also 1, 2, 4, 8, usw., je nachdem welches Bit gesetzt wurde und nicht etwa 1. Deshalb klappt es auch nur bei ersten Bit.

edit: * und wenn das Bit dort nicht gesetzt ist, ist das Resultat 0.

noid
2010-02-12, 20:36:59
Der Overflow Interrupt ist gewollt ;) Besser gesagt heißt er ja Timer Overflow Interrupt - sprich ist ein Wert bei einem Timer (16Bit Timer auf AVR8 AT32) erreicht wird der Interrupt ausgeführt - egal was gerade gemacht wird.

{Code wurde ja schon gefixt, wobei ich != 1 und >= 1 auch nicht schreiben würde: (test & (1 << i)) reicht vollkommen um zu schauen ob das Ergebnisregister ungleich null ist. Viel wichtiger ist, dass du die 1 bei gleich mit (long) bzw dem Typ von test) castest, damit der compiler nicht ne 8bit konstante draus macht und dir Plötzlich was fehlt - auch hier wieder gleich "sauber" schreiben sonst kommt dat zurück (auch wenn die Alu mehr als 8bit hätte)}

Ähm, dann baust du dir nen makro, whatever um eben kritische stellen zu umgehen. Sprich: Ints disablen solange du solche Operationen machst. Oder du machst deinen Interrupt sauber und ordentlich.

Alles andere wird dich nur später durcheinander bringen. Glaub mir, ich hab's einmal nicht gemacht (später erkennbar am TODO im code) und dann fällt das vllt erstmal nicht weiter auf.

Und auch wenn so Codekünstler wie Coda etc. das nicht gerne lesen:
FORMATIERT EUREN TEXT DOCH BITTE EINHEITLICH UND AM BESTEN KONSISTENT.
Für sowas wie
if (true) _nop(); else _nop();
kackt man mir hier auf den Tisch. :freak:

Coda
2010-02-12, 21:20:55
Und auch wenn so Codekünstler wie Coda etc. das nicht gerne lesen:
Kannst du mich bitte mal ganz dezent am Arsch lecken?

So eine Unverschämtheit ist mir wirklich schon lange nicht mehr unter gekommen. Nur weil ich einmal ein bisschen hackigen Code gepostet habe brauchst du hier nicht so einen Dünnschiss ablassen mein Lieber.

pest
2010-02-12, 21:28:42
er meinte mich, er hats nur verwechselt :cool:

Coda
2010-02-12, 21:33:07
Na das will ich auch hoffen.

Aber hier wird man von manchen ja schon dumm angemacht wenn man die geschweifte Klammer in die gleiche Zeile schreibt bei einem if, obwohl das sogar IDEs automatisch so machen. Ich glaub's nicht so ganz.

DraconiX
2010-02-12, 21:56:21
Viel wichtiger ist, dass du die 1 bei gleich mit (long) bzw dem Typ von test) castest, damit der compiler nicht ne 8bit konstante draus macht und dir Plötzlich was fehlt


So was ähnliches passiert nun gerade... er ändert die ersten 16 Bit die letzten 16 Bit fallen beim schreiben oder lesen irgendwie unter den Tisch, so als ob ich nur eine 2Byte Variable habe. Die Doku von MicroC sagt aber explizit das long eine 4Byte Variable ist. :/

Wie soll ich denn das direkt casten?! Gleich mit


long test = "1.1";


initialisieren?!


EDIT:

Ich habe nunmal mit:


unsigned long test = 4294967295;


deklariert, aber ohne Wirkung... nur bis 16Bit Schreib/Lesbar

noid
2010-02-12, 22:31:43
Kannst du mich bitte mal ganz dezent am Arsch lecken?

So eine Unverschämtheit ist mir wirklich schon lange nicht mehr unter gekommen. Nur weil ich einmal ein bisschen hackigen Code gepostet habe brauchst du hier nicht so einen Dünnschiss ablassen mein Lieber.

Unverschämt ist nur deine Ausdrucksweise und dein Unwillen dich an (sinnvolle) Codingconvetions zu halten.

er meinte mich, er hats nur verwechselt :cool:

Ne, so wichtig bist du bezüglich code auch nicht. Eigentlich bei nix, wenn ich es mir überlege.

Na das will ich auch hoffen.

Aber hier wird man von manchen ja schon dumm angemacht wenn man die geschweifte Klammer in die gleiche Zeile schreibt bei einem if, obwohl das sogar IDEs automatisch so machen. Ich glaub's nicht so ganz.

IDEs haben aber ein preset von sinnigen und unsinnigen Autoformatern.

So was ähnliches passiert nun gerade... er ändert die ersten 16 Bit die letzten 16 Bit fallen beim schreiben oder lesen irgendwie unter den Tisch, so als ob ich nur eine 2Byte Variable habe. Die Doku von MicroC sagt aber explizit das long eine 4Byte Variable ist. :/

Wie soll ich denn das direkt casten?! Gleich mit


long test = "1.1";


initialisieren?!


EDIT:

Ich habe nunmal mit:


unsigned long test = 4294967295;


deklariert, aber ohne Wirkung... nur bis 16Bit Schreib/Lesbar

Ich meinte mit dem cast eigentlich die (1 << i)-Geschichte. ((unsigned long)1 << i)

Coda
2010-02-12, 22:35:10
Unverschämt ist nur deine Ausdrucksweise und dein Unwillen dich an (sinnvolle) Codingconvetions zu halten.
Du kannst mich WIRKLICH am Arsch lecken.

Und meine Ausdrucksweise ist mir im Moment ehrlich gesagt egal. Bei sowas wie dir brauche ich mir da wirklich keine Mühe mehr geben.

Ne, so wichtig bist du bezüglich code auch nicht. Eigentlich bei nix, wenn ich es mir überlege.
Hast du sie eigentlich noch alle?

Für den Scheiß hier sollte man dir mindestens ne Woche Auszeit geben. So eine unglaublich assoziale Haltung habe ich ja schon lange nicht mehr erlebt.

Und das beim Streit über so einen unglaublich unwichtigen Scheiß wie wer wie wo seine Klammern hinsetzt. Kindischer geht's ja wohl nicht.

IDEs haben aber ein preset von sinnigen und unsinnigen Autoformatern.
Ich rede vom *DEFAULT* bei so kleinen Dingen wie Eclipse und der Java Coding Guideline:
http://java.sun.com/docs/codeconv/html/CodeConventions.doc6.html#449

noid
2010-02-12, 22:39:26
{lalala}

Ich rede vom *DEFAULT* bei so kleinen Dingen wie Eclipse und der Java Coding Guideline:
http://java.sun.com/docs/codeconv/html/CodeConventions.doc6.html#449

Java ist nicht C, und gerade bei C sollte man es deutlicher schreiben.
Die Leute wundern sich warum nix tut, könnens nicht lesen und fragen sich später warum der Compiler da nix rumgemault hat.

@OT: ich würde dringend empfehlen den Compiler so einzustellen, dass er max. Warnings wirft. Und auch am besten keine haben.

edit: genau in dem Link steht was man nicht machen soll, Coda. {}, und so.

DraconiX
2010-02-12, 22:44:39
...
Ich meinte mit dem cast eigentlich die (1 << i)-Geschichte. ((unsigned long)1 << i)

Jep, achso... ja hatte vorher schon mit (1L << i) probiert, jedoch komme ich auch da nicht über die 16Bit Hürde raus, schätze mal das mein MicroC long nur als 2Byte berechnet :/

Coda
2010-02-12, 22:52:24
Es gibt keine feste Guideline für C, deshalb kann es jeder so halten wie ER es für richtig hält wenn er privat arbeitet. Sonst hätten K&R damals diese Möglichkeit auch nich eingebaut.

Im prof. Umfeld bin ich gerne bereit mein Zeug so obskur zu formatieren wie es gewünscht wird. Die Lesbarkeit ändert sich für mich eh nicht, weshalb ich hier auch keinen so lächerlichen Glaubenskrieg abfahre wie Herr noid.

noid
2010-02-12, 22:53:53
Jep, achso... ja hatte vorher schon mit (1L << i) probiert, jedoch komme ich auch da nicht über die 16Bit Hürde raus, schätze mal das mein MicroC long nur als 2Byte berechnet :/

Das sollte bei korrektem code nicht passieren, assembly passt?

[unsigned] long ist 4byte O_o

DraconiX
2010-02-12, 23:03:24
Ich habe es! :D So funktioniert es - Danke NOID:



for(i=0;i<24;i++)
{
if(bitmask_l[i] == '1') test |= ((unsigned long)1 << i); else test &= ~((unsigned long)1 << i);
}

for(i=0;i<24;i++)
{
if ((test >> i) & 1 == 1) UART1_Write_text("1"); else UART1_Write_text("0");
}


Danköööö euch allen! Habt mir sehr geholfen!
Und so werden die 24Bit auch korrekt ins Schieberegister geschrieben.:


for(i=0;i<24;i++)
{
PortB.B1 = 0; mdelay;
PortB.B3 = (test >> i) & 1; mdelay;
PortB.B1 = 1; mdelay;
}


Nun muß ich bloß diese blöde Bitmaske umgehen, so das er garnicht erst über ein Chararray kommt...

Der_Donnervogel
2010-02-12, 23:55:03
{Code wurde ja schon gefixt, wobei ich != 1 und >= 1 auch nicht schreiben würde: (test & (1 << i)) reicht vollkommen um zu schauen ob das Ergebnisregister ungleich null ist.Es reicht, allerdings macht es den Code nicht unbedingt verständlicher. C ist sowieso eine Sprache, die wie kaum eine andere dazu geeignet unleserlichen Code zu schreiben.

Insofern sind Code Guidlines bei C eine gute Sache. Allerdings deswegen andere Leute in einem öffentlichen Forum so anzumachen, wo es doch gar keine offiziellen Richtlinien gibt, ist schon etwas daneben. Übrigens, gut leserlicher C-Code kann auch so ausschauen:

#include <stdio.h>
#define DIM int
#define IF if (
#define THEN ) {
#define ELSE } else {
#define ENDIF }
#define SUB int
#define Main() main() {
#define ENDSUB return 0; }
#define PRINT(STR, NUM) printf("%s %d", STR, NUM);

SUB Main()
DIM a = 2;
IF a < 0 THEN
PRINT("Negative Zahl:", a)
ELSE
PRINT("Positive Zahl:", a)
ENDIF
ENDSUB
;)
Wie soll ich denn das direkt casten?! Gleich mit


long test = "1.1";


initialisieren?!
:confused:
Was soll denn das darstellen? Ich weiß gar nicht wo ich anfangen soll. Erstens ist long ein numerischer Typ, dem man keinen String zuweisen kann, bzw. der Compiler weist dem allenfalls implizit den Pointer vom String zu. Wenn dann müsste man also die Anführungszeichen weg lassen, aber selbst dann ist es falsch, da long keine Gleitkommazahlen verträgt. C würde einfach den Nachkommateil abschneiden.
Java ist nicht C, und gerade bei C sollte man es deutlicher schreiben.In der Sache gebe ich da recht, das Guidelines bei C hilfreich sind. Allerdings die Art und Weise wie das hier im Thread kommuniziert wurde, ist weniger hilfreich.
Im prof. Umfeld bin ich gerne bereit mein Zeug so obskur zu formatieren wie es gewünscht wird. Die Lesbarkeit ändert sich für mich eh nicht, weshalb ich hier auch keinen so lächerlichen Glaubenskrieg abfahre wie Herr noid.Das sehe ich genauso.

pest
2010-02-12, 23:56:53
Ne, so wichtig bist du bezüglich code auch nicht. Eigentlich bei nix, wenn ich es mir überlege.


DraconiX nimmt zumindest mein Code-Beispiel :)
und da ich nicht ganz so anti-sozial bin wie du, setze ich dich einfach auf meine Ignore

noid
2010-02-13, 09:31:50
{..}
In der Sache gebe ich da recht, das Guidelines bei C hilfreich sind. Allerdings die Art und Weise wie das hier im Thread kommuniziert wurde, ist weniger hilfreich.
Das sehe ich genauso.
Ich hab's nur gekürzt, weil's sonst so extrem lang aussieht, der Quote.
Mir ist der Pseudo-VB code mit zuvielen Makros ausgestattet ;)

Gewisse Guidelines bei C sind im prof. sowie im privaten einfach einzuhalten, einfach weil man so selbst den Code leichter nach logischen Mustern/Fehlern durchsuchen kann. Früher setzte sich man halt hin, machte sich Gedanken was man Programmiert, Diagramm, dann Code schreiben.
Hat man sowas ein paar Dutzende male gemacht, dann kann man Std. lösungen quasi direkt hinschreiben. Wähl man die Formatierung gleich, dann sind die Diagramme quasi in Textform vorhanden.
Mir wäre ja eine Sprachregelung wie bei python sehr gelegen, eben weil da nicht jeder kommt mit "ich mach's aber so". Klar kann ich viel machen, vieles ist extrem Fehleranfällig und endet auch oft darin.

Spaghetticode ohne {} um einfache Befehlt/Statements/Funktionen sollte man sich aber auch nicht privat aneignen. Warum hier dann auf einmal den Schlendrian raus lassen?
Warum hier jetzt 2 User meinen gleich bei angebrachter Kritik so abgehen ist mir unklar - Ausdrucksweise total daneben.

Als Hinweis: ich arbeite an/mit SW, die aus 4 Ländern kommt, >1Mio LOC, >50 Entwickler aus Indien, Österreich, USA etc. - und ich kann mit Gewissheit sagen, dass 50% der Fehler daher kommen, weil die Leute sich nicht an Konventions halten und dann die Fehler nicht sehen. Jeden Tag sehe ich das elend von falsch verstandenen "ich mach das aber so,weil es geht".

noid
2010-02-13, 09:53:05
Ich habe es! :D So funktioniert es - Danke NOID:



for(i=0;i<24;i++)
{
if(bitmask_l[i] == '1') test |= ((unsigned long)1 << i); else test &= ~((unsigned long)1 << i);
}

for(i=0;i<24;i++)
{
if ((test >> i) & 1 == 1) UART1_Write_text("1"); else UART1_Write_text("0");
}


Danköööö euch allen! Habt mir sehr geholfen!
Und so werden die 24Bit auch korrekt ins Schieberegister geschrieben.:


for(i=0;i<24;i++)
{
PortB.B1 = 0; mdelay;
PortB.B3 = (test >> i) & 1; mdelay;
PortB.B1 = 1; mdelay;
}


Nun muß ich bloß diese blöde Bitmaske umgehen, so das er garnicht erst über ein Chararray kommt...

Kleiner Tipp: solltest du einen Debugger per JTAG etc nutzen, dann macht sich die Formatierung nicht so gut - weil in einer Line eben mehrere Anweisungen sind.
So müsste man vllt erst ins Assembly schauen um zu sehen wo er in der Zeile ist. Besser ist es eben c-code und registersatz in der EDE offen zu haben.

Für embedded und mikroprozessoren deutlich sinnvoll.

Monger
2010-02-13, 10:22:05
Kannst du mich bitte mal ganz dezent am Arsch lecken?

So eine Unverschämtheit ist mir wirklich schon lange nicht mehr unter gekommen. Nur weil ich einmal ein bisschen hackigen Code gepostet habe brauchst du hier nicht so einen Dünnschiss ablassen mein Lieber.

Ne, so wichtig bist du bezüglich code auch nicht. Eigentlich bei nix, wenn ich es mir überlege.


und da ich nicht ganz so anti-sozial bin wie du, setze ich dich einfach auf meine Ignore

Was zur Hölle ist hier denn los?? Reißt euch mal ganz fix zusammen, sonst schneit es Punkte.

DraconiX
2010-02-13, 10:27:32
Jep, regulär schreibe ich sie auch untereinander :D Einzigste Ausnahme ist wirklich nur wenn ich serial Out schreibe wie in der unteren Schleife - um die Pausen dahinter zu nehmen (Wobei mdelay im fertigen Projekt meistens leer definiert wird (#define mdelay).

Bei einem 4Bit Serial Interface wird es dann nämlich sehr schnell unübersichtlich wenn nun auch noch die Pausen zwischen den Zeilen stehen :freak:

Jedoch habe ich noch nie via JTAG debuggt, der Anschluß ist noch ganz jungfreulich auf meinem DEV Board :D Dazu wird ja ein spezieller Debugger mit internem SRAM benötigt oder?!

Der_Donnervogel
2010-02-13, 15:43:41
Mir ist der Pseudo-VB code mit zuvielen Makros ausgestattet ;)Nix da VB-Code. Das ist korrektes C, das man problemlos z.B. mit dem GCC compilieren kann. :biggrin: Ich verwende das Beispiel immer wieder gerne, wenn es darum geht zu zeige was für Unfug man mit C, bzw. genauer mit dem Preprocessor, anstellen kann. Dabei ist das nur eine der vielen Möglichkeiten unleserlichen Code mit C zu erzeugen. Genau aus solchen Gründen ist es bei C auch sinnvoll Guidelines zu haben. Man kann mit C so viel anstellen, dass da schnell keiner mehr durchblickt.

Ich schreibe allerdings so gut wie nie etwas in C. Aus dem Grund verwende ich, wenn ich mal C-Code schreibe die Guidelines von Java. Da kommt dann auch z.B. die Angewohnheit her nicht etwas wie if (a) zu schreiben, sofern a kein Boolean ist.
Gewisse Guidelines bei C sind im prof. sowie im privaten einfach einzuhalten, einfach weil man so selbst den Code leichter nach logischen Mustern/Fehlern durchsuchen kann.Das Problem ist halt was sind "gewisse Guidelines". Da ich fast nie etwas in C mache kenne ich die C-Guidelines gar nicht, zumal es ohnehin keine Vorgaben vom Hersteller wie z.B. in Java gibt. Ich verwende deshalb die Guidelines von Java, da ich die gewohnt bin. Das ist aber schon etwas das vielen C-Programmierern sauer aufstößt, weil dann z.B. die Klammern nicht in einer eigenen Zeile stehen, usw.
Spaghetticode ohne {} um einfache Befehlt/Statements/Funktionen sollte man sich aber auch nicht privat aneignen. Warum hier dann auf einmal den Schlendrian raus lassen?Das sehe ich auch so, da die fehlenden Klammern vor allem wenn man nachträglich mal was ändern will geradezu dazu einladen Fehler zu machen. Ich kenne allerdings genug Leute die da voll drauf stehen, bei solchen Einzeilern die Klammern weg zu lassen, weil das "übersichtlicher" ist, "Platz spart", usw.
Warum hier jetzt 2 User meinen gleich bei angebrachter Kritik so abgehen ist mir unklar - Ausdrucksweise total daneben.Der Ton macht die Musik. Das gespoilerten Zitat ist alles andere als der sachliche Hinweis doch bitte Guidelines einzuhalten. Das ist hart an der Grenze zu einem Trollpost. Vor allem der persönliche Angriff auf Coda der in diesem Thread noch nicht mal einen Beitrag hatte war mehr als überflüssig.
Und auch wenn so Codekünstler wie Coda etc. das nicht gerne lesen:
FORMATIERT EUREN TEXT DOCH BITTE EINHEITLICH UND AM BESTEN KONSISTENT.
Für sowas wie
if (true) _nop(); else _nop();
kackt man mir hier auf den Tisch. :freak:

Da braucht man sich wirklich nicht wundern, wenn sich Coda angepisst gefühlt hat.
Als Hinweis: ich arbeite an/mit SW, die aus 4 Ländern kommt, >1Mio LOC, >50 Entwickler aus Indien, Österreich, USA etc. - und ich kann mit Gewissheit sagen, dass 50% der Fehler daher kommen, weil die Leute sich nicht an Konventions halten und dann die Fehler nicht sehen. Jeden Tag sehe ich das elend von falsch verstandenen "ich mach das aber so,weil es geht".Ah, da wird mir einiges klarer:

Monger
2010-02-13, 16:31:14
Als Hinweis: ich arbeite an/mit SW, die aus 4 Ländern kommt, >1Mio LOC, >50 Entwickler aus Indien, Österreich, USA etc. - und ich kann mit Gewissheit sagen, dass 50% der Fehler daher kommen, weil die Leute sich nicht an Konventions halten und dann die Fehler nicht sehen. Jeden Tag sehe ich das elend von falsch verstandenen "ich mach das aber so,weil es geht".
Wenn in der Größenordnung Code Conventions euer größtes Problem sind, seid ihr wirklich in einer beneidenswerten Position! ;-)

Das ist ja ungefähr so, als würdest du einen Roman schreiben, und die dringendste Sorge des Autors ist nicht etwa die Story und der sprachliche Schliff, sondern ob die Satzzeichen und Zeilenumbrüche richtig gesetzt sind. Ist natürlich auch wichtig, aber wie gesagt: deine Sorgen möchte ich haben.

Ich halte ganz allgemein nichts von überreglementiertem Layout. Es soll leserlich sein, das ist wichtig. Und je nachdem was da gerade für Code steht, kann mal Variante A oder Variante B besser lesbar sein.

pest
2010-02-13, 16:35:47
ich arbeite derzeit auch an einem größeren Projekt mit und wir verwenden Python, finde aber nicht das das irgendwie lesbarer aussieht, aber vielleicht liegts auch an mir :freak:,
ick weiß das zeug nach den ifs kann man alles schön untereinander schreiben
vor allem das Fehlen von Konstrukten wie "do {} until" lässt solche Codeblüten wie im Spoiler (proposal) entstehen


http://www.abload.de/img/pythont6f3.png

noid
2010-02-13, 17:39:37
Nix da VB-Code. Das ist korrektes C, das man problemlos z.B. mit dem GCC compilieren kann. :biggrin: Ich verwende das Beispiel immer wieder gerne, wenn es darum geht zu zeige was für Unfug man mit C, bzw. genauer mit dem Preprocessor, anstellen kann. Dabei ist das nur eine der vielen Möglichkeiten unleserlichen Code mit C zu erzeugen. Genau aus solchen Gründen ist es bei C auch sinnvoll Guidelines zu haben. Man kann mit C so viel anstellen, dass da schnell keiner mehr durchblickt.

Ich schreibe allerdings so gut wie nie etwas in C. Aus dem Grund verwende ich, wenn ich mal C-Code schreibe die Guidelines von Java. Da kommt dann auch z.B. die Angewohnheit her nicht etwas wie if (a) zu schreiben, sofern a kein Boolean ist.
Das Problem ist halt was sind "gewisse Guidelines". Da ich fast nie etwas in C mache kenne ich die C-Guidelines gar nicht, zumal es ohnehin keine Vorgaben vom Hersteller wie z.B. in Java gibt. Ich verwende deshalb die Guidelines von Java, da ich die gewohnt bin. Das ist aber schon etwas das vielen C-Programmierern sauer aufstößt, weil dann z.B. die Klammern nicht in einer eigenen Zeile stehen, usw.
Das sehe ich auch so, da die fehlenden Klammern vor allem wenn man nachträglich mal was ändern will geradezu dazu einladen Fehler zu machen. Ich kenne allerdings genug Leute die da voll drauf stehen, bei solchen Einzeilern die Klammern weg zu lassen, weil das "übersichtlicher" ist, "Platz spart", usw.
Der Ton macht die Musik. Das gespoilerten Zitat ist alles andere als der sachliche Hinweis doch bitte Guidelines einzuhalten. Das ist hart an der Grenze zu einem Trollpost. Vor allem der persönliche Angriff auf Coda der in diesem Thread noch nicht mal einen Beitrag hatte war mehr als überflüssig.


Da braucht man sich wirklich nicht wundern, wenn sich Coda angepisst gefühlt hat.
Ah, da wird mir einiges klarer:

Ich rechne der Moderation hoch an, dass sie wenigstens verstanden haben, dass die Erwähnung von Coda keine Beleidigung ist/war - gegen den anderen User, Mr. Neugier-ich-lese-Beiträge-obwohl-ich-ignore-angekündigt-habe, war der Ton genau so wie ich ihn wollte. Coda hat's sicherlich drauf, genau deswegen habe ich nie verstanden warum von ihm geposteter Code so aussieht. Ging etwas in die Hose,

Das Bild ist Hintergrundbild der Website der nightly build machine... X-D

@Monger: man kann convetions auch vllt im weitesten Sinne sehen. Wenn du dir den Mund fusslig redest, weil die Leute es halt gerne so machen wie sie es schon immer gemacht haben, dann aber wiederum nicht einsehen warum es jetzt ausgerechnet an ihnen liegen soll, dass das Puzzle eben nicht mehr geht.

pest
2010-02-13, 18:07:13
dich haben die letzten 10 jahre vorm rechner wohl total verstrahlt?
nochmal kurz zur erinnerung

du motzt über coda,
ich mache ein lustiges statement, damit er es nicht so übel nimmt
du beleidigst mich
ich setzte dich auf meine ignore

das wort "neugierig " passt auch nur jetzt, weil ich ab post #29 deinen schmarrn nichtmehr lesen wollte, und es nun doch, ausgeloggt, getan habe

eol

noid
2010-02-13, 18:16:01
dich haben die letzten 10 jahre vorm rechner wohl total verstrahlt?
nochmal kurz zur erinnerung

du motzt über coda,
ich mache ein lustiges statement, damit er es nicht so übel nimmt
du beleidigst mich
ich setzte dich auf meine ignore

das wort "neugierig " passt auch nur jetzt, weil ich ab post #29 deinen schmarrn nichtmehr lesen wollte, und es nun doch, ausgeloggt, getan habe

eol

Der Simple Blindtest (achtung, nur ein Test): irgendwie sind lustige Ossis wohl schon vorm Mauerfall ausgestorben. Ich hab nichtmal nen Strahlenmonitor mehr - seit 10Jahren.

(wie wäre es einfach das Getippe zu lassen, wenn du den letzten Beitrag schon wieder nicht verstanden hast? Ignore geht auch im Kopf, aber den letzten Beitrag scheinst du dir ja aus Ego Gründen sichern zu wollen. Also mal gespannt ob gleich wieder was kommt, mit Ausrede, oder ob du dich endlich mal an das EOL hälst)

Sephiroth
2010-02-13, 18:31:28
Da man über Geschmack so vortrefflich streiten kann, wie der Verlauf dieses Threads wiedermal beweist, möchte ich euch ans Herz legen wieder auf das ursprüngliche Thema zurückzukommen und/oder das Thema Code-Style zu (hier) begraben. Ihr könnt gerne sachlich argumentativ in einem Thread darüber diskutieren aber nicht hier!

Letzte Warnung!

DraconiX
2010-02-13, 19:04:14
Das wollte ich eigentlich garnicht :( Das sich alle streiten wegen mir :D

Aaaalsooo, wenn ich mit folgendem Code die Daten in dem Array prüfe:


for(i=0;i<32;i++)
{
if((test >> i) & 1)
UART1_Write_Text("1");
else
UART1_Write_Text("0");

}

UART1_Write_Text("ENDSeq 1");


Dann kommt ja, wie vermutet, ein hoher Rechenaufwand auf mich zu - denn das Register wird ja erst 31 Stellen nach rechts geschoben und dann bei der nächsten Schleife um 30 und so weiter... kann man eigentlich mit ner Maske umgehen so das nur noch ein bit verschoben wird.:


mask = 0x00000008;
for(i=0;i<32;i++)
{
if(test & mask)
UART1_Write_Text("1");
else
UART1_Write_Text("0");

mask <<= 1;
}


Damit wird nur noch ein Bit der Maske je Schleifendurchgang verschoben und mit test verglichen, aber er unterschlägt mir da was... den die Ausgabe sieht folgendermaßen aus:


00011001000000000101010100000000 ENDSeq 1 <-- Ohne Maske
11001000000000101010100000000000 ENDSeq 2 <-- Mit Maske

00011001000000000101011000000000 ENDSeq 1 <-- Ohne Maske
11001000000000101011000000000000 ENDSeq 2 <-- Mit Maske


Wie man sieht unterschlägt er mir genau 3bit... Warum? Kann mir das wer erklären?!

noid
2010-02-13, 19:08:54
Maske mit 0x8 initialisert ist 2ˆ3 (ersten 3 bit)?

Hast du die Ausgabe der Listings mal anschaut, dein Compiler könnte/sollte so schlau sein um das selbst zu erkennen.

Dann bin ich halt der Coding-Nazi:
mask = 0x00000008;
for(i = 0; i < 32; i++)
{
if (test & mask)
{
UART1_Write_Text("1");
}
else
{
UART1_Write_Text("0");
//hier kann man jetzt wunderbar weiteren Code unterbringen ohne, dass der compiler diese Anweisung immer ausführt, weil nicht im if-else drin.
}

mask <<= 1;
}

DraconiX
2010-02-13, 19:12:18
Maske ist mit 0x8 initialiesiert.:

unsigned long mask = 0x80000000;


Ey... ASM :freak:

;24Bit Nixie.c,195 :: for(i=0;i<32;i++)
LDI 27, 0
STD Y+2, 27
STD Y+3, 27
L_main68:
LDD 16, Y+2
LDD 17, Y+3
CPI 17, 0
BRNE L__main188
CPI 16, 32
L__main188:
BRLO L__main189
JMP L_main69
L__main189:
;24Bit Nixie.c,197 :: if((test >> i) & 1)
LDS 16, _test+0
LDS 17, _test+1
LDS 18, _test+2
LDS 19, _test+3
LDD 27, Y+2
TST 27
BREQ L__main191
L__main190:
LSR 19
ROR 18
ROR 17
ROR 16
DEC 27
BRNE L__main190
L__main191:
SBRS 16, 0
JMP L_main71
;24Bit Nixie.c,198 :: UART1_Write_Text("1");
LDI 27, 49
STD Y+6, 27
LDI 27, 0
STD Y+7, 27
MOVW 16, 28
SUBI 16, 250
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
JMP L_main72
L_main71:
;24Bit Nixie.c,200 :: UART1_Write_Text("0");
LDI 27, 48
STD Y+8, 27
LDI 27, 0
STD Y+9, 27
MOVW 16, 28
SUBI 16, 248
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
L_main72:
;24Bit Nixie.c,195 :: for(i=0;i<32;i++)
LDD 16, Y+2
LDD 17, Y+3
SUBI 16, 255
SBCI 17, 255
STD Y+2, 16
STD Y+3, 17
;24Bit Nixie.c,202 :: }
JMP L_main68
L_main69:
;24Bit Nixie.c,204 :: UART1_Write_Text("ENDSeq 1");
LDI 30, ?ICS?lstr5_24Bit_32Nixie+0
LDI 31, hi_addr(?ICS?lstr5_24Bit_32Nixie+0)
MOVW 26, 28
ADIW 26, 10
LDI 24, 9
LDI 25, 0
CALL ___CC2DW+0
MOVW 16, 28
SUBI 16, 246
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
;24Bit Nixie.c,206 :: mask = 0x000000008;
LDI 27, 8
STS _mask+0, 27
LDI 27, 0
STS _mask+1, 27
STS _mask+2, 27
STS _mask+3, 27
;24Bit Nixie.c,207 :: for(i=0;i<32;i++)
LDI 27, 0
STD Y+2, 27
STD Y+3, 27
L_main73:
LDD 16, Y+2
LDD 17, Y+3
CPI 17, 0
BRNE L__main192
CPI 16, 32
L__main192:
BRLO L__main193
JMP L_main74
L__main193:
;24Bit Nixie.c,209 :: if(test & mask)
LDS 20, _test+0
LDS 21, _test+1
LDS 22, _test+2
LDS 23, _test+3
LDS 16, _mask+0
LDS 17, _mask+1
LDS 18, _mask+2
LDS 19, _mask+3
AND 16, 20
AND 17, 21
AND 18, 22
AND 19, 23
MOV 27, 16
OR 27, 17
OR 27, 18
OR 27, 19
BRNE L__main194
JMP L_main76
L__main194:
;24Bit Nixie.c,210 :: UART1_Write_Text("1");
LDI 27, 49
STD Y+19, 27
LDI 27, 0
STD Y+20, 27
MOVW 16, 28
SUBI 16, 237
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
JMP L_main77
L_main76:
;24Bit Nixie.c,212 :: UART1_Write_Text("0");
LDI 27, 48
STD Y+21, 27
LDI 27, 0
STD Y+22, 27
MOVW 16, 28
SUBI 16, 235
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
L_main77:
;24Bit Nixie.c,214 :: mask <<= 1;
LDS 16, _mask+0
LDS 17, _mask+1
LDS 18, _mask+2
LDS 19, _mask+3
LSL 16
ROL 17
ROL 18
ROL 19
STS _mask+0, 16
STS _mask+1, 17
STS _mask+2, 18
STS _mask+3, 19
;24Bit Nixie.c,207 :: for(i=0;i<32;i++)
LDD 16, Y+2
LDD 17, Y+3
SUBI 16, 255
SBCI 17, 255
STD Y+2, 16
STD Y+3, 17
;24Bit Nixie.c,215 :: }
JMP L_main73
L_main74:
;24Bit Nixie.c,217 :: UART1_Write_Text("ENDSeq 2");
LDI 30, ?ICS?lstr8_24Bit_32Nixie+0
LDI 31, hi_addr(?ICS?lstr8_24Bit_32Nixie+0)
MOVW 26, 28
ADIW 26, 23
LDI 24, 9
LDI 25, 0
CALL ___CC2DW+0
MOVW 16, 28
SUBI 16, 233
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27

noid
2010-02-13, 19:21:07
ähm, die Maske müsste mit 1 initialisiert werden, meinte ich.

Und jetzt vergleichen wir das mit dem ASM der nicht-Mask variante, dann vergleichen wir das mit dem char-array, der hatte ja nur 8bit-Variablen - und der Zugriff sowie die Operationen auf 8bit-Felder könnte dann beim AVR schneller sein.

bitoperationen sind eben eher ne Platzsparende Geschichte. Trade-off size/speed. Beides zugleich geht selten, wurde hier ja schon erwähnt.

DraconiX
2010-02-13, 19:35:14
Hmmm... so sieht der Assembly des Char-Array aus:

C Code:

for(i=0;i<32;i++)
{
if(dcf_bitmask[i] == 1)
UART1_Write_Text("1");
else
UART1_Write_Text("0");

}


ASM:

L_main74:
;24Bit Nixie.c,218 :: for(i=0;i<32;i++)
LDI 27, 0
STD Y+2, 27
STD Y+3, 27
L_main78:
LDD 16, Y+2
LDD 17, Y+3
CPI 17, 0
BRNE L__main200
CPI 16, 32
L__main200:
BRLO L__main201
JMP L_main79
L__main201:
;24Bit Nixie.c,220 :: if(dcf_bitmask[i] == 1)
LDI 18, _dcf_bitmask+0
LDI 19, hi_addr(_dcf_bitmask+0)
LDD 16, Y+2
LDD 17, Y+3
MOVW 30, 16
ADD 30, 18
ADC 31, 19
LD 16, Z
CPI 16, 1
BREQ L__main202
JMP L_main81
L__main202:
;24Bit Nixie.c,221 :: UART1_Write_Text("1");
LDI 27, 49
STD Y+24, 27
LDI 27, 0
STD Y+25, 27
MOVW 16, 28
SUBI 16, 232
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27
JMP L_main82
L_main81:
;24Bit Nixie.c,223 :: UART1_Write_Text("0");
LDI 27, 48
STD Y+26, 27
LDI 27, 0
STD Y+27, 27
MOVW 16, 28
SUBI 16, 230
SBCI 17, 255
PUSH 17
PUSH 16
CALL _UART1_Write_Text+0
IN 26, 93
IN 27, 94
ADIW 26, 2
OUT 93, 26
OUT 94, 27

DraconiX
2010-02-13, 19:40:20
Mir ist gerade aufgefallen: wenn ich nun nach links statts nach rechts shifte, die Maske, dann stimmt die Bitposition wieder, nur leider spiegelverkehrt :/ Das kann ich so leider nicht zum Schieberegister schicken :/


mask = 0x80000000;
for(i=0;i<32;i++)
{
if(test & mask)
UART1_Write_Text("1");
else
UART1_Write_Text("0");

mask >>= 1;
}



00000000000000000001001100000000 ENDSeq 1 <-- Ohne Maske
00000000110010000000000000000000 ENDSeq 2 <-- Mit Maske



Gibt es eine einfache Möglichkeit das ganze Register vorher zu spiegeln?!

noid
2010-02-13, 19:50:09
edit: äh?
Warum nicht mask = 1, und links schieben?

DraconiX
2010-02-13, 19:53:58
edit: äh?
Warum nicht mask = 1, und links schieben?

Achja... mit "unsigned long mask = 1;" ist das gleiche Ergebniss wie mit 0x8...



00000000000000000000011000000000 ENDSeq 1
00000000000000000011000000000000 ENDSeq 2



EDIT:

Soooo also mit:



mask = 1;
for(i=0;i<32;i++)
{
if(test & mask)
UART1_Write_Text("1");
else
UART1_Write_Text("0");

mask <<= 1;
}



funktioniert es dann auch wirklich... wie kommt das?! 0x8 ist doch aber eins oder?!



00000000000000000000100100000000 ENDSeq1
00000000000000000000100100000000 ENDSeq2

noid
2010-02-13, 20:05:25
hexdezimal 0x8 ist 100b, entspricht somit 2ˆ3 und ist damit auch dezimal 8. Das war auch meine erste Idee. ;)

DraconiX
2010-02-13, 20:08:51
Hmmm.. na gut :D Also ich seh den Rechner vor lauter nullen und einsen nicht mehr, schreibe gerade mal ein kleines Tool zum ausmessen der benötigten Rechenzeit des ATmega's für die einzelnen Versionen (Char-Array, Bit-Array, Bit Array mit Maske) bin mal gespannt wie es sich macht....

noid
2010-02-13, 20:15:47
Hmmm.. na gut :D Also ich seh den Rechner vor lauter nullen und einsen nicht mehr, schreibe gerade mal ein kleines Tool zum ausmessen der benötigten Rechenzeit des ATmega's für die einzelnen Versionen (Char-Array, Bit-Array, Bit Array mit Maske) bin mal gespannt wie es sich macht....

Aus dem ASM-Code und der Theorie würde ich mal ein "char-array gewinnt bei Geschw, braucht aber mehr RAM" ohne Gewähr herausrotzen.

Solltest du ein altes Oszi haben, dann wäre messen über Pins am schnellsten realisiert. So mach ich das, wenn ich timer-basierte CPU Lastmessungen testen will, oder denen (noch) nicht traue. :freak:

DraconiX
2010-03-17, 12:08:25
*hochheb*


So bin nun wieder an einer kleinen Aufgabe die in diesem Bereich fällt...:


void WriteDS75(unsigned short WTR)
{
unsigned short i;
unsigned short mask = 1;

setWRITE();
SDA = 1; mdelay; SCL = 1; mdelay; SDA = 0; mdelay;

//WTR = 0xF9;

for(i=0;i<8;i++)
{
SCL = 0;
if(WTR & mask) SDA = 1; else SDA = 0;
SCL = 1;
mask <<= 1;
}
}


Sooo ich möchte damit einen DS75 Sensor beschreiben, mein Problem jedoch ist das die Startsequenz in Bitfolge so aussieht: 1001 1111 was bei mir, nach Adam Riese, einen HexWert von 9F ergibt. Jedoch ließt er ihn ja nun falsch herum ein. Mit F9 (also 1111 1001) klappt das jedoch wunderbar. Was kann ich tun?!

noid
2010-03-17, 12:27:03
*hochheb*


So bin nun wieder an einer kleinen Aufgabe die in diesem Bereich fällt...:


void WriteDS75(unsigned short WTR)
{
unsigned short i;
unsigned short mask = 1;

setWRITE();
SDA = 1; mdelay; SCL = 1; mdelay; SDA = 0; mdelay;

//WTR = 0xF9;

for(i=0;i<8;i++)
{
SCL = 0;
if(WTR & mask) SDA = 1; else SDA = 0;
SCL = 1;
mask <<= 1;
}
}


Sooo ich möchte damit einen DS75 Sensor beschreiben, mein Problem jedoch ist das die Startsequenz in Bitfolge so aussieht: 1001 1111 was bei mir, nach Adam Riese, einen HexWert von 9F ergibt. Jedoch ließt er ihn ja nun falsch herum ein. Mit F9 (also 1111 1001) klappt das jedoch wunderbar. Was kann ich tun?!

Deine Maske bewegt sich auch von bit 2^0 bis 2^7. Würde dir empfehlen mal das ganze auf Papier mit zeitachse aufzuschreiben und deinen Code im Kopf mal abzuarbeiten.
Weil ich muss schon sagen, dass deine Fehler quasi immer aus der gleichen Quelle stammen.

Gast
2010-12-17, 21:03:51
Hallo Leute, ich habe ein ähnliches Problem. Es soll ein serieller Datenstrom von ca. 68Bits in ein Array eingelesen werden. Die Daten stehen immer in einem Flag (1oder0) zur verfügung. Ich dachte dabei an eine Möglichkeit dieses Bit, ähnllich wie bei einem Schieberegister , in das Array zu schieben.
Wie kann ich ein solches Konstrukt in C erstellen. Kann mir da jemand einen Tip ggeben.
Herzlichen Dank im vorraus.