Forum: Mikrocontroller und Digitale Elektronik STM32, generalisierte Pinansteuerung á la PORTA |= (1 << i)


von Mike (Gast)


Lesenswert?

Hallo,

ich fange gerade an, mich mit dem STM32 zu beschäftigen. In einem 
Projekt würde ich gerne aus einer n,m-Matrix einzelne Bits einer Spalte 
an Pins übergeben und dieses in einer Schleife abarbeiten lassen.

Beim AVR war dieses recht leicht möglich:

Bsp.:

uint8_t irgendEineMatrix [n][m] = { {1,0,0,1,1, bla.....}{0,0,0,1,1, 
foo....     ... ... } };

Ich möchte nun die Matrix entlang m ablaufen lassen und für jede Spalte 
alle n-Einträge auf eine 1 prüfen und dieses entsprechend auf einen Port 
abbilden:

for (uint8_t j=0; j<m; j++)
{
for (uint8_t i=0; i<n; i++)
{
if {irgendEineMatrix[i][j] == 1}
PORTA |= (1 << i);
else
PORTA &= ~(1 << i);
}
}

Ich versuche mich gerade CMSIS-konform und da gibt es für solche 
Ausgaben den Struktureintrag:

GPIO_SetBits(GPIOx, i);

So scheint das jedenfalls nicht zu funktionieren.

Hat einer von euch einen Hinweis für mich?

Mit Gruß

Mike

P.S. Ja, die Clock-Source ist aktiv und der Pin als Ausgang (Out-PP) 
konfiguriert. Eine Ausgabe auf einen festen Pin z.B. GPIO_Pin_8 
funktioniert.

von Mike (Gast)


Lesenswert?

Die if-Zeile benötigt natürlich runde Klammern...

von Mike (Gast)


Lesenswert?

Manchmal ist es einfach:

Habe die defines der GPIO_Pin_x gefunden. Auch hier hilft ein Shift 
weiter :)

Vielen Dank

von web (Gast)


Lesenswert?

gibt die einzeiler:
1
  GPIOB->BSRR|= GPIO_Pin_4;  // set
2
3
  GPIOB->BRR |= GPIO_Pin_4;  // clear
4
5
  
6
  if( GPIOB->IDR & GPIO_Pin_5  ){  // get
7
  }

das BSRR  oder BRR ging auch mit löschen ...
also wäre man bei einem register und bitmanipulation

von Kurt H. (Firma: KHTronik) (kurtharders)


Lesenswert?

Hallo Mike,

ich machs mal mut CUBE :-):
1
uint8_t irgendEineMatrix [n][m] = { {1,0,0,1,1, bla.....}{0,0,0,1,1, foo....     ... ... } };
2
3
// Pins für die Bits (auch in mehreren Ports)
4
uint16_t pins[][] = { {GPIO_PIN_0, GPIO_PIN_1, ...}, {...}, ... };
5
// Ports für die Pins
6
uint16_t ports = { {GPIOA, GPIOB, ...}, {...}, ...};
7
8
for (uint8_t j=0; j<m; j++) {
9
  for (uint8_t i=0; i<n; i++) {
10
    HAL_GPIO_writePin(ports[i][j], pins[i][j],
11
       irgendEineMatrix[i][j] == 1 ? GPIO_PIN_SET : PIO_PIN_RESET);
12
    }
13
  }
14
}
Und, am Rande, zum Thema CUBE/HAL: ich habe auch gut Zeit gebraucht, 
mich in diese Umgebung einzuarbeiten. Nachdem die Integration in eclipse 
läuft schätze ich aber das Tool für Pinout uns Setup sehr. Ausserdem ist 
die Dokumentation auf dem Weg zu besserer Qualität.

Grüße, Kurt

von Little B. (lil-b)


Lesenswert?

Ich verwende auch immer die Einzeiler und greife direkt auf hardware 
register zu, ist deutlich effizienter als diese CMSIS.
(ich hab da mal reingeschaut, optimierter code sieht GANZ anders aus!)
1
GPIOx->BSRRH = 1<<i;   // pin auf low
2
GPIOx->BSRRL = 1<<i;   // pin auf high

Lies hierzu das entsprechende Headerfile und das reference manual

von Kurt H. (Firma: KHTronik) (kurtharders)


Lesenswert?

Hallo,
Optimierung unterliegt stregen Regeln:

Erst einmal messen!

don't do it
don't do it yet
find a better algorithm

:-)

Die Einzeiler könnte man unter Regel 3 einordnen, aber spätestens wenn 
man die Beziehung Datenbit <-> Bitposition nicht mehr direkt auf das 
Register abbilden will/kann, sollte man abstrakter programmieren.

Der Vorteil der Verwendung von HAL liegt in einer größeren Allgemeinheit 
des Codes und in der Unterstützung durch das CUBE-Tool.

Nach nunmehr >40 Jahren von Assembler bis Java traue halte ich in vielen 
Fällen Optimierung für einen Popanz. Dies besonders dann, wenn nicht 
vorher der Engpass klar bestimmt wird.

Grüße, Kurt

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.