-         

Ergebnis 1 bis 10 von 10

Thema: Bitfolgen in hex darstellen

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    28
    Beiträge
    324

    Bitfolgen in hex darstellen

    Anzeige

    Ich versuche grade zum 2. Mal in die AVR Programmierung mit C einzusteigen. Die Grundzüge und Kontrollstrukturen der Sprache sind mir vom Programmieren am Computer aus bekannt und stellen daher kein Problem dar. Es ist mir gelungen avr-gcc einzurichten und ich kann mit einer makefile das Programm auch direkt in den Controller flashen. Soweit Alles prima.

    Nun zu meinem eigentlichen Problem. Am AVR sind ja alle IO Pins in Ports zu je 8 Stück zusammengefasst. Aufgrund der Beschaffenheit von C kann ich nun nicht jeden Pin einzeln ansprechen, sondern ich muss eine Zahl in das entsprechende Port(-richtungs-)byte schreiben, die den Zustand aller 8 pins am Port beinhaltet. In Binär ist das kein Problem. "00000101" würde beispielsweise Pin 0 und 2 des Ports einschalten, bzw. als Ausgang definieren. Nun ist es aber verhältnismäzig umständlich diese Bitfolgen in Binär zu schreiben, bzw. es dauert einfach relativ lang. Daher benutzen viele Leute anscheinend hex. Ich bin mir darüber im klaren, wie das hexadezimalsystem funktioniert, aber ich komme nicht dahinter, was es so einfach macht Bitfolgen in hex darzustellen. Wenn ich das machen wollte müsste ich den hexwert einer Bitfolge entweder in einer Tabelle nachschlagen, oder ihn Mühevoll umrechnen. Aber dann könnte ich ja auch gleich das dezimalsystem verwenden, oder? Kann mir bitte jemand erklären, wie ich von einer (binären) Bitfolge auf einen Hexwert komme, ohne auf eine dieser Möglichkeiten zurückzugreifen? Fände ich echt klasse von euch, denn ich komme einfach nicht dahinter.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    30
    Beiträge
    1.221
    Hi,

    viele Leute nutzen nicht Hex, sondern so ein Konstrukt hier: DDRB = (1 << DDB3);
    Das bedeutet: Schiebe die eins so weit nach "links", dass sie bei DDB3 "landet".
    Willst du also dein "00000101" darstellen, kannst du folgendes verwenden:
    X = (1 << 2)|(1<<0).
    Damit wird eine eins zweimal nach links geschoben, also von 00000001 nach 000000100. Das Ergebnis wird dann mit einer eins, die nicht verschoben wird, per logischem Oder verknüpft:
    000000100
    000000001
    ------------
    000000101

    Oder du nimmst dennoch Hex und rechnest es eben aus. Jeweils vier Bits ergeben ein Zeichen, es wird durchgezählt von null bis 15, wobei die Zahlen zehn bis 15 durch die Buchstaben A bis F repräsentiert werden.
    Und ansonsten das übliche, Bit 0 entspricht 1, Bit 1 entspricht 2, Bit 3 entspricht 4, Bit 4 entspricht 8.

    mfG
    Markus

    PS: Eine besser Erklärung gibts sicher im RN-Wissen-Artikelbereich.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    26.09.2008
    Ort
    Wien
    Alter
    31
    Beiträge
    94
    Guten Abend,

    markusj hat das ja bereits prima erklärt, zur Ergänzung ein recht hilfreicher Link und ein kleines Beispiel.
    Link:
    http://www.easycalculation.com/hex-converter.php
    Dort kannst du einen HEX Wert eingeben und du siehst sofort welchen Binärwert er repräsentiert.

    Und zum Beispiel und der Umrechnung:
    Du kennst HEX ja bereits, also wirst du wissen dass man mit einer HEX Zahl 16 Zahlen, also 0 - 15 darstellen kann.
    Um dieselbe Anzahl an Zahlen im Binärsystem darstellen zu können bräuchtest du 4 Bit. (2^4 = 16)
    Ergo entsprichen 4 Bit 1 HEX.
    In Hex wird 0 - 9 durchnummeriert mit den Zahlen 0 - 9, für 10 - 15 wird, wie markusj ebenso schon gesagt hat A - F verwendet.

    Das heisst, 1111 entspricht F, 1010 entspricht A, 0111 entspricht 7.
    Wenn du demnach die Zahl 00000101 (aus deinem Thread) darstellen willst , wäre das in hex 05, oder nur 5.
    In C müsstest du dass dann mit 0x5 schreiben.

    Hoffe geholfen zu haben.
    Gruß und gn8
    while (!asleep()) sheep++;
    RP6 und Asuro Befehlsübersicht

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    wenn du denn doch umrechnen musst, der Windows-Taschenrechner kann in der wissenschaftlichen Ansicht prima hex in dez oder auch bin und umgekehrt rechnen. Wenn es Linux ist, gcalctool kann es auch.
    Ansonsten ist es halt recht praktisch das zwei Ziffern ein Byte ergeben. Erste Ziffer für die 4 höherwertigen Bits die zweite Ziffer für die 4 niederwertigen. Für das Programm ist es letztendlich egal, welches Zahlensystem du nimmst.

    Gruß

    Jens

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    28
    Beiträge
    324
    X = (1 << 2)|(1<<0)
    Und wenn ich mit einem solchen Konstrukt 7 von 8 Bits in einem Byte setzten möchte wird das ganze dann ziemlich lang, oder?

    Vielen dank an alle für die bisherigen, sehr aufschlussreichen erklärungen!

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    30
    Beiträge
    1.221
    Zitat Zitat von Barthimaeus
    X = (1 << 2)|(1<<0)
    Und wenn ich mit einem solchen Konstrukt 7 von 8 Bits in einem Byte setzten möchte wird das ganze dann ziemlich lang, oder?
    Vielen dank an alle für die bisherigen, sehr aufschlussreichen erklärungen!
    Ja, aber thats C
    Es gibt auch noch die inoffizielle Syntax mit 0b01101001, das ist aber nur in WinAVR eingepatcht und gehört nicht zum C-Standard.

    Der Vorteil besteht darin, dass du zum Bleistift bei einer Initialisierung:
    Code:
    UCSR0B = (1 << RXCIE0)|(1 << RXEN0)|(1 << TXEN0);
    Schnell siehst, welche Bits (und damit Funktionen) gesetzt werden.

    mfG
    Markus

    PS: Und wenn du sieben von acht Bits setzen willst: X = ~(1<<Nicht_Gesetztes_Bit);
    \/

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    28
    Beiträge
    324
    Code:
    #include <avr/io.h>    
     
    int main (void) {        
     
       DDRC  = 0xff;          
       PORTC = (1<<4)|(0<<3);          
     
       while(1) {                
       }                        
     
       return 0;         
    }
    Also würde folgendes Programm den gesamten Port C als Ausgang definieren und PortC.5 auf 1 und PortC.4 auf null setzten? Wenn dem so ist müsste eine LED zwischen PortC.5 und PortC.4 aufleuchten?

    Warum tut sie es bei mir nicht?

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    30
    Beiträge
    1.221
    Öhm, du solltest beim Zugriff auf die Ports/Pins die definierten Werte zu benutzen:
    PORTC = (1 << PB4);
    Nullen brauchst du nicht schieben, du hast Null und definierst die gesetzten Einsen.

    Es gibt für DDRx jeweils DDxN (N ist eine Zahl), für PINx gibt es PINxN, PORTx hat PxN definiert.

    @LED: Möglicherweise kapott? Hast du nen Vorwiderstand dabei? Richtig herum gepolt?

    mfG
    Markus

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    28
    Beiträge
    324
    Mit "PORTC = (1<<PC5);" klappt es. Aber als was ist denn PC5 definiert? Ich hätte angenommen, dass "PORTC = (1<<PC5)" "PORTC = (1<<4)" entspricht, denn wenn, man eine 1 im PORTC Byte um vier Stellen nach links verschiebt, so müsste doch das fünfte Bit gesetzt sein, oder?

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    30
    Beiträge
    1.221
    Keine Ahnung, vielleicht liegts an dem verwendeten µC. Du kannst dir die Include-Files im WinAVR-Zeichnis\avr\include\avr\io*.h
    Wobei * der entsprechende Typ ist, teilweise werden Familien auch zusammengefasst (iomx8.h für ATMega 48,88,16 werden.

    mfG
    Markus

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •