Forum: Mikrocontroller und Digitale Elektronik Schnellere Interrupts


von Steffen Fuchs (Gast)


Lesenswert?

Hallo zusammen,

ich verwende den ATMega328P, SPI läuft über Interrupt im Slave-Modus, 
ich muss aber auch eine Software-PWM mit Timer 1 machen, die 
zeitkritisch ist.

Dazu habe ich diese Fragen:

Bei
1
    reti
werden Interrupts ja wieder aktiviert. Würde bei anliegendem Interrupt 
dann trotzdem noch ein Befehl des Hauptprogramms ausgeführt, bevor der 
nächste Interrupt kommt?

Wenn das so ist: Zu
1
    sei
habe ich gelesen, dass da der unmittelbar folgende Befehl noch vor einem 
eventuellen Interrupt ausgeführt wird. Könnte man dann den Interrupt mit
1
    sei
2
    ret
 beenden?
Dann würde man zwar einen Takt für sei einbüßen, aber man spart die bis 
zu 4 Takte dauernde Beendigung des nächsten Hauptprogramm-Befehls ein, 
und die zuverlässige Beendigung der ISR ist trotzdem noch gewahrt, da 
ret der unmittelbar auf sei folgende Befehl ist.

Ist das so oder habe ich dabei einen Denkfehler?

Meine zweite Frage ist: Ich habe beim Atmega 2 Words Platz in der 
Interrupttabelle. Kann man da auch beliebige Befehle unterbringen, z.B. 
das hier anstelle des üblichen jmp, rjmp oder reti:
1
    ldi r16,0xDA
2
    reti

Vielen Dank schon mal!

von Karl M. (Gast)


Lesenswert?

Hallo Steffen,

ich würde so, wie du es gerade vorhast, nicht "kämpfen".

Das SPI und I2C dir bekannt sind, kann man einen weiteren Slave AVR µC 
für die PWM Erzeugung an den Master anbinden.

Dadurch die Hardware nicht mehr dein Problem und das Schreiben der 
Software auch, in meinen Augen, viel einfacher.

von S. Landolt (Gast)


Lesenswert?

Alle Fragen sind zu bejahen.
Aber, um den Begriff des Vorredners aufzugreifen, könnte es sein, dass 
Sie an der falschen Front kämpfen? Geht nicht auch Hardware-PWM oder ein 
höherer Takt? Oder ein Umgestalten der Software, dazu müsste man aber 
mehr wissen.

von Steffen Fuchs (Gast)


Lesenswert?

Vielen Dank erstmal für alle Antworten, das hilft mir weiter!

PWM nur in Hardware ist etwas schwierig, weil ich eine Vollbrücke mit 
vier Schaltzuständen mit variabler Frequenz und Einschaltdauer habe. Der 
Chip läuft zur Zeit mit 16 MHz, daraus werden in der endgültigen Version 
dann sicher noch die maximalen 20 MHz.

An einen separaten µC hatte ich auch schon gedacht, aber so viel hat er 
außer der Software-PWM auch nicht zu tun:
- der SPI wird nicht mehr als 50 Byte/s übertragen
- immer wenn Zeit ist werden Spannung und Strom aus je einem externen 
A/D-Wandler ausgelesen, 100 Mal in der Sekunde reichen dafür auch, in 
der Praxis wird eher 500x pro Sekunde erreicht (dass es so langsam ist 
liegt an recht einfachen Optokopplern dazwischen, aber ich brauche auch 
nicht mehr)

Was ich erreichen will ist vor allem eine recht kleine minimale 
Einschaltdauer der PWM, die ich jetzt auf 18 Takte gebracht habe, d.h. 
knapp 1 µs bei 20 MHz, davon nimmt der MOSFET-Treiber nochmal 500 ns zur 
Sicherheit weg. Die 18 Takte sind die Zeit zwischen dem Setzen der Ports 
in der ersten (Einschalten) und in der zweiten ISR (Ausschalten).

Ich hatte aber durch den Hinweis auf den separaten µC noch die Idee, bei 
kleiner Einschaltdauer auf die zweite ISR zu verzichten, und in der 
ersten einfach nacheinander ein- und gleich wieder auszuschalten - damit 
komme ich dann auf einen einzigen Takt Mindesteinschaltdauer.

von Sascha_ (Gast)


Lesenswert?

Steffen Fuchs schrieb:
> Vielen Dank erstmal für alle Antworten, das hilft mir weiter!
>
> PWM nur in Hardware ist etwas schwierig, weil ich eine Vollbrücke mit
> vier Schaltzuständen mit variabler Frequenz und Einschaltdauer habe.

Attiny26 würde sich da anbieten, kann das in Hardware.

von Peter D. (peda)


Lesenswert?

Steffen Fuchs schrieb:
> SPI läuft über Interrupt im Slave-Modus

