Hallo Leute,
ich brauche dringend eure Hilfe. Ich sitze hier an einer Studienarbeit
und soll jetzt plötzlich mit dem ATmega 2561 noch eine
Nulldurchgangserkennung für eine Drehstromasynschronmaschine erstellen,
und meine programmierkenntnisse sind vorsichtig ausgedrückt sehr gering.
Also das Programm soll ,nach dem es sich initalisiert hat, bei jedem
Nulldurchgang der Sinusspannung die zugehörigen Triacs, es sind 3 Stück
für jede Phase einer, mit dem entsprechenden Alpha zünden.
Ich habe jetzt das Problem das ich nicht weiß wie ich meinem Timer 1
(16bit,vorteiler ist 8) klar machen soll das er alle 10ms die Triacs mit
einer Phasenverschiebung von 120° und unter Berücksichtung eines Alphas
von 90 ° sprich 5 ms zünden soll. Um ein sicheres zünden der Triacs zu
gewährleisten soll er immer den entsprechenden Pin für 1000 Takte auf
LOW halten.
Ich habe im Datenblatt gesehen das der Timer1 3 Comparewerte besitzt.
Das müsste ich mir doch irgendwie zu nütze machen können.
Hier noch ein paar Infos die vielleicht wichtig sind.
Also das Signal der Nulldurchgangserkennnung von 5V leigt am Pin
PD1(INT1) an. Die Ausgänge für die Triacs sind PF1(Triac1),PF3(Triac2)
und PA2(Triac3).
Ich bedanke mich jetzt schonmal für eure Mühe und hoffe ich habe genug
Informationen bereitgestellt. Den Code den ich bisher geschrieben habe
ist angehängt.
MFG
Sky
Hallo!
Ich bin da leider keine echte Hilfe, aber ich möchte Dir sagen:
Der Trick an einer Studien-/Diplomarbeit ist ja eben zu sehen wie DU
dich als Individuum durch das Problem durchbeisst. Und nicht ein
Anderer.
Später im Beruf sieht das wieder anders aus.
Zum Problem selbst: "Wir" können Dir auch das Datenblatt vorlesen. Die
meisten haben ihr wissen daraus gewonnen.
Nichts für ungut.
Olaf
Hey,
ja da gebe ich Dir ohne zweifel recht, aber eigentlich sollte ich auch
nur die Hardware etwas ergänzen und nicht programmieren. Jetzt hat sich
der Prof das halt anders überlegt und ich habe nur noch 3 Wochen bis zur
abgabe ;).
Deswegen hatte ich auf etwas Hilfe gehofft.
MFG
Hallo Sky,
mit dem Anhang aus deinem ersten Posting fange ich leider nichts an,
könntest du bitte die "normalen" .c Dateien (ich vermute es geht um C)
anhängen.
Gruß
André
Versteh ich das richtig:
Du hast 4 'Signale'
0 ----------------------------------------------
Tr1 ----------------------------------------------
Tr2 ----------------------------------------------
Tr3 ----------------------------------------------
(0 ist die 0-Durchgangserkennung; Tr1, Tr2, Tr3 sind die Ausgänge zu den
Triacs)
So, jetzt kommt ein Puls an 0 daher.
Als Folge davon sollen zeitversetzt, die Ausgänge Tr1, Tr2 und Tr3
jeweils für eine definierte Zeit auf 1 gesetzt werden.
Danach ist wieder Ruhe und das Programm wartet auf den nächsten Puls an
0
+-+
| |
0 ---+ +-----------------------------------------
+-----+
| |
Tr1 -------------+ +------------------------------
<-------->
t1
+-----+
| |
Tr2 -----------------------+ +--------------------
<------------------>
t2
+-----+
| |
Tr3 ---------------------------------+ +----------
<---------------------------->
t3
Wenn dem so ist, wo kommen die Zeiten t1, t2, t3 her? Sind die immer fix
oder wie berechnen sich diese? Kann es sein, dass sich (bei
entsprechender Pulslänge von Tr1, Tr2 bzw. Tr3) die Pulse an den
Ausgängen überlappen?
Ich fürchte da wird der mögliche 3-fach Compare im Timer 1 so auch nicht
weiter helfen. Allerdings ist die Idee mit dem Timer so schon nicht
schlecht. Im Grunde sieht dein Problem jetzt erst mal nur so aus:
Aufgrund eines Pulses werden nacheinander 3 Ausgänge zeitversett auf 1
und 0 gezogen. Klassisches Einsatzgebiet für einen Timer.
Ehe ich da jetzt aber weiterspekuliere, kannst du das soweit erst mal
bestätigen, bzw. die Frage nach den Zeiten beantworten?
Sky schrieb:> Also das Signal der Nulldurchgangserkennnung von 5V leigt am Pin> PD1(INT1) an.
Je nachdem, was der MC noch so an Interrupts zu tun hat, kann dadurch
ein hoher Jitter entstehen.
Besser ist daher, ICP1 oder ICP3 zu nehmen. Dann kann man auf den
CPU-Zyklus genau die Compareausgänge takten.
Lies Dir die Beschreibung der 16Bit-Timer in Ruhe durch.
Peter
@ Karl Heinz.
Ich kann das alles soweit bestätigen. Sobald der Nulldurchgang erkannt
ist sollen die drei Triacs jeweils um 120° Phasenverschoben zünden,
natürlich unter Beachtung des Alphawertes.
Also die Zeiten wie lange ein Triac gezündet werden soll habe ich mit
1000 Takten festgelegt und dieser Wert soll immer der gleiche sein.
Somit möchte ich gewährleisten das die Triacs sauber zünden.
Und 120° entsprechen 13320 Takten. Sprich das Signal kommt und nun soll
der erste Triac für 1000 Takte auf Low gehalten werden und dann wieder
auf High gesetzt werden. Dann soll der Timer 13320 Takte weiter zählen
und dann den Triac2 für 1000 Takte auf Low setzten und soweiter und
sofort.
@all die Datei im Anhang ist eine AVR-Studiodatei.
MFG
@Karl Heinz nochmal:
also die Signale können sich glaube ich nicht überlappen, da jeder
Ausgang über einzelne Verbindungen zu dem jeweiligen Triac geführt
werden.
@Peter:
Das andere Problem ist das ich hier eine schon fertige Platine vorliegen
habe und die Ausgänge somit definiert sind.
Trotzdem danke :)
Von der Logik her also so richtig:
Interrupt wird durch Nulldurchgang ausgeloest, Timer 1 wird angehalten
wenn er laeuft.
Du wartest x Takte
Startest Timer 1 so dass er mindestens alle 13320 Takte einen Interrupt
ausloest.
In diesem Interrupt zuendest Du Triac Y (immer den naechsten in der
Reihe) und startest Timer 2, der nach 1000 Takten feuert.
Im Interrupt von Timer 2 setzt Du den zuletzt gezuendeten Triac wieder
auf low und haeltst den Timer 2 an.
Und dann von vorne.
?
Volker
Sky schrieb:> Und 120° entsprechen 13320 Takten. Sprich das Signal kommt und nun soll> der erste Triac für 1000 Takte auf Low gehalten werden und dann wieder> auf High gesetzt werden. Dann soll der Timer 13320 Takte weiter zählen> und dann den Triac2 für 1000 Takte auf Low setzten und soweiter und> sofort.
Na ja, das hört sich jetzt aber nicht so dramatisch an.
Wie genau muss das ganze sein?
deine 1000 sind ja nur eine willkürliche Festlegung. INteressant ist:
wie genau müssen die 13320 Takte eigehalten werden?
zb: 2 Timer.
Timer 1 zählt im CTC die lange Zeitdauer ab, also die 13320 Takte
Sind die erreicht gibt es einen INterrupt. Im Interrupt wird der
jeweilige Triac eingeschaltet und ein 2.ter Timer gestartet. Aufgabe des
2.ten Timers: die 1000 Takte abzählen. Am Ende gibt es wieder einen
INterrupt und in diesem wird der Triac wieder abgeschaltet.
Der INterrupt vom Timer 1 zählt einfach mit, bei welchem Triac er gerade
ist, Ist er beim 3.ten angelangt startet er nur mehr den 2.ten Timer für
die 1000 Takte und stellt seinen eigenen Timer wieder ab.
Mit jedem Nulldurchgang beginnt das Spiel wieder von vorne.
Soweit erst mal als grobe Skizze des Programmplans.
Wichtige Frage: Wie genau MÜSSEN die Zeiten eingehalten werden. Das du
natürlich möglichst auf 0 Abweichung kommen willst ist mir schon klar.
0-Abweichung ist aber ein hoher Aufwand. Daher schaun wir mal, ob es
nicht gelingt etwas relaxtere Zeitforderungen einfacher zu erfüllen.
Dafür brauchst du aber eine Vorgabe, was noch tolerabel ist.
Noch ein Vorschlag.
Da anscheinend das Hauptprogramm sowieso nichts zu tun hat, bietet es
sich an die 0-Durchgangserkennung in die Hauptschleife zu verlegen.
Vorteil: Dadurch fällt die Interrupt Latenz des Erkennens schon mal weg.
Das hängt jetzt aber von der Antwort auf die Zusatzfrage ab:
Wo kommt eigentlich das Alpha her?
Und: gehe ich recht in der Annahme, dass dieses Alpha sich eigentlich
nur in einem Zeitversatz von der 0-Erkennung bis zum Start des ersten
Triac auswirkt - im Grunde daher als Phasenverschiebung der
Triac-Sequenz zum 0-Durchgang zu werten ist.
Bzw. wenn der µC sowieso keine anderen Aufgaben hat und da sich nichts
ueberlappen kann, koenntest Du auch komplett auf Interrupts und Timer
verzichten...
Volker
Volker Schulz schrieb:> Zwei Dumme ein Programmplan... ;)
:-)
Ist wie ich finde, ein ziemlich naheliegende Vorgehensweise. D.h. wenn
nicht noch irgendwelche Zeitvorgaben einen Strich durch die Rechnung
machen.
Volker Schulz schrieb:> Bzw. wenn der µC sowieso keine anderen Aufgaben hat und da sich nichts> ueberlappen kann, koenntest Du auch komplett auf Interrupts und Timer> verzichten...
Hmm.
Die Idee ist gar nicht mal so dumm. Nur müsste man das in Assembler
programmieren, damit man die Taktzahlen genau einhalten kann. (Ansonsten
müsste man das mit einem Timer machen, dessen TCNT Register man pollt.
Geht auch)
In der Zeit vom Tr3-Ende bis zum nächsten erwarteten 0-Durchgang hat man
rund 12000 Takte Zeit. Das reicht locker für zb eine ADC-Abfrage und
eine Neuberechnung der ersten Wartezeit.
Damit ist das in Pseudocode
while( 1 )
while( Pin_0_Durchgang == 0 )
;
warte Alpha Takte
Tr1 auf 1
warte 1000 Takte
Tr1 auf 0
warte 133was_weiß_ich - 1000 - Tr setzen Takte
Tr2 auf 1
warte 1000 Takte
Tr2 auf 0
warte 133was_weiß_ich - 1000 - Tr setzen Takte
Tr3 auf 1
warte 1000 Takte
Tr3 auf 0
weiteres, zb ADC Abfragen für ALph und neuberechnung
der ersten Wartezeit
}
Der INterrupt Latenz würde man so ein Schnippchen schlagen, wenn man die
Hardware Möglichkeiten nicht ausnutzen kann oder will.
Also die Werte für Alpha wollte ich über eine Rampe vorgeben. So 5 Werte
zwischen 0 und 180°. Und je nachdem wie der Alpha eingestellt ist also
z.B. 90°(5ms) soll der erste Triac dann halt 5ms nach dem Nulldurchgang
der Netzspannung gezündet werden und Triac 2 dann halt wieder 13320
Takte nach Triac1 und Triac 3 dann halt 13320 Takte nach Triac 2.
Also ich denke das man schon eine Abweichung hinnehmen kann was die
13320 Takte betrifft, solange alles bis zum nächsten Nulldurchgang
erledigt ist und ein neuer Wert für Alpha übernommen werden soll.
MFG
Karl Heinz Buchegger schrieb:> Hmm.> Die Idee ist gar nicht mal so dumm. Nur müsste man das in Assembler> programmieren, damit man die Taktzahlen genau einhalten kann.
Vorgabe vom Prof ist, dass ich das in mit AVR Studio 4 programmiere.
Volker Schulz schrieb:> Apropos genaue Timings... Wenn ich nachrechne muesste er einen 1,332 MHz> Takt haben, oder? Ist das ueblich?
Keine Ahnung. Da klingelt bei mir nichts.
Kann auch sein, dass er sich bei seinen Taktzahlen verrechnet hat.
Weil Du oben "alle 10 ms" geschrieben hattest.. Aber das bezog sich dann
wohl nicht auf den Abstand zwischen zwei Triac-Zuendungen sondern auf
nur eine der Phasen... Macht ja auch irgendwie Sinn. ;)
Sky schrieb:> Karl Heinz Buchegger schrieb:>> Hmm.>> Die Idee ist gar nicht mal so dumm. Nur müsste man das in Assembler>> programmieren, damit man die Taktzahlen genau einhalten kann.>> Vorgabe vom Prof ist, dass ich das in mit AVR Studio 4 programmiere.
Dann ist die Assemblerloesung doch perfekt. Oder muss der Controller
noch andere Aufgaben ausfuehren?
Volker
Also der Prof. meinte zu mir das ich in meiner Arbeit nur die
Nulldurchgangserkennung realisieren soll. Später soll dann vielleicht
noch eine Leitdauererfassung und ein Beobachter für den Strom realisiert
werden. Eventuell soll der Alpha dann auch über ein Poti vorgegeben
werden und nicht per Rampe.
Aber ist Assembler nicht viel anders als C++??
MFG
Sky schrieb:> Also ich denke das man schon eine Abweichung hinnehmen kann was die> 13320 Takte betrifft,
Wie groß darf die Abweichung sein? Winde dich doch nicht so um eine
klare Aussage herum.
OK. Ich sag mal eine Zahl. Die Schaltzeiten könenn irgendwo im Bereich
+-10 Takte variieren.
Das sind bei 16Mhz 0.625µs. Seien wir großzügig und sagen 1µs
Zuviel / zu wenig?
Sky schrieb:> [...]> Aber ist Assembler nicht viel anders als C++??> MFG
Doch! ;)
http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
Aber fuer solch ein relativ simples Programm dann doch kein Problem,
selbst wenn man sich noch nicht damit beschaeftigt hat. Einfach mal das
verlinkte Tutorial durchgehen...
Volker
Sky schrieb:> Also der Prof. meinte zu mir das ich in meiner Arbeit nur die> Nulldurchgangserkennung realisieren soll. Später soll dann vielleicht> noch eine Leitdauererfassung und ein Beobachter für den Strom realisiert> werden. Eventuell soll der Alpha dann auch über ein Poti vorgegeben> werden und nicht per Rampe.
OK.
Wenn du mit dem Timing hinkommst, dann nimm C.
Da du in Programmierung wenig Erfahrung hast, ist es dann für deinen
Nachfolger einfacher alles zu verwerfen und mit der Grundidee neu zu
schreiben. In Assembler ist das für ihn sonst nur eine Qual.
Karl Heinz Buchegger schrieb:> Wie groß darf die Abweichung sein? Winde dich doch nicht so um eine> klare Aussage herum.> OK. Ich sag mal eine Zahl. Die Schaltzeiten könenn irgendwo im Bereich> +-10 Takte variieren.> Das sind bei 16Mhz 0.625µs. Seien wir großzügig und sagen 1µs>> Zuviel / zu wenig?
Jap das das geht in Ordnung. Danke