mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 direkter Port zugriff


Autor: Mathias Dubdidu (darkfirefighter)
Datum:

Bewertung
0 lesenswert
nicht 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)
if(*ptr++ == 1)
  GPIOE->BSRR = GPIO_Pin_3;
else
  GPIOE->BRR = GPIO_Pin_3;

if(*ptr++ == 1)
  GPIOE->BSRR = GPIO_Pin_3;
else
  GPIOE->BRR = GPIO_Pin_3;

.
.
.
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:
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:
GPIOE = 0x8; //0000 0000 0000 1000

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

Gruß

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: the_dude (Gast)
Datum:

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

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


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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mathias Dubdidu (darkfirefighter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo A.K.

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

Du hast im ersten Post soetwas vorgeschlagen:
  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ß

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so war's gemeint. Ich hatte es aber eher symbolisch formuliert.

Autor: Mathias Dubdidu (darkfirefighter)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.