Forum: Mikrocontroller und Digitale Elektronik STM42F429 - XOR


von Michael (Gast)


Lesenswert?

Hallo Zusammen,

ich habe eine kurze Frage zu meiner blinkenden LED eines 
STM32F429Discovery:
1
#include "stm32f4xx.h"
2
#include "stm32f4xx_gpio.h"
3
#include "stm32f4xx_rcc.h"
4
5
int main(void) {
6
7
GPIO_InitTypeDef GPIO_InitDef;
8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
9
10
//Pins 13 and 14
11
GPIO_InitDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
12
//Mode output
13
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
14
//Output type push-pull
15
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
16
//Without pull resistors
17
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
18
//50MHz pin speed
19
GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz;
20
21
//Initialize pins on GPIOG port
22
GPIO_Init(GPIOG, &GPIO_InitDef);
23
24
while(1){
25
  volatile uint32_t i=5000000;
26
while(i--){}
27
    GPIOG->ODR ^= GPIO_Pin_13;
28
}
29
}

Ich verstehe nicht ganz, wie diese Zeile hier funktioniert:
    GPIOG->ODR ^= GPIO_Pin_13;
Damit blinkt die LED, aber wie funktioniert das Ganze?

Pin 13 ist wie folgt definiert:
#define GPIO_Pin_13                ((u16)0x2000)  /* Pin 13 selected */
0x2000 ist, wenn ich das richtig verstehe, das Register. Der Wert ist 
bei auisgeschalteter LED "0"
Mit einer XOR Operation wird dann Ein/Ausgeschaltet. Aber welchen Wert 
hat GPIOG->ODR dann? Ich kann die Zeile nicht ganz nachvollziehen.

von fop (Gast)


Lesenswert?

> #define GPIO_Pin_13                ((u16)0x2000)  /* Pin 13 selected */
> 0x2000 ist, wenn ich das richtig verstehe, das Register. Der Wert ist
> bei auisgeschalteter LED "0"

Nein, wohl eher falsch verstanden. Das Register heißt ODR und enthält 
vermutlich die Infos von bis zu 32 Pins. Jeweils ein Bit für einen Pin.
Ich orakle jetzt mal, da ich Deinen Mikrokontroller nicht kenne :
Bit 0 für Pin 1, Bit 1 für Pin 2... Bit 12 für Pin 13.
Der Wert von Bit 12 ist 0x2000, also wenn das Bit gesetzt ist, ist der 
Wert im Register ODR um 8192 (0x2000) höher, als wenn es nicht gesetzt 
ist. Und wie gesagt, dieses Bit beeinflußt Pin 13.
Um auf das ODR Register zuzugreifen, stellt Dir eine der von Dir 
eingebundenen Header Dateien (.h) etwas zur Verfügung, so dass Du 
GPIOG->ODR schreiben kannst. Sowohl zum Auslesen als auch zum 
Beschreiben des Registers.
Du willst aber nur mit Pin 13 blinken, die anderen sollen sich nicht 
ändern.
Also musst Du den bisherigen Zustand lesen, Bit 12 ändern und den 
Kladderadatsch zurück schreiben.
Wie also Bit 12 auf den Kopf stellen ? Hier kommt die 
Exklusiv-Oder-Verknüpfung in's Spiel. Wenn Du Dir die Wahrheitstabelle 
dazu anschaust, siehst Du, dass ein Bit, dass Du mit einer 0 ex-oder 
verknüpfst, seinen Wert behält. Ein Bit, was Du mit einer 1 ex-oder 
verknüpfst, kehrt seinen Zustand um.

schnulli ^= bulli;
in C bedeutet : Lese schnulli, verknüpfe jedes einzelne Bit davon mit 
dem entsprechenden Bit von bulli und schreibe das Ergebnis in schnulli.
Also Bit 0 von schnulli ist danach Bit 0 von schnulli vorher ex-oder 
verknüpft mit Bit 0 von bulli.
Also Bit 1 von schnulli ist danach Bit 1 von schnulli vorher ex-oder 
verknüpft mit Bit 1 von bulli.
Also Bit 2 von schnulli ist danach Bit 2 von schnulli vorher ex-oder 
verknüpft mit Bit 2 von bulli.
Und so heiter weiter.
Wir wollten nur Bit 12 umdrehen. Gut - wir brauchen also für Bulli einen 
Wert, in dem nur Bit 12 gesetzt ist.

Ich hoffe, ab hier kommst Du selber weiter...

von Christopher J. (christopher_j23)


Lesenswert?

Ich seh schon fop war schneller aber sei es drum:

Michael schrieb:
> Ich verstehe nicht ganz, wie diese Zeile hier funktioniert:
>     GPIOG->ODR ^= GPIO_Pin_13;
> Damit blinkt die LED, aber wie funktioniert das Ganze?

GPIOG->ODR ist das "Output Data Register" von GPIO Port G.

GPIO_Pin_13 ist die Bitmaske für den 13. GPIO, also in C äquivalent zu
1 << 13, bzw. als Zahl allgemein 2^13 oder als Dezimalzahl 8192 bzw. 
0x2000 als Hexadezimalzahl.

Dann hast du noch "^" als XOR-Operator und kombiniert mit dem "=" wird 
aus
1
A ^= B;

soviel wie
1
A = A ^ B;

Der XOR-Operator sorgt dafür, dass Bits "getogglet" werden, d.h. waren 
sie vorher Null werden sie zu Eins und andersherum werden sie zu Null 
wenn sie vorher eins waren.

Edit: @fop, auch bei den Pins fangen sie zumindest bei ST bei 0 an zu 
zählen, d.h. Bit 0 entspricht Pin 0 und Bit 13 entspricht Pin 13, nicht 
Bit 12.

von Michael (Gast)


Lesenswert?

Ich sehe schon,  ich habe Tomaten auf den Augen. Besten Dank für die 
ausführliche Erklärung.  Manchmal ist es doch einfacher als Gedacht ...

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
Noch kein Account? Hier anmelden.