Forum: Mikrocontroller und Digitale Elektronik STM32F4 Discovery. Wie kann ich den GPIO_ReadInputDataBit beschleunigen


von Basti E. (basti_z84)


Lesenswert?

Hallo,
Ich bin Anfänger mit dem STM32 und arbeite gerade an einem Projekt in 
dem ich ein 2,4 MHz Signal auf logisch 1 und 0 abtasten muss.
Meine erste Idee war es einen Timer-Interrupt alle 2,4 MHz zu 
konfigurieren. In dieser sollte unter anderem das Signal mit 
GPIO_ReadInputDataBit eingelesen werden.

Mein IRQHandler:

void TIM3_IRQHandler()
{  TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

//Sendet einen Datenstring mit 2,4 MHz. Die ersten 9 Zeichen von buf
  if (buf[a]=='0')
  {GPIO_ResetBits(GPIOE,GPIO_Pin_15);
  }
  if (buf[a]=='1')
  {GPIO_SetBits(GPIOE,GPIO_Pin_15);
  }

//Liest Datenbits ein (2,4 MHz). Antwort vom gesendeten Datenstring
  if(buf[0]=='P'&& buf[1]=='R' && a > 9)
  {
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))
    {BufRead[x] = 1;
    }else
    {BufRead[x] = 0;
    }
  x++;
  }
  a++;

  // Ende von Datenstring
  if (a==44 )
  {
  //--> Timer ausschalten
  }
}



Prinzipiell funktioniert das, allerdings benötigt die Abarbeitung der 
Interruptroutine länger als 1/2400000 Sekunden.
Kann man das Einlesen auf irgend eine weise beschleunigen? -->Compiler 
ist schon auf Opitmizate Most(-03)eingestellt.

von Little B. (lil-b)


Lesenswert?

man kann das beschleunigen, indem man statt
1
GPIO_ResetBits(GPIOE,GPIO_Pin_15);
einfach
1
GPIOE->BSRRH = 0x80
schreibt.

umgekehrt dann für
1
GPIO_SetBits(GPIOE,GPIO_Pin_15);
einfach
1
GPIOE->BSRRL = 0x80
schreiben.


und statt
1
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1);
schreibt man
1
GPIOA->IDR & 0x02

Ich war nie ein Fan der STM Libraries. Zu ineffizient.

von Basti E. (basti_z84)


Lesenswert?

Ist jetzt scho schneller, allerdings reicht es immer noch nicht aus. 
Gibt es noch eine Schraube an der man drehen kann?

von Stefan K. (stefan64)


Lesenswert?

Ja, lass den Interrupt weg und mache das per DMA. Einen DMA für den 
Output und einen für den Input.

Gruß, Stefan

von Stefan K. (stefan64)


Lesenswert?

Wenn Du auf das "port bit set/reset register" GPIOx_BSRR als 32-Bit-Wert 
schreibst, dann kannst Du ein Bit gezielt setzen oder löschen.

Du kannst Dir eine Tabelle mit Setz/Lösch-32Bit-Werten bauen und die 
dann per DMA ausgeben.

Gruß, Stefan

von avr (Gast)


Lesenswert?

Little B. schrieb:
> Ich war nie ein Fan der STM Libraries. Zu ineffizient.

Dann kompiliere halt mit LTO, dann merkst du keinen Unterschied mehr.

@TO
Weißt du was ein Interrupt für einen Overhead mit sich bringt? Schau mal 
das Assemblerlisting an, um ein Gefühl dafür zu bekommen. Dazu kommen 
nochmal ~20 Takte allein für den Core. Wer Interrupts im MHz-Bereich 
nutzt, sollte genau wissen was da passiert. Bei deinem Programm lastet 
der Interrupt den ganzen Controller aus. Das eigentliche Programm kommt 
kaum noch zum Zuge. Wie Stefan schrieb, ist bei solchen Sachen 
eigentlich immer DMA die Lösung.

von Basti E. (basti_z84)


Lesenswert?

Super, vielen Dank.... Werd ich gleich mal ausprobieren

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.