www.mikrocontroller.net

Forum: Compiler & IDEs SW PWM Geschwindigkeit


Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe folgendes bei meiner SW PWM festgestellt:

wenn ich direkt über das Port (8 us) schalte funktioniert das wesentlich 
schneller als wenn ich das Port mittels übergabe über eine Variable (20 
us) schalte. Ich brauche die Geschwindigkeit und möchte aber trotzdem 
per Übergabe des Ports und Pins schalten.
Gibt es da ein Lösung für das Problem?
volatile  uint8_t     *m_x_toggle_port;
volatile  uint8_t     m_x_toggle_bit;


ISR( TIMER3_COMPB_vect )                      
{
// Auf Low setzen 
//  *m_x_toggle_port &= ~(1<<m_x_toggle_bit);   // langsam
  PORTE &= ~ (1<<MV1aufM);   //schneller
}


ISR( TIMER3_OVF_vect )
{
// Auf High setzen 
//  *m_x_toggle_port |= (1<<m_x_toggle_bit);   //langsam
  PORTE |= (1<<MV1aufM);    //schneller
}

.
.
.

m_x_toggle_port  = &PORTE;
m_x_toggle_bit  = MV1aufM;

.
.
.

start_timer();

Danke schon mal für eure Vorschläge.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> (1<<m_x_toggle_bit)

Sowas ist langsam, weil der AVR keinen Befehl für mehrfaches Schieben 
hat. Der Compiler muss also eine Schleife erzeugen, in der 
m_x_toggle_bit mal um 1 geschoben wird. Speichere in m_x_toggle_bit 
nicht die Bitnummer, sondern gleich die fertige Maske:
m_x_toggle_bit  = (1<<MV1aufM);

*m_x_toggle_port &= ~m_x_toggle_bit;

*m_x_toggle_port |= m_x_toggle_bit;

Trotzdem erzeugt das natürlich deutlich mehr Code, z.B. muss ja auch 
erstmal der Inhalt der Variablen aus dem Speicher geholt werden. Und bei 
der ISR kommt noch hinzu, dass bei der Variablen-Variante zusätzliche 
Pushs und Pops erzeugt werden müssen.

ISR ( TIMER1_OVF_vect ) {
    *m_x_toggle_port &= ~m_x_toggle_bit;
}
->
  5e:  1f 92         push  r1
  60:  0f 92         push  r0
  62:  0f b6         in  r0, 0x3f  ; 63
  64:  0f 92         push  r0
  66:  11 24         eor  r1, r1
  68:  8f 93         push  r24
  6a:  9f 93         push  r25
  6c:  ef 93         push  r30
  6e:  ff 93         push  r31
  70:  e0 91 60 00   lds  r30, 0x0060
  74:  f0 91 61 00   lds  r31, 0x0061
  78:  90 81         ld  r25, Z
  7a:  80 91 62 00   lds  r24, 0x0062
  7e:  80 95         com  r24
  80:  89 23         and  r24, r25
  82:  80 83         st  Z, r24
  84:  ff 91         pop  r31
  86:  ef 91         pop  r30
  88:  9f 91         pop  r25
  8a:  8f 91         pop  r24
  8c:  0f 90         pop  r0
  8e:  0f be         out  0x3f, r0  ; 63
  90:  0f 90         pop  r0
  92:  1f 90         pop  r1
  94:  18 95         reti

ISR ( TIMER1_OVF_vect ) {
    PORTB &= ~(1<<MV1aufM);
}
->
  5e:  1f 92         push  r1
  60:  0f 92         push  r0
  62:  0f b6         in  r0, 0x3f  ; 63
  64:  0f 92         push  r0
  66:  11 24         eor  r1, r1
  68:  c5 98         cbi  0x18, 5  ; 24
  6a:  0f 90         pop  r0
  6c:  0f be         out  0x3f, r0  ; 63
  6e:  0f 90         pop  r0
  70:  1f 90         pop  r1
  72:  18 95         reti

Die 2. Variante ließe sich sogar noch deutlich reduzieren:
ISR ( TIMER1_OVF_vect, ISR_NAKED ) {
    PORTB &= ~ (1<<MV1aufM);
    reti();
}
->
  5e:  c5 98         cbi  0x18, 5  ; 24
  60:  18 95         reti


> möchte aber trotzdem per Übergabe des Ports und Pins schalten.

Wenn du erklärst warum, könnte dir vielleicht besser geholfen werden.

Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan Ernst
Danke erstmal, das macht die Sache schon mal klarer.

>> möchte aber trotzdem per Übergabe des Ports und Pins schalten.
>
> Wenn du erklärst warum, könnte dir vielleicht besser geholfen werden.

Ich muss 3 bistabile Magnetventile ansteuern wobei jedes mal das selbe 
passieren soll, jedoch an anderen Ports u. Pins.
Ich möchte eigentlich keinen Code doppelt haben. Also wenn ich eine 
Änderung vornehmen muss soll das gleich auf alle 3 Magnetventile wirken.
Ich denke im notfall werde ich mir Makros schreiben, dann habe ich die 
Wartbarkeit die ich haben will (Code nur einmal) und das mit der 
Geschwinidgkeit sollte ich dann auch hinbekommen.

Wenn es andere Lösungen gibt bin ich auf jeden Fall interessiert.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.