Forum: Mikrocontroller und Digitale Elektronik Hilfe bei der Programmierung vom ATmega 2561


von Sky (Gast)


Angehängte Dateien:

Lesenswert?

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

von Olaf H. (agentp)


Lesenswert?

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

von Sky (Gast)


Lesenswert?

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

von André M. (pc-fan)


Lesenswert?

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é

von Karl H. (kbuchegg)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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

von Sky (Gast)


Lesenswert?

@ 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

von Sky (Gast)


Lesenswert?

@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 Volker S. (volkerschulz)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Volker S. (volkerschulz)


Lesenswert?

Zwei Dumme ein Programmplan... ;)

Volker

von Karl H. (kbuchegg)


Lesenswert?

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.

von Volker S. (volkerschulz)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Volker S. (volkerschulz)


Lesenswert?

Apropos genaue Timings... Wenn ich nachrechne muesste er einen 1,332 MHz 
Takt haben, oder? Ist das ueblich?

Volker

von Sky (Gast)


Lesenswert?

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

von Sky (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Sky (Gast)


Lesenswert?

Also ich habe eine 16Mhz Frequenz und einen Vorteiler von 8, sprich ich 
habe 0,5 us pro Takt.
MFG

von Volker S. (volkerschulz)


Lesenswert?

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

von Sky (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?

von Volker S. (volkerschulz)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Sky (Gast)


Lesenswert?

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

von Sky (Gast)


Lesenswert?

Gut. Ich werd mich dann wohl mal mit dem Tutorial anfreunden und mich an 
euren Ideen und Tipps halten. Schonmal vielen Dank.
MFG

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.