hallo mir stellt sich folgendes problem: ich benutze einen ds89c420 "8051" und einen c-compiler. nun habe ich eine variable unsigned char command=0xCC; und möchte die variable bit-weise auf dem port pin P2_B2 ausgeben. ich möchte das ganze jedoch in c-programmieren und nicht in asm. kann mir jemand vieleicht ein kurzes bsp geben wie ich das programieren kann? besten dank tobias
unsigned char Mask = 0x01; do { P2_B2 = (unsigned char)Value & Mask?0:1; } while (Mask <<= 1);
Hallo Sascha, war wohl ein bischen spät(früh?) heute morgen. unsigned char Mask = 0x01; do { P2_B2 = (unsigned char)Value & Mask?1:0; // ! } while (Mask <<= 1); Hochachtung.Ich muß sagen: Superlösung! Grüße Oliver
danke kannst du mir vieleicht noch kurz erklären wie das funktioniert? gruss tobias
Hallo tobias Die Lösung von Sascha ist schon der Hammer. Aber als Anfänger braucht man erstmal 2 Stunden, um den Code nachzuvollziehen. Also grundsätzlich muß man immer ein Bit abfragen, ob es gesetzt ist oder nicht. Dann kann man entsprechen reagieren. Hier ein Beispiel, was vielleicht besser zu verstehen ist: #define sda_high sbi(i2c_DataOut,sda) #define sda_low cbi(i2c_DataOut,sda) for (j=0;j<=7;j++) //Schleife zum ausgeben der 8 Bits { if(daten & 0x80) // MSB von data = 1 { sda_high; //dann eine 1 schreiben } else //ansonsten eine 0 schreiben { sda_low; //dann eine 0 schreiben } daten<<=1; // Daten eine Stelle nach links schieben, um nächste Bit einzustellen. } if(daten & 0x80) maskiert die Variable daten mit &B1000 0000 , womit nur das MSB zum tragen kommt. Also gibt die Routinen erst das MSB aus. MFG Dieter
sehr elegant, danke werde das mal versuchen zu implementieren. gruss tobias
das mit dem ausmaskieren und dem links shiften verstehe ich jetzt. mit der define anweisung habe ich jedoch noch meine mühe. könnte ich das auch so programieren: for(j=0;j<=7;j++) { if(daten&0x80) P2_B2=1; else P2_B2=0; daten<<=1; } gruss tobias
Hallo Das mit den Define hat den Vorteil, daß man ganz am Anfang im Programm die Port festlegen kann. Wenn man jetzt beim nächsten Programm mal andere Port braucht, braucht man sie nur einmal oben im Porgramm zu ändern. Bei deiner Lösung mußt du nachher das ganze Programm durchsuchen, und die Ports ändern. #define i2c_DataOut PORTD #define i2c_DataDir DDRD #define ic2_DataIn PIND #define sda 7 //ow Pin hier einfach den gewünschten Pin einstellen #define scl 6 //ow Pin hier einfach den gewünschten Pin einstellen #define sda_high sbi(i2c_DataOut,sda) //Zum bessern lesen des Codes #define sda_low cbi(i2c_DataOut,sda) #define scl_high sbi(i2c_DataOut,scl) #define scl_low cbi(i2c_DataOut,scl) Wenn du im Programm jetzt schreibst sda_high wird nachher folgendes eingesetzt sbi(PORTD,7) Oder bei sbi(i2c_DataDir,sda); // SDA auf Ausgang sbi(DDRD,7) Hoffe das hat etwas geholfen MFG Dieter
Hallo nochmal und Danke an Oliver für die Verbesserung, es war wohl wirklich etwas spät ;) unsigned char Mask = 0x01, Value = 0xCC; do { P2_B2 = (unsigned char)Value & Mask?1:0; } while (Mask <<= 1); Also hier die vermisste Erklärung: Value wird dem LSB voran ausgegeben, das gesetzte Bit in der Maske verschiebt sich mit jedem Durchlauf um eine Stelle nach links (0b00000001, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000, [0b00000000]), das macht "Mask <<= 1". Nach dem letzten Durchlauf, 0b10000000, wird das das Bit einfach raus geschoben und somit ist Mask = 0 und die While-Schleife wird verlassen. Will man das MSB als erstes ausgeben initialisiert man Value einach auf 0x80 und shiftet nach rechts. In der Schleife wird dein Wert (Value) mit der Maske UND-Verknüpft, ist die jeweiligen Bitstelle gesetzt so wird P2_B2 auf 1 gesetzt, andernfalls auf 0. Dazu hab ich den ?-Operator benutzt, <Bedingung>?<True-Statement>:<False-Statement>, der Cast nach "unsigned char" sorgt dafür dass es auch brav 8 Bit bleiben, man müsste evtl. mal ausprobieren ob dies überhaupt nötig ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.