Forum: Mikrocontroller und Digitale Elektronik AVR-Timer mit Netzfrequenz synchronisieren


von Thomas (Gast)


Lesenswert?

Moin moin,

ich nutze einen ATmega32 mit 16MHz externen Quarz.
Timer 1 nutze ich via Compare-Irq für einen 1ms Irq. Toggle ich in 
diesem Interrupt einen Port-Pin so habe ich exakt jede ms eine Änderung. 
(funktioniert also!).

Diesen 1ms Irq muss ich mit der Netzfrequenz synchronisieren. So baute 
ich eine Nulldurchgangserkennung (funktioniert einwandfrei!), die mir 
einen externen Irq auslöst (Int0).
In der Funktion Int0 initialisiere ich den Timer erneut (zurücksetzen 
von TCNT1).

Mein Problem ist jetzt, das dieses so nicht funktioniert :-(
Messe ich mit dem Oszi den 1ms-Impuls und lege auf den anderen Kanal die 
Nulldurchgangserkennung, so rasen die Signale aneinander vorbei...

Hat jemand eine andere Idee, wie man den Timer entsprechend 
synchronisieren kann?

Die Nulldurchgangserkennung ist vom Versorgungstrafo (9V eff) 
abgegriffen; Spannungsteiler geg. Masse; Mittelpunkt via Basiswiderstand 
an einen BC547B; Emitter mit Widerstand geg. Int0; Kollektor mit 
Widerstand geg. VCC.

von Fragesteller (Gast)


Lesenswert?

Warum und wofür benutzt du den Timerinterrupt?
Ist nicht alles mit dem ext Int zu erledigen?

von Thomas (Gast)


Lesenswert?

Anschneiden der Phase zum bestimmten Winkel.

von Fragesteller (Gast)


Lesenswert?

Also möchtest du einen Dimmer bauen.
Dein Timer Interrupt hat eine Zykluszeit von 1ms. Dein Ext int. 10ms.
Du setzt den Zähler des Timers mit deinem ext int zurück.
Mein Vorschlag, Timer nicht auf auto reload sondern jeweils im ext int 
setzen.

von Spess53 (Gast)


Lesenswert?

Hi

Nur so eine Idee: Prescaler Reset.

MfG Spess

von Thomas (Gast)


Lesenswert?

Nein, ein Dimmer wird es nicht.
Auch sind es keine 50Hz, aber das macht alles nix :-)

Nehmen wir mal an, das wie Du schreibst, der externe Int alle 10ms 
auslöst, und ich dort den Timer setze -> dann muss ich auf meinen 1ms 
Irq verzichten...das geht nicht.

Andere Timer sind belegt.

von Fragesteller (Gast)


Lesenswert?

Du brauchst ja nicht zwingend einen Timer im ext int initialisieren. 
Nehmen wir an deine Application würde in einem Timerinterrupt zyklisch 
ausgeführt,dein ext int würde eine globale Variable setzen, dann könnte 
mann in seiner Application diese Variable benutzen um zu reagieren.

von Matthias L. (Gast)


Lesenswert?

>Diesen 1ms Irq muss ich mit der Netzfrequenz synchronisieren.

Wie soll das gehen? Netzfrequenz ist 10ms und nicht 1ms...?

Oder meinst du so:


Netz:...|.................................................|.............
1ms: ...|....|....|....|....|....|....|....|....|....|....|....|....|...

Das du sozusagen die Netzfrequenz verzehnfachen willst???

von Thomas (Gast)


Lesenswert?

@Matthias. Genau dieses!

und ich bekomme:
Netz: ....|......................................|........... oder ->
Netz: ....|........................................|.........
1ms:  ....|....|....|....|....|....|....|....|....|....|....|

aber eben nicht:
Netz: ....|.......................................|..........
1ms:  ....|....|....|....|....|....|....|....|....|....|....|

von Thomas (Gast)


Lesenswert?

Upps...verzählt habe ich mich jetzt auch noch. Entschuldigt bitte.

