In Bezug auf die Register- und Bitdefinitionen des Microchip XC8-Compilers

Ich werde einen zufälligen 8-Bit-Microchip-Mikrocontroller nehmen: PIC16F887 .

Schauen wir uns an, wie der XC8-Compiler (und übrigens auch der HI-TECH PICC) ein Register (SFR) und seine entsprechenden Bits in der Header-Datei des Geräts definiert ( ) /opt/microchip/xc8/v1.31/include/pic16f887.h:

extern volatile unsigned char           PORTB               @ 0x006;

SFR ist also PORTBlaut Datenblatt als flüchtige 8-Bit-Variable mit der absoluten Adresse 0x006 definiert.

Ich habe Probleme, die Definition eines einzelnen Bits (z. B. Bit 1) zu verstehen, das PORTB entspricht:

extern volatile __bit                   RB1                 @ (((unsigned) &PORTB)*8) + 1;

Warum multiplizieren sie die PORTB-Adresse mit 8?

BEARBEITEN:

Ich habe auch im Handbuch des Compilers nach einer Erklärung gesucht und ziemlich genau die gleichen Antworten gefunden, die Spehro mir gegeben hat . Ich hätte das Handbuch konsultieren sollen, bevor ich hier frage:

Bei der Definition von absoluten Bit-Variablen (siehe Abschnitt 5.4.2.1 „Bit-Datentypen und Variablen“) muss die angegebene Adresse eine Bit-Adresse sein. Eine Bitadresse erhält man, indem man die gewünschte Byteadresse mit 8 multipliziert und dann den Bit-Offset innerhalb dieses Bits hinzufügt.

Um beispielsweise eine Bit-Variable mit dem Namen mode an Bitposition #2 bei Byte-Adresse 0x50 zu platzieren, verwenden Sie Folgendes: bit mode @ 0x282; Wenn Sie eine Bit-Variable über ein vorhandenes Objekt platzieren möchten (normalerweise ist dies eine SFR-Variable oder eine andere absolute Variable), können Sie das Symbol dieses Objekts verwenden, wie im folgenden Beispiel, das Flag an Bit-Position #3 in platziert char-Variable MOT_STATUS:

bit flag @ ((unsigned) &MOT_STATUS)*8 + 3;

@Swanand Ja, sie verwenden Unions und Strukturen, um die Bits des Registers zu definieren. Die Microchip-Compiler machen das neben den von mir erwähnten Definitionen auch.

Antworten (1)

Die Bitadressierung verwendet die unteren 3 Bits der Adresse, um auf das Bit innerhalb eines Bytes zu zeigen.

Das Bit ist also in Ihrem Beispiel die Nummer (RB1 & 0x07) oder 1, die Byteadresse ist (RB1 >> 3) oder in Ihrem Beispiel 0x06.

Ich glaube nicht, dass ich deine Erklärung verstehe. Nehmen Sie den Ausdruck aus der Bit-Definition: @ (((unsigned) &PORTB)*8) + 1;Lassen Sie uns diesen Ausdruck auswerten: &PORTB = 0x06. 0x06 * 8 = 0x30 (0b00110000). 0x30 + 1 = 0x31 (0b00110001). Wie ist 0x31 die Adresse von Bit 1 von PORTB?
Der Compiler weiß, auf welchen Typ von Objekt (Bit) die Adresse zeigt, und behandelt sie anders als eine Byte-Adresse. Versuchen Sie, den ausgegebenen Maschinencode auf sehr einfache Bit-Set/Clear-Anweisungen zu untersuchen.