Das Original in C
hier wird hinter dem Doppelpunkt die Anzahl der Bits angegeben:
Also z.B. 4 Bits für die Revision, da passen also die Zahlen 0..15 rein
oder PartNo belegt 12 Bits. Da passen die Zahlen 0..4095 rein
Code: Alles auswählen
typedef volatile union
{
struct
{
U32 Revision : 4; // [0..3] Revision nunber, the p value in the rnpn product revision identifier 0x0 = r2p0
U32 PartNo : 12; // Part number of the processor: 0x23 = Cortex-M3
U32 Constant : 4; // read as 0x0F
U32 Variant : 4; // Variante number, the r value ist the rnpn product revision identifier
U32 Implementer : 8; // Implementer code: 0x41 = ARM
} bits;
U32 value;
} CPUID_TypeDef;
#define LPC_CPUID (*(CPUID_TypeDef *)(0xE000ED00))
---------------------------
In Pascal sieht es etwas anders aus, hier wird angegebn welcher Wertebereich da reinpassen soll
und der Compiler kümmert sich um die Anzahl und Belegung der Bits.
Um es etwas einfacher(übersichtlicher) zu machen habe ich die Typen mit den entsprechenden Bits definiert
z.B. T6Bit was in Pascal dann bedeutet Wertebereich 0..63
Code: Alles auswählen
// Das macht es etwas übersichtlicher....
Type T1Bit = 0..1;
T2Bit = 0..3;
T3Bit = 0..7;
T4Bit = 0..15;
T5Bit = 0..31;
T6Bit = 0..63;
T7Bit = 0..127;
T8Bit = 0..255;
T9Bit = 0..511;
T10Bit = 0..1023;
T11Bit = 0..2047;
T12Bit = 0..4095;
//....usw.
// der Record sieht dann so aus:
Type CPUID_TypeDef = bitpacked record
case boolean of
true: (
Revision : T4Bit; // [0..3] Revision number, the p value in the rnpn product revision identifier 0x0 = r2p0
PartNo : T12Bit; // Part number of the processor: 0x23 = Cortex-M3
Constant : T4Bit; // read as 0x0F
Variant : T4Bit; // Variant number, the r value ist the rnpn product revision identifier
Implementer : T8Bit; // Implementer code: 0x41 = ARM
);
false : ( value:UInt32); // 32 Bit Wert
end;
// zum Testen habe ich eine Variable angelegt, sonst gibts nen Laufzeitfehler auf dem PC,
// hier darf ich ja nicht auf feste Adressen zugreifen.
var dummy:UInt32;
var LPC_CPUID : CPUID_TypeDef absolute dummy; // var LPC_CPUID : CPUID_TypeDef absolute $E000ED00;
procedure TForm1.FormCreate(Sender: TObject);
begin
LPC_CPUID.PartNo:=35;
caption:=IntToStr(SizeOf(LPC_CPUID)); // ergibt 4, es werden 4 Bytes belegt
caption:=IntToStr(LPC_CPUID.PartNo); // ergibt 35, habe ich ja gesetzt
caption:=IntToStr(LPC_CPUID.value); // ergibt 560 weil (35 viermal links (Revision hat 4 Bits) schieben = 560)
end;
Man kann auf dieses Art und Weise direkt auf den 32 Bit Wert des Registers zugreifen oder aber auch auf enzelne Bits.
Hauptanwendung sind die Prozessor/Peripherie-Register des Microcontrollers.
Das ist also ein Variantenrecord mit eizelnen Bitzugriffen