STM32L412 - Pin toggeling zeigt unterschiedliche Umschaltzeiten?

OP #5955358
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
  }
Angehängte Dateien:
Gast #5955497
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.
Gast #5955499
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)
Gast #5955654
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren