Forum: Mikrocontroller und Digitale Elektronik AVR [AtTiny404] Registeroperationen blockieren Interrupt


von Jonathan B. (icwhiner)


Angehängte Dateien:

Lesenswert?

Hallo,

Wie man aus dem Betreff schon erahnen kann ist die Grundfrage meines 
Posts: Können Registeroperationen, also ein Register lesen oder 
schreiben, Interrupts blockieren?

Damit ihr einen Überblick bekommt warum sich diese Frage für mich 
stellt, muss ich etwas ausholen und stelle kurz mein Projekt vor.

Ziel des Projekts ist es einen MPP-Tracker auf einem ATTiny404 zu 
implementieren. Dieser wurde ausgewählt, weil er unschlagbar günstig ist 
( ~0,41€ /Stück) und dabei uns trotzdem eine Schaltfrequenz von 80kHz 
für die PWM zur verfügung stellt.

Die Schaltung die verwendet wird ist ein Inverswandler 
(https://de.wikipedia.org/wiki/Inverswandler).

Ein großer Nachteil den dieser Chip hat, ist das er nicht dafür geeignet 
ist Halbbrücken anzusteuern. Der Grund ist, dass man keine Totzeit 
einstellen kann.

Um dieses Problem zu umgehen, kam die Idee auf das ganze mit zwei 
Interrupts zu lösen und sich quasi einen eigenen PWM-Generator zu 
basteln. Dazu wird ein Overflow-Interrupt und ein Compare-Interrupt 
verwendet.

Hier einmal der Code für den Overflow Interrupt_
1
ISR(TCA0_OVF_vect)
2
{
3
  /* Insert your TCA overflow interrupt handling code */
4
    
5
    if(enable){
6
        //Untere Halbbruecke wird Ausgeschaltet
7
        LI_set_level(false);
8
9
        //Totzeit bis die obere Halbbruecke eingeschaltet wird
10
        //Assemblerbefehler der dafür sorgt das für 1 Zyklus nichts gemacht wird
11
        asm("nop");
12
        asm("nop");
13
14
        //Obere Halbbruecke wird eingeschaltet
15
        HI_set_level(true);
16
    } else {
17
       LI_set_level(false);
18
        HI_set_level(false);
19
    }
20
         
21
  /* The interrupt flag has to be cleared manually */
22
  TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
23
}
Beim Compare-Interrupt ist natürlich alles umgekehrt.

Hat auch soweit alles Funktioniert. Über die Timer Period kann man die 
Schaltfrequenz einstellen und über den Compare-Wert den Tastgrad.

Nun aber fingen die Probleme an, als ich begann das restliche Programm 
zu implementieren. Man sieht es ganz gut auf dem Bild was ich angehängt 
habe.

Dort sieht man in Grün den Induktivitätsstrom und in Gelb die 
geschaltete Spannung. Das pinke und das blaue Signal sind Testpins. 
Diese zeigen mir an wann Registeroperationen durchgeführt werden. Pink 
ist dabei der ADC und Blau alles andere (RTC und noch ein paar andere 
Sachen).

Wie man sieht kommt die negative Flanke nicht. Wodurch der 
Induktivitätsstrom  nach unten wegrennt.

Ich weiß, dass es Operationen gibt die nicht untebrochen werden können 
und es eine Gewisse Anzahl an Zyklen dauert bis der µC mit dem Interrupt 
anfängt.

Aber so wie es aussieht, fällt der Interrupt einfach komplett weg und 
kommt erst eine Periode später.  Dazu sieht man auf dem Bild, dass in 
dem moment wo der Interrupt kommen sollte, gerade der ADC aufgerufen 
wird.

Ich konnte dieses Verhalten auch bei anderen Registeroperationen 
beobachten.

Ursprünglich bestand das Problem auch bei der positiven-Flanke.  Dies 
habe ich dadurch gelöst, dass ich dem Overflow-Interrupt eine höhere 
Priorität gegeben habe. (Beim ATTiny404 kann man leider nur einem 
Interrupt eine höhere Priorität geben)

Dadurch komme ich auf meine Vermutung, dass Registeroperationen das 
setzen der Interrupt-Flag verhindern, wenn diese eine normale 
Priorisierung hat.

Meine Frage ist nun ob jemand ähnliche Erfahrungen gemacht hat, vlt eine 
Literaturempfehlung für mich hat oder sogar weiß warum dies so ist. ?

Beste Grüße

Jonathan

EDIT: Was ich noch erwähnen sollte. Ich habe eine Lösung bzw. ein 
Workaround gefunden. Dies hier ist also eine reine Interessenfrage, weil 
mich das ganze schon sehr gewundert hat.

: Bearbeitet durch User
von Georg M. (g_m)


Lesenswert?

Jonathan B. schrieb:
> Ziel des Projekts ist es einen MPP-Tracker auf einem ATTiny404 zu
> implementieren.
>
> Ein großer Nachteil den dieser Chip hat, ist das er nicht dafür geeignet
> ist Halbbrücken anzusteuern. Der Grund ist, dass man keine Totzeit
> einstellen kann.

Darf ich fragen, warum dann nicht der ATtiny414 mit dem Timer/Counter 
Type D?

von Achim M. (minifloat)


Lesenswert?

Warum setzt du die Ausgänge händisch im Overflow-Interrupt? Das Ding hat 
genau dazu doch PWM-Ausgänge?

Ich hätte mir den passenden PWM-Modus rausgesucht (edge- oder 
centre-aligned) und im Overflow-Interrupt nur die gepufferten 
compare-Register (mit Schattenregistern!) geschrieben.

Dann wäre es noch hilfreich, keinen neuen TOP-Wert zu schreiben, der 
unterhalb des aktuellen counters liegt. Dann muss der Timer nämlich 
einen kompletten Durchlauf des counters machen, bevor die Periodendauer 
wieder stimmt. Ich denke, letzteres ist dir passiert, weil du in Prosa 
erwähnst, dass man bequem die Schaltfrequenz verändern kann, dies aber 
offenbar nicht synchronisiert zum Overflow gemacht wird.

Nutze doch die Hardware, wenn du sie schon gezielt auswählst.

mfg mf

: Bearbeitet durch User
von Jonathan B. (icwhiner)


Lesenswert?

Georg M. schrieb:
> Darf ich fragen, warum dann nicht der ATtiny414 mit dem Timer/Counter
> Type D?

Kurze Antwort: Weil Ich anscheinend ein Idiot bin.

Lange Antwort:
Ich hab das Projekt von einem Kommilitonen übernommen. Er die Hardware 
entworfen und die Bauteile ausgesucht hat. Ich hab mich bei dem ganzen 
auf seine Aussage verlassen. Hätte ich mal besser nicht gemacht

von Jonathan B. (icwhiner)


Lesenswert?

Achim M. schrieb:
> Warum setzt du die Ausgänge händisch im Overflow-Interrupt? Das Ding hat
> genau dazu doch PWM-Ausgänge?

Wie beschrieben sind diese nicht dazu geeignet eine Halbbrücke 
anzusteuern.

> Ich hätte mir den passenden PWM-Modus rausgesucht (edge- oder
> centre-aligned) und im Overflow-Interrupt nur die gepufferten
> compare-Register (mit Schattenregistern!) geschrieben.



> Dann wäre es noch hilfreich, keinen neuen TOP-Wert zu schreiben, der
> unterhalb des aktuellen counters liegt. Dann muss der Timer nämlich
> einen kompletten Durchlauf des counters machen, bevor die Periodendauer
> wieder stimmt. Ich denke, letzteres ist dir passiert, weil du in Prosa
> erwähnst, dass man bequem die Schaltfrequenz verändern kann, dies aber
> offenbar nicht synchronisiert zum Overflow gemacht wird.
>
> Nutze doch die Hardware, wenn du sie schon gezielt auswählst.

Da hab ich mich missverständlich ausgedrückt. Die Schaltfrequenz wird im 
laufenden Betrieb nicht verändert, sondern nur der Tastgrad.

Ja, daran hatte ich auch gedacht. Das blaue Signal in meinem Bild zeigt 
die Zeitpunkte an, an dennen ein neuer TOP-Wert geschrieben wird. Man 
sieht, dass die negative-Flanke davor schon hätte kommen müssen. Dadruch 
war ich mir sicher das ausschliessen zu können.

von Peter D. (peda)


Lesenswert?

Jonathan B. schrieb:
> Ein großer Nachteil den dieser Chip hat, ist das er nicht dafür geeignet
> ist Halbbrücken anzusteuern. Der Grund ist, dass man keine Totzeit
> einstellen kann.

Mit den tinyAVR0 werden sich nur sehr wenige auskennen.
Bei den standard Timern kann man sehr wohl eine Totzeit erzeugen. Dazu 
nimmt man einfach 2 Compareregister und setzt sie um die Totzeit 
versetzt. Der eine PWM-Ausgang wird dann invertiert benutzt.

Jonathan B. schrieb:
> Ich habe eine Lösung bzw. ein
> Workaround gefunden.

Dann macht es einen super Eindruck diese geheim zu halten.
Man möchte Hilfe, aber ist nicht bereit, auch etwas zu geben.

von Achim M. (minifloat)


Lesenswert?

Jonathan B. schrieb:
> Achim M. schrieb:
>> Warum setzt du die Ausgänge händisch im Overflow-Interrupt? Das Ding hat
>> genau dazu doch PWM-Ausgänge?
>
> Wie beschrieben sind diese nicht dazu geeignet eine Halbbrücke
> anzusteuern.

Doch, geht.
Ich hätte den symmetrischen PWM-Modus(mit dem auf-und abwärts) genommen. 
Es gibt zwei PWM-Ausgänge am Timer, einer wird invertiert zum anderen 
eingestellt. Die Compare-Werte werden jetzt unter Berücksichtigung der 
Totzeit eingestellt.
TOP wird einmal auf die Schaltfrequenz eingestellt und nicht weiter 
angefasst. Wenn du Wobbeln musst, darf ein Schreiben des TOP-Wertes nur 
im Overflow bei counter weit weg von TOP erfolgen.

Jonathan B. schrieb:
> Die Schaltfrequenz wird im laufenden Betrieb nicht verändert, [...] Das blaue 
Signal in meinem Bild zeigt
> die Zeitpunkte an, an dennen ein neuer TOP-Wert geschrieben wird
Ja die Schaltfrequenz wird nicht verändert das glaub' ich dir. Du 
hangelst dich von Schaltflanke zu Schaltflanke. Das generierst du dann 
immer im Overflow-Interrupt und musst für die nächste Schaltflanke einen 
neuen TOP-Wert einstellen. Das erfolgt aber nicht synchronisiert zum 
Overflow.
Also wird die negative Flanke nicht ausgegeben. Das nächste 
Schaltereignis ist die positive Flanke, von der man nichts sieht, da die 
Ausgänge sowieso schon auf diesen Werten stehen.

Nutze die Hardware, wenn du sie schon gezielt auswählst.

mfg mf

: Bearbeitet durch User
von Jonathan B. (icwhiner)


Lesenswert?

Peter D. schrieb:
> Jonathan B. schrieb:
>> Ein großer Nachteil den dieser Chip hat, ist das er nicht dafür geeignet
>> ist Halbbrücken anzusteuern. Der Grund ist, dass man keine Totzeit
>> einstellen kann.
>
> Mit den tinyAVR0 werden sich nur sehr wenige auskennen.
> Bei den standard Timern kann man sehr wohl eine Totzeit erzeugen. Dazu
> nimmt man einfach 2 Compareregister und setzt sie um die Totzeit
> versetzt. Der eine PWM-Ausgang wird dann invertiert benutzt.

Okay, da muss ich mich wohl nochmal genauer einlesen. Aus dem Datenblatt 
ging das so für mich nicht hervor.

> Jonathan B. schrieb:
>> Ich habe eine Lösung bzw. ein
>> Workaround gefunden.
>
> Dann macht es einen super Eindruck diese geheim zu halten.
> Man möchte Hilfe, aber ist nicht bereit, auch etwas zu geben.

Da hast du recht. Ich fand meinen Post nur schon etwas sehr lang.

Die Lösung die ich gefunden habe ist, dass ich alle Registeroperationen 
zu definierten Zeitpunkten durchführe. Dazu habe ich einen weiteren 
Timer im "Single-shot" mode hinzugefügt. Der Timer wird vom 
Overflow-Interrupt über das Eventsystem angetriggert. Der Compare-Wert 
für diesen Timer ist so gewählt, dass der Interrupt immer nach der 
negativen Flanke kommt. Dadurch werden alle Registeroperationen in der 
Zeit zwischen negativer- und positiver-Flanke durchgeführt. Dadurch wird 
oben beschriebene Verhalten verhindert. Hab dazu leider kein Oszi Bild.

Ich füge das per Edit noch meinem Ursprungsposte hinzu.

EDIT: Hab gerade gelernt, dass das wohl nicht geht.

: Bearbeitet durch User
von Achim M. (minifloat)


Lesenswert?

Jonathan B. schrieb:
> Die Lösung die ich gefunden habe ist, dass ich alle Registeroperationen
> zu definierten Zeitpunkten durchführe

Selbst das kann die Hardware für dich erledigen. Schattenregister!

Aber so ist das, wie in der Automobilindustrie. Nach einem Problem wird 
immer mit dazugebauten Mechanismen geworfen, die dann neue Probleme 
aufwerfen, nach denen mit erneut dazugebauten Mechanismen geworfen wird 
usw.

Ich bin raus. mfg mf

von Jonathan B. (icwhiner)


Lesenswert?

Achim M. schrieb:
> Jonathan B. schrieb:
>> Achim M. schrieb:
>>> Warum setzt du die Ausgänge händisch im Overflow-Interrupt? Das Ding hat
>>> genau dazu doch PWM-Ausgänge?
>>
>> Wie beschrieben sind diese nicht dazu geeignet eine Halbbrücke
>> anzusteuern.
>
> Doch, geht.
> Ich hätte den symmetrischen PWM-Modus(mit dem auf-und abwärts) genommen.
> Es gibt zwei PWM-Ausgänge am Timer, einer wird invertiert zum anderen
> eingestellt. Die Compare-Werte werden jetzt unter Berücksichtigung der
> Totzeit eingestellt.
> TOP wird einmal auf die Schaltfrequenz eingestellt und nicht weiter
> angefasst. Wenn du Wobbeln musst, darf ein Schreiben des TOP-Wertes nur
> im Overflow bei counter weit weg von TOP erfolgen.
> Jonathan B. schrieb:
>> Die Schaltfrequenz wird im laufenden Betrieb nicht verändert, [...] Das blaue
> Signal in meinem Bild zeigt
>> die Zeitpunkte an, an dennen ein neuer TOP-Wert geschrieben wird
> Ja die Schaltfrequenz wird nicht verändert das glaub' ich dir. Du
> hangelst dich von Schaltflanke zu Schaltflanke. Das generierst du dann
> immer im Overflow-Interrupt und musst für die nächste Schaltflanke einen
> neuen TOP-Wert einstellen. Das erfolgt aber nicht synchronisiert zum
> Overflow.
> Also wird die negative Flanke nicht ausgegeben. Das nächste
> Schaltereignis ist die positive Flanke, von der man nichts sieht, da die
> Ausgänge sowieso schon auf diesen Werten stehen.
>
> Nutze die Hardware, wenn du sie schon gezielt auswählst.
>
> mfg mf

Ich glaube wir reden aneinander vorbei.

Grundsätzlich könnte dein Ansatz funktionieren. Ich kann ihn aber nicht 
ausprobieren, da ich keinen Zugriff mehr auf die Hardware habe. (Corona 
ahoi)

Den Teil wie ich meine Schaltsignale erzeuge beschreibst du allerdings 
falsch.

Es gibt zwei Interrupts. Den Overflow-Interrupt und den 
Compare-Interrupt.

Der Overflow Interrupt erzeugt nur die positive-Flanke.
Der Compare-Interrupt immer nur die negative-Flanke.

Ich muss also nur einen neuen Topwert einstellen, wenn ich den Tastgrad 
verändern will. Wenn dieser gleich bleibt, dann muss ich gar nichts 
verändern.

Wenn ich diue Hardware spezifisch asgesucht hätte, dann wäre es 
aufjedenfall ein anderer Chip geworden.(z.b. der 414 der einen extra 
Timer für diese Anwendung hat.)

mfg jb

von Jonathan B. (icwhiner)


Lesenswert?

Achim M. schrieb:
> Jonathan B. schrieb:
>> Die Lösung die ich gefunden habe ist, dass ich alle Registeroperationen
>> zu definierten Zeitpunkten durchführe
>
> Selbst das kann die Hardware für dich erledigen. Schattenregister!
>
> Aber so ist das, wie in der Automobilindustrie. Nach einem Problem wird
> immer mit dazugebauten Mechanismen geworfen, die dann neue Probleme
> aufwerfen, nach denen mit erneut dazugebauten Mechanismen geworfen wird
> usw.
>
> Ich bin raus. mfg mf

Grundsätzlich vlt nicht ganz falsch. In diesem Fall hat es noch andere 
Probleme direkt mitgelöst. Daher war ich ganz zufrieden damit.

Danke trotzdem für deinen Input zu diesem Thema.

mfg Jb

von Uwe D. (monkye)


Lesenswert?

Peter D. schrieb:
> Jonathan B. schrieb:
>> Ein großer Nachteil den dieser Chip hat, ist das er nicht dafür geeignet
>> ist Halbbrücken anzusteuern. Der Grund ist, dass man keine Totzeit
>> einstellen kann.
> Dazu nimmt man einfach 2 Compareregister und setzt sie um die Totzeit
> versetzt. Der eine PWM-Ausgang wird dann invertiert benutzt.

@Peter, was meinst Du mit der Formulierung „...um die Totzeit versetzt“? 
Im PDF zum Tiny habe ich keinen direkten Bezug entdecken können.

Danke vorab für Deine Antwort.

NACHTRAG: Hab‘ es selbst gefunden, vermutlich wie in AVR447 beschrieben.

: Bearbeitet durch User
von Jonathan B. (icwhiner)


Lesenswert?

Achim M. schrieb:
> Doch, geht.
> Ich hätte den symmetrischen PWM-Modus(mit dem auf-und abwärts) genommen.
> Es gibt zwei PWM-Ausgänge am Timer, einer wird invertiert zum anderen
> eingestellt. Die Compare-Werte werden jetzt unter Berücksichtigung der
> Totzeit eingestellt.
> TOP wird einmal auf die Schaltfrequenz eingestellt und nicht weiter
> angefasst. Wenn du Wobbeln musst, darf ein Schreiben des TOP-Wertes nur
> im Overflow bei counter weit weg von TOP erfolgen.

Auch wenn du raus bist, vlt liest du es ja trotzdem noch.

Hab es ausprobiert und es funktioniert.

Danke

mfg jb

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.