von Matthias L. (Gast)


Lesenswert?

Hm.. folgende Idee:

Proescaler auf 8. ergibt 2MHz Zähltakt.
Somit würde ein Überlauf alle 32,768ms stattfinden.

Deinen ext. Interrupt legst du auf den ICP-Interrupt. Dort löscht du den 
Timerwert (tcnt=0) und merkst dir ein den letzten (icp-wert). diesen 
teilst du durch zehn und merkst dir das ergebnis als ocp-wert. Diesen 
nutzt du um alle diese ticks einen ocp interrupt auszulösen...

Also im icq-int schreibst du den ocp-wert (icp/10) ins ocp register.
kommt der ocp-int. dann erhohst du den ocq-wert immer um icq/10...

Das sollte gehen...

von F. K. (freddy436)


Lesenswert?

Kann es sein das deine Null Durchgangs Erkennungs Schaltung einfach bei 
einem falschen Pegel schaltet?

von Spess53 (Gast)


Lesenswert?

Hi

Hast du eigentlich beachtet,daß die Netzfrequenz nicht konstant ist?

Unter folg. Link kannst du dir mal ansehen, wie sich die Frequenz 
innerhalb kurzer Zeit ändert:

http://www.etrans.ch/services/online/frequency/

Die Quarzfrequenz dürfte auf kurze Zeit gesehen, wesentlich stabiler als 
die Netzfrequenz sein.

MfG Spess

von Thomas (Gast)


Lesenswert?

@freddy.
Die Schaltung schaltet exakt. Anfangs habe ich gedacht, dass evtl. 
Eingangskapazitäten mir den Pegel verderben, durch diverse Messungen 
kann ich dieses ausschließen. Die Schaltung arbeitet einwandfrei.

@matthias.
Bis auf den letzten Satz kann ich das alles nachvollziehen. Warum 
erhöhen? Es reicht doch dann, wenn ich stets icp/10 ins ocp-reg 
schreibe...oder?

von Matthias L. (Gast)


Lesenswert?

> Es reicht doch dann, wenn ich stets icp/10 ins ocp-reg
>schreibe...oder?

Nein. weil der Timer nur alle 10* (icp/10) auf null zurückgesetzt wird:


Netz: 
....|.................................................|.............
1ms: 
....|....|....|....|....|....|....|....|....|....|....|....|....|...


Tcnt    20000
          0       4000      8000      12000     16000     20000

                                                            0 
40000

Das ICP REgister beinhaltet also immer Werte ~20000. Und das OCP 
register muss nun mit den werten n*(icq/10), mit n=0..8 geladen 
werden...

Nicht 9 ! Das muss im ICP-Int erfolgen...

von hubert (Gast)


Lesenswert?

misst du die 50 Hz am trafo oder am Netz?

denn am Trafo ist die Spannung/Strom in Bezug aufs Netz ja 
phasenverschoben...

von Ralph (Gast)


Lesenswert?

Nimm eine diskret aufgebaute PLL Schaltung die du mit der Netzfrquenz 
synchronisierst. Du erhälst einen zur Netzfrequenz synchronen Takt mit 
beliebiger Frequenz. Den kannst du dann an den externe IRQ anlegen.

Was du hier machen willst, ist das Paradebeispiel für eine PLL.

In µC mit Software und IRQ wirst du NIE synchron sein, sondern immer 
eine Abweichung vom Nulldurchgang bekommen.
Die Frage ist wieviel Abweichung ist für dich und diese Anwendung 
akzeptabel.

von Werner (Gast)


Lesenswert?

Würde das nicht so gehen?
Wenn ein ext. Ereignis auftaucht zunächst die Zeit seit dem letzten 
Ereignis bestimmen, den wert durch 10 teilen, den timer zurücksetzten 
und dann als prescaler bis zum nächsten ext. Ereignis diesen Wert 
eintragen.

von Matthias L. (Gast)


Lesenswert?

@Werner:

Ich glaube, das wurde schonmal vorgeschlagen ;-)

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.