SPI-Slave ist bei den AVRs einfach nur krank.
Wenn Du nur 50Byte/s übertragen mußt, könnte der Master ja nach jedem 
Byte 1ms warten. Dann hast Du Zeit, das SPI in der Mainloop zu pollen 
und brauchst keinen Interrupt, der Dir die SW-PWM zerkloppt.

Alternativ wäre auch I2C oder UART. Die UART hat einen 3 Byte Puffer und 
das I2C ist selbst synchronisierend, d.h. verzögert den Master per 
Clock-Stretching. Beides ist also lange nicht so zeitkritisch, wie das 
SPI.

von A. S. (Gast)


Lesenswert?

Steffen Fuchs schrieb:
> PWM nur in Hardware ist etwas schwierig, weil ich eine Vollbrücke mit
> vier Schaltzuständen mit variabler Frequenz und Einschaltdauer habe.

Was genau ist Dein Problem bei den HW-PWMs?

Falls Du nur eine weitere PWM brauchst, bietet sich vielleicht auch der 
zweite SPI an (also per Datenbytes).

> immer wenn Zeit ist werden Spannung und Strom aus je einem externen
> A/D-Wandler ausgelesen, 100 Mal in der Sekunde reichen dafür auch, in
> der Praxis wird eher 500x pro Sekunde erreicht

in den meisten Fällen ist das nicht gut. Meist ist hier ein Synchrones 
Design besser.


> davon nimmt der MOSFET-Treiber nochmal 500 ns zur Sicherheit weg.
?? Meinst Du damit, er schaltet 500ns mehr verzögert ein als aus?

> Ich hatte aber durch den Hinweis auf den separaten µC noch die Idee, bei
> kleiner Einschaltdauer auf die zweite ISR zu verzichten

Das ist in jedem Fall vorzuziehen. Auch bei großer Einschaltdauer 
(~99%).

Für nähere Tipps wäre es wichtig zu wissen, welche Periodendauer Dein 
PWM hat und welche Baudrate Dein Slave-SPI. Wenn Du die Slave-SPI z.B. 
auf 1kHz reduzieren kannst (reicht ja für die Datenmenge), dann kommt 
vielleicht auch ein rein synchrones Design in Frage.

von Steffen Fuchs (Gast)


Lesenswert?

Vielen Dank an alle für die Antworten!

Ich nehme für die PWM den Timer 1 mit 16 Bit. Der Pin 16 an meinem PDIP, 
der als OC1B auch die PWM ausgeben könnte, ist durch den SPI belegt, 
aber mit den 8-Bit-Timern komme ich nicht hin, wenn ich Frequenz und 
Pulsbreite variabel brauche, da dann bei hoher Frequenz die Pulsbreite 
sehr ungenau wird.

Mit dem SPI-Interrupt habe ich auch kein Problem. Das Erste was ich tue 
ist Interrupts wieder zuzulassen, so dass die PWM weiterläuft. Dass ich 
ein Stack-Problem bekomme ist auch ausgeschlossen, zum einen weil der 
Master nur eine kleine Datenrate sendet, zum anderen habe ich noch eine 
Routine die bei einem evtl. doch vorkommenden zweiten Aufruf nur eine 
kurze Fehlerinformation zurücksendet und sofort wieder aussteigt.

Die Kommunikation mit SPI funktioniert auch einwandfrei, daher würde ich 
es jetzt auch nicht ändern wollen.

Bezüglich der Verzögerung durch den MOSFET-Treiber ist es genau wie 
vermutet dass aus- und erst nach 500 ns der andere Transistor 
eingeschaltet wird.

Spannungs- und Strommessung ist recht unkritisch weil sich der Strom 
nicht schneller als innerhalb von ca. 100 ms und die Spannung im Bereich 
einiger Sekunden nennenswert ändert - deshalb messe ich sie nur wenn ich 
sonst nichts zu tun habe.

Die PWM geht bis max. ca. 60 kHz, das sind bei 16 MHz Takt 267 
Taktzyklen, innerhalb derer ich normalerweise 4 Interrupts auslöse, 
deren Gesamtlaufzeit inkl. Overhead bei ca. 120 Takten liegt. Die 
restliche Hälfte der Laufzeit bleibt für die 50 Byte/s SPI und die 
Messungen reicht.

Die SPI-Routine hat auch nicht mehr als 150 Taktzyklen, deren Interrupt 
wird max. für 40 Taktzyklen durch die PWM geblockt, die ISR ist damit 
innerhalb von max. 30-50 µs nach Auftreten des Interrupts abgearbeitet. 
Das nächste Byte kommt frühestens nach 1,5 ms an, der SPI-Takt liegt bei 
ca. 5 kHz.

Vielen Dank auch für den Tip, auch bei hohen Tastzyklen in Richtung 99% 
auf einen Interrupt zu verzichten, aber der Fall kommt nicht vor.

Viele Grüße,
Steffen

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ein Xmega könnte ebenfalls helfen, deren PWM-Module sind extrem 
wandlungsfähig und mit integriertem Totzeitgenerator auch ziemlich 
"endstufenfreundlich".

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.