Ich habe gerade angefangen, C (aus Java kommend) zu schreiben. Ich versuche herauszufinden, wie sich die Sprache einer Bedingung anpasst, die auf dem Namen einer Definition basiert.Bedingte Anweisungen basierend auf dem Namen von # define
z.B. Ich habe eine riesige Header-Datei, die ich nicht mit vielen Definitionen bearbeiten kann (sollte).
#define GPIO_OTYPER_OT_0 ((uint32_t)0x00000001)
#define GPIO_OTYPER_OT_1 ((uint32_t)0x00000002)
#define GPIO_OTYPER_OT_2 ((uint32_t)0x00000004)
#define GPIO_OTYPER_OT_3 ((uint32_t)0x00000008)
#define GPIO_OTYPER_OT_4 ((uint32_t)0x00000010)
#define GPIO_OTYPER_OT_5 ((uint32_t)0x00000020)
Und so weiter;
Ich möchte eine Funktion/Deklaration (oder was auch immer die Lösung ist) machen, um auf den _ # Teil der Definition zu wirken.
(Pseudo-Code)
void initialize(int X) {
GPIOA->MODER |= GPIO_MODER_MODER%X_5;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_%X;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR%X;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR5;
GPIOA->ODR |= GPIO_ODR_ODR_%X;
}
Wo% X int X
Alles, was ich denken kann, ist eine switch-Anweisung für jeden X aber X verfügt über einen großen Bereich, so dass die Quelldatei sehr groß sein würde.
bearbeiten: https://github.com/espruino/Espruino/blob/master/targetlibs/stm32f4/lib/stm32f411xe.h ist die Header-Datei.
Ich würde eine zweite Kopfzeile generieren, die den ursprünglichen (unveränderbar) Header nachahmt, aber dies ist sinnvoll. Zum Beispiel: '#define GPIO_OTYPER_OT (x) ((uint32_t) 1 << (x))' und dann vielleicht '# GPIO_OTYPER_OT_0 GPIO_OTYPER (0)' usw. definieren und Code generieren, um die Ergebnisse zu überprüfen. Dann benutze den gesunden Header, nicht den wahnsinnigen. –
Ich würde das Problem betrachten, das Sie versuchen zu lösen, um zu sehen, warum das, was Sie tun, der falsche Weg ist, es zu lösen. – stark
Korrigieren Sie mich, wenn ich falsch liege, aber 'initialize()' riecht sehr viel wie das nächste, was Sie tun würden, ist es in einer Schleife zu nennen ", um jeden GPIO-Pin zu initialisieren"; Das wäre ein eindeutiger Fall von Denken auf der falschen Ebene. Wenn Sie initialisieren, tun Sie dies auf der _port_-Ebene, d. H. 'GPIOA-> OTYPER = GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_2 | GPIO_OTYPER_OT_5; '. Eine Flut von Lese-Modifizier-Schreib-Operationen auf demselben Register ist eine vollständige Verschwendung von Zyklen. Ich vermute, dass Sie _straight_ nicht in Bit-bangende bidirektionale Protokolle oder irgendetwas anderes springen, das die Neukonfiguration von beliebigen GPIOs zur Laufzeit erfordern könnte. – Notlikethat