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.
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.
Ist jetzt scho schneller, allerdings reicht es immer noch nicht aus. Gibt es noch eine Schraube an der man drehen kann?
Ja, lass den Interrupt weg und mache das per DMA. Einen DMA für den Output und einen für den Input. Gruß, Stefan
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.