Forum: Mikrocontroller und Digitale Elektronik STM32L412 - Pin toggeling zeigt unterschiedliche Umschaltzeiten?


von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

Hallo,

ich verwende einen STM32L412 Controller (Systemtakt = Takt am Bus = 
32MHz).
Wenn ich wie hier den Portpin PA4 toggeln lasse bekomme ich 
unterscheidliche ON/OFF Zeiten. Nach high - low - high Pulsen mit je 1µs 
folgt ein längerer low-Pulse mit 2,8µs.
Gibt es dafür eine Erklärung?
1
while (1)
2
  { 
3
    GPIOA->ODR |= (1 << 4);     // CS High
4
    GPIOA->ODR &= ~(1 << 4);     // CS LOW
5
    GPIOA->ODR |= (1 << 4);     // CS High
6
    GPIOA->ODR &= ~(1 << 4);     // CS LOW
7
    GPIOA->ODR |= (1 << 4);     // CS High
8
    GPIOA->ODR &= ~(1 << 4);     // CS LOW
9
    GPIOA->ODR |= (1 << 4);     // CS High
10
    GPIOA->ODR &= ~(1 << 4);     // CS LOW
11
  }

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

M. G. schrieb:
> Gibt es dafür eine Erklärung?
Wie sieht denn der aus dem C-File erzeugte Assemblercode aus?

von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

anbei der disassembly Ausschnitt...

von Potentieller Erklärbär (Gast)


Lesenswert?

M. G. schrieb:
> Gibt es dafür eine Erklärung?

GPIO und Prozessorkern laufen mit verschiedenen Takten. Bei
Ausgaben muss der Prozessorkern solange "warten" bis eine
GPIO-Taktflanke die Ausgabe ermöglich. Dieser Synchronisierungs-
machanismus ergibt (aufgrund möglicher nichtsynchroner Takte)
eine Quantisierung in Prozessortakt-Längen, mal einer mehr
mal einer weniger.

Wenn man genau genug hinschaut wird ein Systick-Interrupt auch
manchmal dazwischenfunken.

von Ingo Less (Gast)


Lesenswert?

M. G. schrieb:
> anbei der disassembly Ausschnitt...
Naja, du siehst doch das er für Setzen nur einen, für Rücksetzen jedoch 
zwei Befehle benötigt. Versuch es mal mit diesen #defines
1
#define SET_BIT(Register,Pin)    (Register->BSRR = Pin)
2
#define CLEAR_BIT(Register,Pin)    (Register->BRR = Pin)

von M. G. (ixil96)


Lesenswert?

Danke für die Hinweise!
1
      GPIOA->BSRR = (1<<4);     // set bit
2
      GPIOA->BSRR = ~(1<<4);    // clear bit

Jetzt toggelt der Pin alle 250ns :-)

von Thomas B (Gast)


Lesenswert?

M. G. schrieb:
> Danke für die Hinweise!
>      GPIOA->BSRR = (1<<4);     // set bit
>       GPIOA->BSRR = ~(1<<4);    // clear bit
>
> Jetzt toggelt der Pin alle 250ns :-)

Die untere Zeile ist nicht ganz sauber. Über das "Bit Set Reset 
Register" werden die Bits gesetzt bzw. zurückgesetzt, deren 
entsprechendes Bit du im Register setzt. Die untern 16-bit setzen die 
Pins, die oberen 16-bit setzen sie zurück.

M. G. schrieb:
>      GPIOA->BSRR = (1<<4);     // set bit

Setzt Pin4 auf high.

M. G. schrieb:
>       GPIOA->BSRR = ~(1<<4);    // clear bit

Setzt für alle Pins das Set und Reset Bit gleichzeitig, ausser für Pin 
4, für diesen wird nur Reset getzt (deshalb funktioniert es auch). 
Richtig wäre ...

>       GPIOA->BSRR = (1<< (4 + 16) );    // clear bit


Oder eben gleich über das BRR (Bit Reset Register) gehen.

von Thomas B (Gast)


Lesenswert?

Thomas B schrieb:
> [...]
> Oder eben gleich über das BRR (Bit Reset Register) gehen.

Habe gerade gesehen das es kein "BRR" Register gibt.

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.