Forum: Mikrocontroller und Digitale Elektronik STM32 direkter Port zugriff


von Mathias D. (darkfirefighter)


Lesenswert?

Hallo zusammen,

ich stehe gerade wieder vor einem Problem mit meinem STM32.
Ich habe ein Array mit den Werten 0 oder 1 und möchte das jetzt so 
schnell wie möglich auf einem Pin ausgeben.
Eine Möglichkeit wäre es jetzt z.b. so: (ptr ist ein Pointer auf das 
Array)
1
if(*ptr++ == 1)
2
  GPIOE->BSRR = GPIO_Pin_3;
3
else
4
  GPIOE->BRR = GPIO_Pin_3;
5
6
if(*ptr++ == 1)
7
  GPIOE->BSRR = GPIO_Pin_3;
8
else
9
  GPIOE->BRR = GPIO_Pin_3;
10
11
.
12
.
13
.
Zu gunsten der Geschwindigkeit und weil es nur 12 bit sind die gesetzt 
werden müssen würde ich es untereinander schreiben und in keiner 
Schleife.
Das Problem ist allerdings, dass auch die if-Abfrage Zeit kostet.
Gibt es eine Möglichkeit die Pins direkt anzusprechen?
Also in etwa so:
1
GPIOE->GPIO_Pin_3 = *ptr++;
Oder kann ich auch einfach auf den ganzen Port ein 16bit Wort legen, 
wobei eben nur die Bits durchkommen, wo der entsprechende Pin auch auf 
Ausgang geschlaten ist, also in etwa so:
1
GPIOE = 0x8; //0000 0000 0000 1000

Habe im Internet dazu leider nichs gefunden.
Danke für die Bemühungen :)

Gruß

von (prx) A. K. (prx)


Lesenswert?

Schau dir die Definition des BSRR mal genau an. Man kann sozusagen ein 
Bit gleichzeitig setzen und löschen, wobei setzen gewinnt. Das kann also 
auf sowas wie
  BSRR = Pin<<16 | array[i++];
rauslaufen. Ist array[..]=0 wird gelöscht, sonst gesetzt.

von the_dude (Gast)


Lesenswert?

du kannst den gesamten Port, oer nur ein Teil davon gleichzeitig 
schreiben, man muss nicht jedes Bit einzeln ansprechen!

Port komplet setzen
1
GPIOA->ODR = (GPIOA->ODR);


nur das obere Byte eines Ports setzen
1
GPIOA->ODR = ((GPIOA->ODR & 0x00FF) | (((uint16_t)datenbyte)<<8) );

von (prx) A. K. (prx)


Lesenswert?

Das ist dann allerdings die langsamste Methode überhaupt, weil auf ein 
I/O-Read gewartet werden muss. Das gleiche lässt sich mit
  GPIOA->BSRR =  0xFF00<<16 | datenbyte<<8;
deutlich flotter erledigen.

von Mathias D. (darkfirefighter)


Lesenswert?

Hallo A.K.

Danke :)
Habs jetzt so gemacht:
1
GPIOE->BSRR = (Pin3<<16) | (data[x]<<3);
Funktioniert wunderbar.

Du hast im ersten Post soetwas vorgeschlagen:
1
  BSRR = Pin<<16 | array[i++];
das läuft ja dann, wenn ich das richtig verstanden habe, aufs gleich 
raus wie ich es gemacht habe und müsste die schnellste Methode sein 
oder?

Gruß

von (prx) A. K. (prx)


Lesenswert?

Ja, so war's gemeint. Ich hatte es aber eher symbolisch formuliert.

von Mathias D. (darkfirefighter)


Lesenswert?

Ok gut dann habe ich das schon richtig verstanden.
An dieser Stelle nochmal vielen Dank an dich, für deine geduldige Hilfe 
bei meinen Fragen!

Gruß

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.